xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_mac.c (revision 86ef0a63)
144961713Sgirish /*
244961713Sgirish  * CDDL HEADER START
344961713Sgirish  *
444961713Sgirish  * The contents of this file are subject to the terms of the
544961713Sgirish  * Common Development and Distribution License (the "License").
644961713Sgirish  * You may not use this file except in compliance with the License.
744961713Sgirish  *
844961713Sgirish  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
944961713Sgirish  * or http://www.opensolaris.org/os/licensing.
1044961713Sgirish  * See the License for the specific language governing permissions
1144961713Sgirish  * and limitations under the License.
1244961713Sgirish  *
1344961713Sgirish  * When distributing Covered Code, include this CDDL HEADER in each
1444961713Sgirish  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1544961713Sgirish  * If applicable, add the following below this CDDL HEADER, with the
1644961713Sgirish  * fields enclosed by brackets "[]" replaced with your own identifying
1744961713Sgirish  * information: Portions Copyright [yyyy] [name of copyright owner]
1844961713Sgirish  *
1944961713Sgirish  * CDDL HEADER END
2044961713Sgirish  */
2144961713Sgirish /*
2289282175SSantwona Behera  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
2344961713Sgirish  */
2444961713Sgirish 
2544961713Sgirish #include <sys/nxge/nxge_impl.h>
2644961713Sgirish #include <sys/nxge/nxge_mac.h>
27678453a8Sspeer #include <sys/nxge/nxge_hio.h>
2844961713Sgirish 
2998ecde52Stm #define	LINK_MONITOR_PERIOD	(1000 * 1000)
3098ecde52Stm #define	LM_WAIT_MULTIPLIER	8
3198ecde52Stm 
32321febdeSsbehera #define	SERDES_RDY_WT_INTERVAL	50
33321febdeSsbehera #define	MAX_SERDES_RDY_RETRIES	10
34321febdeSsbehera 
3500161856Syc #define	TN1010_SPEED_1G		1
3600161856Syc #define	TN1010_SPEED_10G	0
3700161856Syc #define	TN1010_AN_IN_PROG	0	/* Auto negotiation in progress */
3800161856Syc #define	TN1010_AN_COMPLETE	1
3900161856Syc #define	TN1010_AN_RSVD		2
4000161856Syc #define	TN1010_AN_FAILED	3
4100161856Syc 
4244961713Sgirish extern uint32_t nxge_no_link_notify;
4359ac0c16Sdavemq extern boolean_t nxge_no_msg;
4444961713Sgirish extern uint32_t nxge_lb_dbg;
454202ea4bSsbehera extern uint32_t nxge_jumbo_mtu;
4644961713Sgirish 
4798ecde52Stm typedef enum {
4898ecde52Stm 	CHECK_LINK_RESCHEDULE,
4998ecde52Stm 	CHECK_LINK_STOP
5098ecde52Stm } check_link_state_t;
5198ecde52Stm 
5298ecde52Stm static check_link_state_t nxge_check_link_stop(nxge_t *);
5398ecde52Stm 
5444961713Sgirish /*
5544961713Sgirish  * Ethernet broadcast address definition.
5644961713Sgirish  */
5744961713Sgirish static ether_addr_st etherbroadcastaddr =
5844961713Sgirish 				{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
5959ac0c16Sdavemq /*
6059ac0c16Sdavemq  * Ethernet zero address definition.
6159ac0c16Sdavemq  */
6256d930aeSspeer static ether_addr_st etherzeroaddr =
6356d930aeSspeer 				{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
6459ac0c16Sdavemq /*
6559ac0c16Sdavemq  * Supported chip types
6659ac0c16Sdavemq  */
6752cdd236Ssbehera static uint32_t nxge_supported_cl45_ids[] = {
6852cdd236Ssbehera 	BCM8704_DEV_ID,
6952cdd236Ssbehera 	MARVELL_88X_201X_DEV_ID,
7000161856Syc 	BCM8706_DEV_ID,
7100161856Syc 	TN1010_DEV_ID
7252cdd236Ssbehera };
7352cdd236Ssbehera 
74b1000363Sml static uint32_t nxge_supported_cl22_ids[] = {
75b1000363Sml     BCM5464R_PHY_ID,
76b1000363Sml     BCM5482_PHY_ID
77b1000363Sml };
7859ac0c16Sdavemq 
7959ac0c16Sdavemq #define	NUM_CLAUSE_45_IDS	(sizeof (nxge_supported_cl45_ids) /	\
8059ac0c16Sdavemq 				sizeof (uint32_t))
8159ac0c16Sdavemq #define	NUM_CLAUSE_22_IDS	(sizeof (nxge_supported_cl22_ids) /	\
8259ac0c16Sdavemq 				sizeof (uint32_t))
8359ac0c16Sdavemq /*
8459ac0c16Sdavemq  * static functions
8559ac0c16Sdavemq  */
862e59129aSraghus static uint32_t nxge_get_cl45_pma_pmd_id(p_nxge_t, int);
872e59129aSraghus static uint32_t nxge_get_cl45_pcs_id(p_nxge_t, int);
882e59129aSraghus static uint32_t nxge_get_cl22_phy_id(p_nxge_t, int);
8959ac0c16Sdavemq static boolean_t nxge_is_supported_phy(uint32_t, uint8_t);
9089282175SSantwona Behera static boolean_t nxge_hswap_phy_present(p_nxge_t, uint8_t);
912d17280bSsbehera static boolean_t nxge_is_phy_present(p_nxge_t, int, uint32_t, uint32_t);
9259ac0c16Sdavemq static nxge_status_t nxge_n2_serdes_init(p_nxge_t);
934df55fdeSJanie Lu static nxge_status_t nxge_n2_kt_serdes_init(p_nxge_t);
9459ac0c16Sdavemq static nxge_status_t nxge_neptune_10G_serdes_init(p_nxge_t);
9559ac0c16Sdavemq static nxge_status_t nxge_1G_serdes_init(p_nxge_t);
9659ac0c16Sdavemq static nxge_status_t nxge_10G_link_intr_stop(p_nxge_t);
9759ac0c16Sdavemq static nxge_status_t nxge_10G_link_intr_start(p_nxge_t);
9859ac0c16Sdavemq static nxge_status_t nxge_1G_copper_link_intr_stop(p_nxge_t);
9959ac0c16Sdavemq static nxge_status_t nxge_1G_copper_link_intr_start(p_nxge_t);
10059ac0c16Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_stop(p_nxge_t);
10159ac0c16Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_start(p_nxge_t);
10259ac0c16Sdavemq static nxge_status_t nxge_check_mii_link(p_nxge_t);
10359ac0c16Sdavemq static nxge_status_t nxge_check_10g_link(p_nxge_t);
10459ac0c16Sdavemq static nxge_status_t nxge_10G_xcvr_init(p_nxge_t);
1052d17280bSsbehera static nxge_status_t nxge_BCM8704_xcvr_init(p_nxge_t);
1062d17280bSsbehera static nxge_status_t nxge_BCM8706_xcvr_init(p_nxge_t);
10759ac0c16Sdavemq static nxge_status_t nxge_1G_xcvr_init(p_nxge_t);
10859ac0c16Sdavemq static void nxge_bcm5464_link_led_off(p_nxge_t);
10900161856Syc static nxge_status_t nxge_check_mrvl88x2011_link(p_nxge_t, boolean_t *);
11052cdd236Ssbehera static nxge_status_t nxge_mrvl88x2011_xcvr_init(p_nxge_t);
11189282175SSantwona Behera static nxge_status_t nxge_check_nlp2020_link(p_nxge_t, boolean_t *);
11289282175SSantwona Behera static nxge_status_t nxge_nlp2020_xcvr_init(p_nxge_t);
11389282175SSantwona Behera static int nxge_nlp2020_i2c_read(p_nxge_t, uint8_t, uint16_t, uint16_t,
11489282175SSantwona Behera 	    uint8_t *);
11589282175SSantwona Behera static boolean_t nxge_is_nlp2020_phy(p_nxge_t);
11689282175SSantwona Behera static uint8_t nxge_get_nlp2020_connector_type(p_nxge_t);
11789282175SSantwona Behera static nxge_status_t nxge_set_nlp2020_param(p_nxge_t);
11800161856Syc static nxge_status_t nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id,
11900161856Syc 	uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui);
12000161856Syc static nxge_status_t nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed);
12100161856Syc static nxge_status_t nxge_set_tn1010_param(p_nxge_t nxgep);
12200161856Syc static nxge_status_t nxge_tn1010_check(p_nxge_t nxgep,
12300161856Syc 	nxge_link_state_t *link_up);
12400161856Syc static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep);
12500161856Syc static nxge_status_t nxge_tn1010_xcvr_init(p_nxge_t nxgep);
12600161856Syc 
12700161856Syc nxge_status_t nxge_mac_init(p_nxge_t);
12800161856Syc static nxge_status_t nxge_mii_get_link_mode(p_nxge_t);
12900161856Syc 
13000161856Syc #ifdef NXGE_DEBUG
13100161856Syc static void nxge_mii_dump(p_nxge_t);
13200161856Syc static nxge_status_t nxge_tn1010_reset(p_nxge_t nxgep);
13300161856Syc static void nxge_dump_tn1010_status_regs(p_nxge_t nxgep);
13400161856Syc #endif
13559ac0c16Sdavemq 
13659ac0c16Sdavemq /*
13759ac0c16Sdavemq  * xcvr tables for supported transceivers
13859ac0c16Sdavemq  */
13959ac0c16Sdavemq 
14000161856Syc /*
14100161856Syc  * nxge_n2_10G_table is for 10G fiber or serdes on N2-NIU systems.
14200161856Syc  * The Teranetics TN1010 based copper XAUI card can also be used
14300161856Syc  * on N2-NIU systems in 10G mode, but it uses its own table
14400161856Syc  * nxge_n2_10G_tn1010_table below.
14500161856Syc  */
1462e59129aSraghus static nxge_xcvr_table_t nxge_n2_10G_table = {
14759ac0c16Sdavemq 	nxge_n2_serdes_init,
14859ac0c16Sdavemq 	nxge_10G_xcvr_init,
14959ac0c16Sdavemq 	nxge_10G_link_intr_stop,
15059ac0c16Sdavemq 	nxge_10G_link_intr_start,
15159ac0c16Sdavemq 	nxge_check_10g_link,
1522d17280bSsbehera 	PCS_XCVR
15359ac0c16Sdavemq };
15459ac0c16Sdavemq 
15500161856Syc /*
15600161856Syc  * For the Teranetics TN1010 based copper XAUI card
15700161856Syc  */
15800161856Syc static nxge_xcvr_table_t nxge_n2_10G_tn1010_table = {
15900161856Syc 	nxge_n2_serdes_init,		/* Handle both 1G and 10G */
16000161856Syc 	nxge_tn1010_xcvr_init,		/* Handle both 1G and 10G */
16100161856Syc 	nxge_10G_link_intr_stop,
16200161856Syc 	nxge_10G_link_intr_start,
16300161856Syc 	nxge_check_tn1010_link,		/* Will figure out speed */
16400161856Syc 	XPCS_XCVR
16500161856Syc };
16600161856Syc 
1672e59129aSraghus static nxge_xcvr_table_t nxge_n2_1G_table = {
1682e59129aSraghus 	nxge_n2_serdes_init,
1692e59129aSraghus 	nxge_1G_xcvr_init,
1702e59129aSraghus 	nxge_1G_fiber_link_intr_stop,
1712e59129aSraghus 	nxge_1G_fiber_link_intr_start,
1722e59129aSraghus 	nxge_check_mii_link,
1732d17280bSsbehera 	PCS_XCVR
1742e59129aSraghus };
1752e59129aSraghus 
17600161856Syc static nxge_xcvr_table_t nxge_n2_1G_tn1010_table = {
17700161856Syc 	nxge_n2_serdes_init,
17800161856Syc 	nxge_tn1010_xcvr_init,
17900161856Syc 	nxge_1G_fiber_link_intr_stop,	/* TN1010 is a Cu PHY, but it uses */
18000161856Syc 	nxge_1G_fiber_link_intr_start,	/* PCS for 1G, so call fiber func */
18100161856Syc 	nxge_check_tn1010_link,
18200161856Syc 	PCS_XCVR
18300161856Syc };
18400161856Syc 
18500161856Syc static nxge_xcvr_table_t nxge_10G_tn1010_table = {
18600161856Syc 	nxge_neptune_10G_serdes_init,
18700161856Syc 	nxge_tn1010_xcvr_init,
18800161856Syc 	nxge_10G_link_intr_stop,
18900161856Syc 	nxge_10G_link_intr_start,
19000161856Syc 	nxge_check_tn1010_link,
19100161856Syc 	XPCS_XCVR
19200161856Syc };
19300161856Syc 
19400161856Syc static nxge_xcvr_table_t nxge_1G_tn1010_table = {
19500161856Syc 	nxge_1G_serdes_init,
19600161856Syc 	nxge_tn1010_xcvr_init,
19700161856Syc 	nxge_1G_fiber_link_intr_stop,
19800161856Syc 	nxge_1G_fiber_link_intr_start,
19900161856Syc 	nxge_check_tn1010_link,
20000161856Syc 	PCS_XCVR
20100161856Syc };
20200161856Syc 
20359ac0c16Sdavemq static nxge_xcvr_table_t nxge_10G_fiber_table = {
20459ac0c16Sdavemq 	nxge_neptune_10G_serdes_init,
20559ac0c16Sdavemq 	nxge_10G_xcvr_init,
20659ac0c16Sdavemq 	nxge_10G_link_intr_stop,
20759ac0c16Sdavemq 	nxge_10G_link_intr_start,
20859ac0c16Sdavemq 	nxge_check_10g_link,
2092d17280bSsbehera 	PCS_XCVR
21059ac0c16Sdavemq };
21159ac0c16Sdavemq 
21259ac0c16Sdavemq static nxge_xcvr_table_t nxge_1G_copper_table = {
21359ac0c16Sdavemq 	NULL,
21459ac0c16Sdavemq 	nxge_1G_xcvr_init,
21559ac0c16Sdavemq 	nxge_1G_copper_link_intr_stop,
21659ac0c16Sdavemq 	nxge_1G_copper_link_intr_start,
21759ac0c16Sdavemq 	nxge_check_mii_link,
2182d17280bSsbehera 	INT_MII_XCVR
21959ac0c16Sdavemq };
22059ac0c16Sdavemq 
22100161856Syc /* This table is for Neptune portmode == PORT_1G_SERDES cases */
22259ac0c16Sdavemq static nxge_xcvr_table_t nxge_1G_fiber_table = {
22359ac0c16Sdavemq 	nxge_1G_serdes_init,
22459ac0c16Sdavemq 	nxge_1G_xcvr_init,
22559ac0c16Sdavemq 	nxge_1G_fiber_link_intr_stop,
22659ac0c16Sdavemq 	nxge_1G_fiber_link_intr_start,
22759ac0c16Sdavemq 	nxge_check_mii_link,
2282d17280bSsbehera 	PCS_XCVR
22959ac0c16Sdavemq };
23059ac0c16Sdavemq 
23159ac0c16Sdavemq static nxge_xcvr_table_t nxge_10G_copper_table = {
23259ac0c16Sdavemq 	nxge_neptune_10G_serdes_init,
23359ac0c16Sdavemq 	NULL,
23459ac0c16Sdavemq 	NULL,
23559ac0c16Sdavemq 	NULL,
2362e59129aSraghus 	NULL,
2372d17280bSsbehera 	PCS_XCVR
23859ac0c16Sdavemq };
23944961713Sgirish 
24000161856Syc /*
24100161856Syc  * NXGE_PORT_TN1010 is defined as,
24200161856Syc  *      NXGE_PORT_SPD_NONE | (NXGE_PHY_TN1010 << NXGE_PHY_SHIFT)
24300161856Syc  *	= 0 | 5 << 16 = 0x50000
24400161856Syc  *
24500161856Syc  * So NEPTUNE_2_TN1010 =
24600161856Syc  *      (NXGE_PORT_TN1010 |
24700161856Syc  *      (NXGE_PORT_TN1010 << 4) |
24800161856Syc  *      (NXGE_PORT_NONE << 8) |
24900161856Syc  *      (NXGE_PORT_NONE << 12)),
25000161856Syc  *      = 0x50000 | (0x50000 << 4)
25100161856Syc  *	= 0x550000
25200161856Syc  *
25300161856Syc  * This function partitions nxgep->nxge_hw_p->niu_type (which may have
25400161856Syc  * value NEPTUNE_2_TN1010) and checks if a port has type = NXGE_PORT_TN1010
25500161856Syc  * = 0x50000
25600161856Syc  */
nxge_is_tn1010_phy(p_nxge_t nxgep)25700161856Syc static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep)
25800161856Syc {
25900161856Syc 	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
26000161856Syc 
26100161856Syc 	if (((nxgep->nxge_hw_p->niu_type >> (NXGE_PORT_TYPE_SHIFT * portn))
26200161856Syc 	    & NXGE_PHY_MASK) == NXGE_PORT_TN1010) {
26300161856Syc 		return (B_TRUE);
26400161856Syc 	} else {
26500161856Syc 		return (B_FALSE);
26600161856Syc 	}
26700161856Syc }
26844961713Sgirish 
269d81011f0Ssbehera 
27000161856Syc /*
27100161856Syc  * Figure out nxgep->mac.portmode from nxge.conf, OBP's device properties,
27200161856Syc  * serial EEPROM or VPD if possible.  Note that not all systems could get
27300161856Syc  * the portmode information by calling this function.  For example, the
27400161856Syc  * Maramba system figures out the portmode information by calling function
27500161856Syc  * nxge_setup_xcvr_table.
27600161856Syc  */
2772e59129aSraghus nxge_status_t
nxge_get_xcvr_type(p_nxge_t nxgep)2782e59129aSraghus nxge_get_xcvr_type(p_nxge_t nxgep)
2792e59129aSraghus {
2802e59129aSraghus 	nxge_status_t status = NXGE_OK;
2812e59129aSraghus 	char *phy_type;
2822e59129aSraghus 	char *prop_val;
28300161856Syc 	uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num);
2841c7408c9Stc 	uint32_t	val;
2851c7408c9Stc 	npi_status_t	rs;
2861c7408c9Stc 
2871c7408c9Stc 	/* For Opus NEM, skip xcvr checking if 10G Serdes link is up */
2881c7408c9Stc 	if (nxgep->mac.portmode == PORT_10G_SERDES &&
2891c7408c9Stc 	    nxgep->statsp->mac_stats.link_up) {
2901c7408c9Stc 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
2911c7408c9Stc 		return (status);
2921c7408c9Stc 	}
2932e59129aSraghus 
2942e59129aSraghus 	nxgep->mac.portmode = 0;
2952d17280bSsbehera 	nxgep->xcvr_addr = 0;
2962e59129aSraghus 
2972d17280bSsbehera 	/*
2982d17280bSsbehera 	 * First check for hot swappable phy property.
2992d17280bSsbehera 	 */
3002d17280bSsbehera 	if (nxgep->hot_swappable_phy == B_TRUE) {
3012d17280bSsbehera 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
3022d17280bSsbehera 		nxgep->mac.portmode = PORT_HSP_MODE;
3032d17280bSsbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Other: Hot Swappable"));
3042d17280bSsbehera 	} else if (ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip,
3052d17280bSsbehera 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
3062d17280bSsbehera 	    "hot-swappable-phy") == 1) {
3072d17280bSsbehera 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
3082d17280bSsbehera 		nxgep->mac.portmode = PORT_HSP_MODE;
3092d17280bSsbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, ".conf: Hot Swappable"));
3102d17280bSsbehera 	} else if (nxgep->niu_type == N2_NIU &&
3112d17280bSsbehera 	    ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip, 0,
3122d17280bSsbehera 	    "hot-swappable-phy") == 1) {
3132d17280bSsbehera 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
3142d17280bSsbehera 		nxgep->mac.portmode = PORT_HSP_MODE;
3152d17280bSsbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "OBP: Hot Swappable"));
3162d17280bSsbehera 	}
3172d17280bSsbehera 
3182d17280bSsbehera 	/*
3192d17280bSsbehera 	 * MDIO polling support for Monza RTM card, Goa NEM card
3202d17280bSsbehera 	 */
3212d17280bSsbehera 	if (nxgep->mac.portmode == PORT_HSP_MODE) {
3222d17280bSsbehera 		nxgep->hot_swappable_phy = B_TRUE;
323ef523517SMichael Speer 		if (portn > 1) {
324ef523517SMichael Speer 			return (NXGE_ERROR);
325ef523517SMichael Speer 		}
326ef523517SMichael Speer 
32789282175SSantwona Behera 		if (nxge_hswap_phy_present(nxgep, portn))
3282d17280bSsbehera 			goto found_phy;
3292d17280bSsbehera 
3302d17280bSsbehera 		nxgep->phy_absent = B_TRUE;
3311c7408c9Stc 
3321c7408c9Stc 		/* Check Serdes link to detect Opus NEM */
3331c7408c9Stc 		rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
3341c7408c9Stc 		    XPCS_REG_STATUS, &val);
3351c7408c9Stc 
3361c7408c9Stc 		if (rs == 0 && val & XPCS_STATUS_LANE_ALIGN) {
3371c7408c9Stc 			nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3381c7408c9Stc 			nxgep->mac.portmode = PORT_10G_SERDES;
3391c7408c9Stc 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3401c7408c9Stc 			    "HSP 10G Serdes FOUND!!"));
3411c7408c9Stc 		}
3422d17280bSsbehera 		goto check_phy_done;
3432d17280bSsbehera found_phy:
3442d17280bSsbehera 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3452d17280bSsbehera 		nxgep->mac.portmode = PORT_10G_FIBER;
3462d17280bSsbehera 		nxgep->phy_absent = B_FALSE;
3472d17280bSsbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Fiber Xcvr "
3482d17280bSsbehera 		    "found for hot swappable phy"));
3492d17280bSsbehera check_phy_done:
3502d17280bSsbehera 		return (status);
3512d17280bSsbehera 	}
3522d17280bSsbehera 
35300161856Syc 	/* Get phy-type property (May have been set by nxge.conf) */
3542e59129aSraghus 	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip,
3552e59129aSraghus 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
3562e59129aSraghus 	    "phy-type", &prop_val)) == DDI_PROP_SUCCESS) {
3572e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3582e59129aSraghus 		    "found  conf file: phy-type %s", prop_val));
3592e59129aSraghus 		if (strcmp("xgsd", prop_val) == 0) {
3602e59129aSraghus 			nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3612e59129aSraghus 			nxgep->mac.portmode = PORT_10G_SERDES;
3622e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3632e59129aSraghus 			    "found: 10G Serdes"));
3642e59129aSraghus 		} else if (strcmp("gsd", prop_val) == 0) {
3652e59129aSraghus 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
3662e59129aSraghus 			nxgep->mac.portmode = PORT_1G_SERDES;
3672e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Serdes"));
3682e59129aSraghus 		} else if (strcmp("mif", prop_val) == 0) {
3692e59129aSraghus 			nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
3702e59129aSraghus 			nxgep->mac.portmode = PORT_1G_COPPER;
3712e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr"));
3722e59129aSraghus 		} else if (strcmp("pcs", prop_val) == 0) {
3732e59129aSraghus 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
3742e59129aSraghus 			nxgep->mac.portmode = PORT_1G_FIBER;
3752e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G FIBER Xcvr"));
376321febdeSsbehera 		} else if (strcmp("xgf", prop_val) == 0) {
37700161856Syc 			/*
37800161856Syc 			 * Before OBP supports new phy-type property
37900161856Syc 			 * value "xgc", the 10G copper XAUI may carry
38000161856Syc 			 * "xgf" instead of "xgc". If the OBP is
38100161856Syc 			 * upgraded to a newer version which supports
38200161856Syc 			 * "xgc", then the TN1010 related code in this
38300161856Syc 			 * "xgf" case will not be used anymore.
38400161856Syc 			 */
38500161856Syc 			if (nxge_is_tn1010_phy(nxgep)) {
38600161856Syc 				if ((status = nxge_set_tn1010_param(nxgep))
38700161856Syc 				    != NXGE_OK) {
38800161856Syc 					return (status);
38900161856Syc 				}
39000161856Syc 				NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
39100161856Syc 			} else {  /* For Fiber XAUI */
39200161856Syc 				nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
39300161856Syc 				nxgep->mac.portmode = PORT_10G_FIBER;
39400161856Syc 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
39500161856Syc 				    "10G Fiber Xcvr"));
39600161856Syc 			}
39700161856Syc 		} else if (strcmp("xgc", prop_val) == 0) {
39800161856Syc 			if ((status = nxge_set_tn1010_param(nxgep)) != NXGE_OK)
39900161856Syc 				return (status);
40000161856Syc 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
4012e59129aSraghus 		}
4022e59129aSraghus 
4032e59129aSraghus 		(void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip,
4042e59129aSraghus 		    "phy-type", prop_val);
4052e59129aSraghus 		ddi_prop_free(prop_val);
4062e59129aSraghus 
4072e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
4082e59129aSraghus 		    "Got phy type [0x%x] from conf file",
4092e59129aSraghus 		    nxgep->mac.portmode));
4102e59129aSraghus 
4112e59129aSraghus 		return (NXGE_OK);
4122e59129aSraghus 	}
4132d17280bSsbehera 
4142d17280bSsbehera 	/* Get phy-type property from OBP */
4152e59129aSraghus 	if (nxgep->niu_type == N2_NIU) {
4162e59129aSraghus 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0,
4172e59129aSraghus 		    "phy-type", &prop_val) == DDI_PROP_SUCCESS) {
4182e59129aSraghus 			if (strcmp("xgf", prop_val) == 0) {
41900161856Syc 				/*
42000161856Syc 				 * Before OBP supports new phy-type property
42100161856Syc 				 * value "xgc", the 10G copper XAUI may carry
42200161856Syc 				 * "xgf" instead of "xgc". If the OBP is
42300161856Syc 				 * upgraded to a newer version which supports
42400161856Syc 				 * "xgc", then the TN1010 related code in this
42500161856Syc 				 * "xgf" case will not be used anymore.
42600161856Syc 				 */
42700161856Syc 				if (nxge_is_tn1010_phy(nxgep)) {
42800161856Syc 					if ((status =
42900161856Syc 					    nxge_set_tn1010_param(nxgep))
43000161856Syc 					    != NXGE_OK) {
43100161856Syc 						return (status);
43200161856Syc 					}
43300161856Syc 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
43400161856Syc 					    "TN1010 Xcvr"));
43589282175SSantwona Behera 				} else if (nxge_is_nlp2020_phy(nxgep)) {
43689282175SSantwona Behera 					if ((status =
43789282175SSantwona Behera 					    nxge_set_nlp2020_param(nxgep))
43889282175SSantwona Behera 					    != NXGE_OK) {
43989282175SSantwona Behera 						return (status);
44089282175SSantwona Behera 					}
44189282175SSantwona Behera 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
44289282175SSantwona Behera 					    "NLP2020 Xcvr"));
44389282175SSantwona Behera 				} else { /* For Fiber XAUI */
44400161856Syc 					nxgep->statsp->mac_stats.xcvr_inuse
44500161856Syc 					    = XPCS_XCVR;
44600161856Syc 					nxgep->mac.portmode = PORT_10G_FIBER;
44700161856Syc 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
44800161856Syc 					    "10G Fiber Xcvr"));
44900161856Syc 				}
4502e59129aSraghus 			} else if (strcmp("mif", prop_val) == 0) {
4512e59129aSraghus 				nxgep->statsp->mac_stats.xcvr_inuse =
4522e59129aSraghus 				    INT_MII_XCVR;
4532e59129aSraghus 				nxgep->mac.portmode = PORT_1G_COPPER;
4542e59129aSraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4552e59129aSraghus 				    "1G Copper Xcvr"));
4562e59129aSraghus 			} else if (strcmp("pcs", prop_val) == 0) {
4572e59129aSraghus 				nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
4582e59129aSraghus 				nxgep->mac.portmode = PORT_1G_FIBER;
4592e59129aSraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4602e59129aSraghus 				    "1G Fiber Xcvr"));
4612e59129aSraghus 			} else if (strcmp("xgc", prop_val) == 0) {
46200161856Syc 				status = nxge_set_tn1010_param(nxgep);
46300161856Syc 				if (status != NXGE_OK)
46400161856Syc 					return (status);
46500161856Syc 				NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
4662e59129aSraghus 			} else if (strcmp("xgsd", prop_val) == 0) {
4672e59129aSraghus 				nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
4682e59129aSraghus 				nxgep->mac.portmode = PORT_10G_SERDES;
4692e59129aSraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4702e59129aSraghus 				    "OBP: 10G Serdes"));
4712e59129aSraghus 			} else if (strcmp("gsd", prop_val) == 0) {
4722e59129aSraghus 				nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
4732e59129aSraghus 				nxgep->mac.portmode = PORT_1G_SERDES;
4742e59129aSraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4752e59129aSraghus 				    "OBP: 1G Serdes"));
4762e59129aSraghus 			} else {
4772e59129aSraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4782e59129aSraghus 				    "Unknown phy-type: %s", prop_val));
4792e59129aSraghus 				ddi_prop_free(prop_val);
4802e59129aSraghus 				return (NXGE_ERROR);
4812e59129aSraghus 			}
4822e59129aSraghus 			status = NXGE_OK;
4832e59129aSraghus 			(void) ddi_prop_update_string(DDI_DEV_T_NONE,
4842e59129aSraghus 			    nxgep->dip, "phy-type", prop_val);
4852e59129aSraghus 			ddi_prop_free(prop_val);
4862e59129aSraghus 
4872e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
4882e59129aSraghus 			    "Got phy type [0x%x] from OBP",
4892e59129aSraghus 			    nxgep->mac.portmode));
4902e59129aSraghus 
4912e59129aSraghus 			return (status);
4922e59129aSraghus 		} else {
4932e59129aSraghus 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4942e59129aSraghus 			    "Exiting...phy-type property not found"));
4952e59129aSraghus 			return (NXGE_ERROR);
4962e59129aSraghus 		}
4972e59129aSraghus 	}
4982e59129aSraghus 
4992e59129aSraghus 
5002e59129aSraghus 	if (!nxgep->vpd_info.present) {
5012e59129aSraghus 		return (NXGE_OK);
5022e59129aSraghus 	}
5032e59129aSraghus 
5042e59129aSraghus 	if (!nxgep->vpd_info.ver_valid) {
5052e59129aSraghus 		goto read_seeprom;
5062e59129aSraghus 	}
5072e59129aSraghus 
5082e59129aSraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5092e59129aSraghus 	    "Reading phy type from expansion ROM"));
5102e59129aSraghus 	/*
5112e59129aSraghus 	 * Try to read the phy type from the vpd data read off the
5122e59129aSraghus 	 * expansion ROM.
5132e59129aSraghus 	 */
5142e59129aSraghus 	phy_type = nxgep->vpd_info.phy_type;
5152e59129aSraghus 
516d81011f0Ssbehera 	if (strncmp(phy_type, "mif", 3) == 0) {
5172e59129aSraghus 		nxgep->mac.portmode = PORT_1G_COPPER;
5182e59129aSraghus 		nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
519d81011f0Ssbehera 	} else if (strncmp(phy_type, "xgf", 3) == 0) {
5202e59129aSraghus 		nxgep->mac.portmode = PORT_10G_FIBER;
5212e59129aSraghus 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
522d81011f0Ssbehera 	} else if (strncmp(phy_type, "pcs", 3) == 0) {
5232e59129aSraghus 		nxgep->mac.portmode = PORT_1G_FIBER;
5242e59129aSraghus 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
525d81011f0Ssbehera 	} else if (strncmp(phy_type, "xgc", 3) == 0) {
52600161856Syc 		status = nxge_set_tn1010_param(nxgep);
52700161856Syc 		if (status != NXGE_OK) {
52800161856Syc 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
52900161856Syc 			    "nxge_get_xcvr_type: Failed to set TN1010 param"));
53000161856Syc 			goto read_seeprom;
53100161856Syc 		}
532d81011f0Ssbehera 	} else if (strncmp(phy_type, "xgsd", 4) == 0) {
533d81011f0Ssbehera 		nxgep->mac.portmode = PORT_10G_SERDES;
534d81011f0Ssbehera 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
535d81011f0Ssbehera 	} else if (strncmp(phy_type, "gsd", 3) == 0) {
536d81011f0Ssbehera 		nxgep->mac.portmode = PORT_1G_SERDES;
537d81011f0Ssbehera 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
5382e59129aSraghus 	} else {
539d81011f0Ssbehera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5402e59129aSraghus 		    "nxge_get_xcvr_type: Unknown phy type [%c%c%c] in EEPROM",
5412e59129aSraghus 		    phy_type[0], phy_type[1], phy_type[2]));
5422e59129aSraghus 		goto read_seeprom;
5432e59129aSraghus 	}
5442e59129aSraghus 
5452e59129aSraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
5462e59129aSraghus 	    "Got phy type [0x%x] from VPD", nxgep->mac.portmode));
5472e59129aSraghus 
5482e59129aSraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type"));
5492e59129aSraghus 	return (status);
5502e59129aSraghus 
5512e59129aSraghus read_seeprom:
5522e59129aSraghus 	/*
5532e59129aSraghus 	 * read the phy type from the SEEPROM - NCR registers
5542e59129aSraghus 	 */
5552e59129aSraghus 	status = nxge_espc_phy_type_get(nxgep);
5562e59129aSraghus 	if (status != NXGE_OK) {
5572e59129aSraghus 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5582e59129aSraghus 		    "Failed to get phy type"));
5592e59129aSraghus 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version "
5602e59129aSraghus 		    "[%s] invalid...please update", nxgep->vpd_info.ver));
5612e59129aSraghus 	}
5622e59129aSraghus 
5632e59129aSraghus 	return (status);
5642e59129aSraghus 
5652e59129aSraghus }
5662e59129aSraghus 
56759ac0c16Sdavemq /* Set up the PHY specific values. */
56859ac0c16Sdavemq 
56959ac0c16Sdavemq nxge_status_t
nxge_setup_xcvr_table(p_nxge_t nxgep)57059ac0c16Sdavemq nxge_setup_xcvr_table(p_nxge_t nxgep)
57159ac0c16Sdavemq {
57259ac0c16Sdavemq 	nxge_status_t	status = NXGE_OK;
57359ac0c16Sdavemq 	uint32_t	port_type;
57459ac0c16Sdavemq 	uint8_t		portn = NXGE_GET_PORT_NUM(nxgep->function_num);
5752e59129aSraghus 	uint32_t	pcs_id = 0;
5762e59129aSraghus 	uint32_t	pma_pmd_id = 0;
5772e59129aSraghus 	uint32_t	phy_id = 0;
5782d17280bSsbehera 	uint16_t	chip_id = 0;
57959ac0c16Sdavemq 
58059ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_setup_xcvr_table: port<%d>",
58159ac0c16Sdavemq 	    portn));
58259ac0c16Sdavemq 
5832e59129aSraghus 	switch (nxgep->niu_type) {
5842e59129aSraghus 	case N2_NIU:
5852e59129aSraghus 		switch (nxgep->mac.portmode) {
5862e59129aSraghus 		case PORT_1G_FIBER:
5872e59129aSraghus 		case PORT_1G_SERDES:
5882e59129aSraghus 			nxgep->xcvr = nxge_n2_1G_table;
5892d17280bSsbehera 			nxgep->xcvr_addr = portn;
5902e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 1G %s Xcvr",
5912e59129aSraghus 			    (nxgep->mac.portmode == PORT_1G_FIBER) ? "Fiber" :
5922e59129aSraghus 			    "Serdes"));
5932e59129aSraghus 			break;
5942e59129aSraghus 		case PORT_10G_FIBER:
59589282175SSantwona Behera 		case PORT_10G_COPPER:
5962e59129aSraghus 		case PORT_10G_SERDES:
5972e59129aSraghus 			nxgep->xcvr = nxge_n2_10G_table;
5982d17280bSsbehera 			if (nxgep->nxge_hw_p->xcvr_addr[portn]) {
5992d17280bSsbehera 				nxgep->xcvr_addr =
6002d17280bSsbehera 				    nxgep->nxge_hw_p->xcvr_addr[portn];
6012d17280bSsbehera 			}
6022e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G %s Xcvr",
6032e59129aSraghus 			    (nxgep->mac.portmode == PORT_10G_FIBER) ? "Fiber" :
60489282175SSantwona Behera 			    ((nxgep->mac.portmode == PORT_10G_COPPER) ?
60589282175SSantwona Behera 			    "Copper" : "Serdes")));
6062e59129aSraghus 			break;
60700161856Syc 		case PORT_1G_TN1010:
60800161856Syc 			nxgep->xcvr = nxge_n2_1G_tn1010_table;
60900161856Syc 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
61000161856Syc 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61100161856Syc 			    "TN1010 Copper Xcvr in 1G"));
61200161856Syc 			break;
61300161856Syc 		case PORT_10G_TN1010:
61400161856Syc 			nxgep->xcvr = nxge_n2_10G_tn1010_table;
61500161856Syc 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
61600161856Syc 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61700161856Syc 			    "TN1010 Copper Xcvr in 10G"));
61800161856Syc 			break;
6192d17280bSsbehera 		case PORT_HSP_MODE:
6202d17280bSsbehera 			nxgep->xcvr = nxge_n2_10G_table;
6212d17280bSsbehera 			nxgep->xcvr.xcvr_inuse = HSP_XCVR;
6222d17280bSsbehera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G Hot "
6232d17280bSsbehera 			    "Swappable Xcvr (not present)"));
6242d17280bSsbehera 			break;
6252e59129aSraghus 		default:
6262e59129aSraghus 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6272e59129aSraghus 			    "<== nxge_setup_xcvr_table: "
6282e59129aSraghus 			    "Unable to determine NIU portmode"));
6292e59129aSraghus 			return (NXGE_ERROR);
6302e59129aSraghus 		}
6312e59129aSraghus 		break;
6322e59129aSraghus 	default:
6332e59129aSraghus 		if (nxgep->mac.portmode == 0) {
6342e59129aSraghus 			/*
6352e59129aSraghus 			 * Would be the case for platforms like Maramba
6362e59129aSraghus 			 * in which the phy type could not be got from conf
6372e59129aSraghus 			 * file, OBP, VPD or Serial PROM.
6382e59129aSraghus 			 */
6392e59129aSraghus 			if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
6402e59129aSraghus 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6412e59129aSraghus 				    "<== nxge_setup_xcvr_table:"
6422e59129aSraghus 				    " Invalid Neptune type [0x%x]",
6432e59129aSraghus 				    nxgep->niu_type));
6442e59129aSraghus 				return (NXGE_ERROR);
6452e59129aSraghus 			}
6462e59129aSraghus 
6472e59129aSraghus 			port_type = nxgep->niu_type >>
6482e59129aSraghus 			    (NXGE_PORT_TYPE_SHIFT * portn);
6492e59129aSraghus 			port_type = port_type & (NXGE_PORT_TYPE_MASK);
6502e59129aSraghus 
6512e59129aSraghus 			switch (port_type) {
6522e59129aSraghus 
6532e59129aSraghus 			case NXGE_PORT_1G_COPPER:
6542e59129aSraghus 				nxgep->mac.portmode = PORT_1G_COPPER;
6552e59129aSraghus 				break;
6562e59129aSraghus 			case NXGE_PORT_10G_COPPER:
6572e59129aSraghus 				nxgep->mac.portmode = PORT_10G_COPPER;
6582e59129aSraghus 				break;
6592e59129aSraghus 			case NXGE_PORT_1G_FIBRE:
6602e59129aSraghus 				nxgep->mac.portmode = PORT_1G_FIBER;
6612e59129aSraghus 				break;
6622e59129aSraghus 			case NXGE_PORT_10G_FIBRE:
6632e59129aSraghus 				nxgep->mac.portmode = PORT_10G_FIBER;
6642e59129aSraghus 				break;
6652e59129aSraghus 			case NXGE_PORT_1G_SERDES:
6662e59129aSraghus 				nxgep->mac.portmode = PORT_1G_SERDES;
6672e59129aSraghus 				break;
6682e59129aSraghus 			case NXGE_PORT_10G_SERDES:
6692e59129aSraghus 				nxgep->mac.portmode = PORT_10G_SERDES;
6702e59129aSraghus 				break;
67100161856Syc 			/* Ports 2 and 3 of Alonso or ARTM */
6722e59129aSraghus 			case NXGE_PORT_1G_RGMII_FIBER:
6732e59129aSraghus 				nxgep->mac.portmode = PORT_1G_RGMII_FIBER;
6742e59129aSraghus 				break;
67500161856Syc 			case NXGE_PORT_TN1010:
67600161856Syc 				/*
67700161856Syc 				 * If this port uses the TN1010 copper
67800161856Syc 				 * PHY, then its speed is not known yet
67900161856Syc 				 * because nxge_scan_ports_phy could only
68000161856Syc 				 * figure out the vendor of the PHY but
68100161856Syc 				 * not its speed. nxge_set_tn1010_param
68200161856Syc 				 * will read the PHY speed and set
68300161856Syc 				 * portmode accordingly.
68400161856Syc 				 */
68500161856Syc 				if ((status = nxge_set_tn1010_param(nxgep))
68600161856Syc 				    != NXGE_OK) {
68700161856Syc 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
68800161856Syc 					    "nxge_set_tn1010_param failed"));
68900161856Syc 					return (status);
69000161856Syc 				}
69100161856Syc 				break;
6922e59129aSraghus 			default:
6932e59129aSraghus 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6942e59129aSraghus 				    "<== nxge_setup_xcvr_table: "
6952e59129aSraghus 				    "Unknown port-type: 0x%x", port_type));
6962e59129aSraghus 				return (NXGE_ERROR);
6972e59129aSraghus 			}
6982e59129aSraghus 		}
6992e59129aSraghus 
70000161856Syc 		/*
70100161856Syc 		 * Above switch has figured out nxge->mac.portmode, now set
70200161856Syc 		 * nxgep->xcvr (the table) and nxgep->xcvr_addr according
70300161856Syc 		 * to portmode.
70400161856Syc 		 */
7052e59129aSraghus 		switch (nxgep->mac.portmode) {
7062e59129aSraghus 		case PORT_1G_COPPER:
7072e59129aSraghus 		case PORT_1G_RGMII_FIBER:
70859ac0c16Sdavemq 			nxgep->xcvr = nxge_1G_copper_table;
7092d17280bSsbehera 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
71059ac0c16Sdavemq 			/*
71159ac0c16Sdavemq 			 * For Altas 4-1G copper, Xcvr port numbers are
71259ac0c16Sdavemq 			 * swapped with ethernet port number. This is
7132e59129aSraghus 			 * designed for better signal integrity in
7142e59129aSraghus 			 * routing. This is also the case for the
7152e59129aSraghus 			 * on-board Neptune copper ports on the Maramba
7162e59129aSraghus 			 * platform.
71759ac0c16Sdavemq 			 */
7182e59129aSraghus 			switch (nxgep->platform_type) {
7192e59129aSraghus 			case P_NEPTUNE_ATLAS_4PORT:
7202e59129aSraghus 			case P_NEPTUNE_MARAMBA_P0:
7212e59129aSraghus 			case P_NEPTUNE_MARAMBA_P1:
7222e59129aSraghus 				switch (portn) {
7232e59129aSraghus 				case 0:
7242d17280bSsbehera 					nxgep->xcvr_addr += 3;
7252e59129aSraghus 					break;
7262e59129aSraghus 				case 1:
7272d17280bSsbehera 					nxgep->xcvr_addr += 1;
7282e59129aSraghus 					break;
7292e59129aSraghus 				case 2:
7302d17280bSsbehera 					nxgep->xcvr_addr -= 1;
7312e59129aSraghus 					break;
7322e59129aSraghus 				case 3:
7332d17280bSsbehera 					nxgep->xcvr_addr -= 3;
7342e59129aSraghus 					break;
7352e59129aSraghus 				default:
7362e59129aSraghus 					return (NXGE_ERROR);
7372e59129aSraghus 				}
73859ac0c16Sdavemq 				break;
73959ac0c16Sdavemq 			default:
7402e59129aSraghus 				break;
74159ac0c16Sdavemq 			}
742d81011f0Ssbehera 
7432e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
7442e59129aSraghus 			    (nxgep->mac.portmode == PORT_1G_COPPER) ?
7452e59129aSraghus 			    "Copper" : "RGMII Fiber"));
74659ac0c16Sdavemq 			break;
74700161856Syc 
7482e59129aSraghus 		case PORT_10G_COPPER:
74959ac0c16Sdavemq 			nxgep->xcvr = nxge_10G_copper_table;
75059ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr"));
75159ac0c16Sdavemq 			break;
75200161856Syc 
75300161856Syc 		case PORT_1G_TN1010:
75400161856Syc 			nxgep->xcvr = nxge_1G_tn1010_table;
75500161856Syc 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
75600161856Syc 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
75700161856Syc 			    "1G TN1010 copper Xcvr"));
75800161856Syc 			break;
75900161856Syc 
76000161856Syc 		case PORT_10G_TN1010:
76100161856Syc 			nxgep->xcvr = nxge_10G_tn1010_table;
76200161856Syc 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
76300161856Syc 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
76400161856Syc 			    "10G TN1010 copper Xcvr"));
76500161856Syc 			break;
76600161856Syc 
7672e59129aSraghus 		case PORT_1G_FIBER:
7682e59129aSraghus 		case PORT_1G_SERDES:
76959ac0c16Sdavemq 			nxgep->xcvr = nxge_1G_fiber_table;
7702d17280bSsbehera 			nxgep->xcvr_addr = portn;
7712e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
7722e59129aSraghus 			    (nxgep->mac.portmode == PORT_1G_FIBER) ?
7732e59129aSraghus 			    "Fiber" : "Serdes"));
77459ac0c16Sdavemq 			break;
7752e59129aSraghus 		case PORT_10G_FIBER:
7762e59129aSraghus 		case PORT_10G_SERDES:
77759ac0c16Sdavemq 			nxgep->xcvr = nxge_10G_fiber_table;
7782d17280bSsbehera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G xcvr "
7792d17280bSsbehera 			    "nxgep->nxge_hw_p->xcvr_addr[portn] = [%d] "
7802d17280bSsbehera 			    "nxgep->xcvr_addr = [%d]",
7812d17280bSsbehera 			    nxgep->nxge_hw_p->xcvr_addr[portn],
7822d17280bSsbehera 			    nxgep->xcvr_addr));
7832d17280bSsbehera 			if (nxgep->nxge_hw_p->xcvr_addr[portn]) {
7842d17280bSsbehera 				nxgep->xcvr_addr =
7852d17280bSsbehera 				    nxgep->nxge_hw_p->xcvr_addr[portn];
7862d17280bSsbehera 			}
7872e59129aSraghus 			switch (nxgep->platform_type) {
7882e59129aSraghus 			case P_NEPTUNE_MARAMBA_P0:
7892e59129aSraghus 			case P_NEPTUNE_MARAMBA_P1:
79059ac0c16Sdavemq 				/*
79159ac0c16Sdavemq 				 * Switch off LED for corresponding copper
79259ac0c16Sdavemq 				 * port
79359ac0c16Sdavemq 				 */
79459ac0c16Sdavemq 				nxge_bcm5464_link_led_off(nxgep);
7952e59129aSraghus 				break;
7962e59129aSraghus 			default:
7972e59129aSraghus 				break;
79859ac0c16Sdavemq 			}
7992e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G %s Xcvr",
8002e59129aSraghus 			    (nxgep->mac.portmode == PORT_10G_FIBER) ?
8012e59129aSraghus 			    "Fiber" : "Serdes"));
80259ac0c16Sdavemq 			break;
8032d17280bSsbehera 
8042d17280bSsbehera 		case PORT_HSP_MODE:
8052d17280bSsbehera 			nxgep->xcvr = nxge_10G_fiber_table;
8062d17280bSsbehera 			nxgep->xcvr.xcvr_inuse = HSP_XCVR;
8072d17280bSsbehera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Neptune 10G Hot "
8082d17280bSsbehera 			    "Swappable Xcvr (not present)"));
8092d17280bSsbehera 			break;
81059ac0c16Sdavemq 		default:
81159ac0c16Sdavemq 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
81259ac0c16Sdavemq 			    "Unknown port-type: 0x%x", port_type));
81359ac0c16Sdavemq 			return (NXGE_ERROR);
81459ac0c16Sdavemq 		}
81559ac0c16Sdavemq 	}
81659ac0c16Sdavemq 
81789282175SSantwona Behera 	if (nxgep->mac.portmode == PORT_10G_FIBER ||
81889282175SSantwona Behera 	    nxgep->mac.portmode == PORT_10G_COPPER) {
81952cdd236Ssbehera 		uint32_t pma_pmd_id;
82052cdd236Ssbehera 		pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep,
82152cdd236Ssbehera 		    nxgep->xcvr_addr);
82252cdd236Ssbehera 		if ((pma_pmd_id & BCM_PHY_ID_MASK) == MARVELL_88X201X_PHY_ID) {
82352cdd236Ssbehera 			chip_id = MRVL88X201X_CHIP_ID;
82452cdd236Ssbehera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
82552cdd236Ssbehera 			    "nxge_setup_xcvr_table: "
82652cdd236Ssbehera 			    "Chip ID  MARVELL [0x%x] for 10G xcvr", chip_id));
82789282175SSantwona Behera 		} else if ((pma_pmd_id & NLP2020_DEV_ID_MASK) ==
82889282175SSantwona Behera 		    NLP2020_DEV_ID) {
82989282175SSantwona Behera 			chip_id = NLP2020_CHIP_ID;
83089282175SSantwona Behera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
83189282175SSantwona Behera 			    "nxge_setup_xcvr_table: "
83289282175SSantwona Behera 			    "Chip ID  AEL2020 [0x%x] for 10G xcvr", chip_id));
83352cdd236Ssbehera 		} else if ((status = nxge_mdio_read(nxgep, nxgep->xcvr_addr,
8342d17280bSsbehera 		    BCM8704_PCS_DEV_ADDR, BCM8704_CHIP_ID_REG,
8352d17280bSsbehera 		    &chip_id)) == NXGE_OK) {
8362d17280bSsbehera 
8372d17280bSsbehera 			switch (chip_id) {
8382d17280bSsbehera 			case BCM8704_CHIP_ID:
8392d17280bSsbehera 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
8402d17280bSsbehera 				    "nxge_setup_xcvr_table: "
8412d17280bSsbehera 				    "Chip ID 8704 [0x%x] for 10G xcvr",
8422d17280bSsbehera 				    chip_id));
8432d17280bSsbehera 				break;
8442d17280bSsbehera 			case BCM8706_CHIP_ID:
8452d17280bSsbehera 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
8462d17280bSsbehera 				    "nxge_setup_xcvr_table: "
8472d17280bSsbehera 				    "Chip ID 8706 [0x%x] for 10G xcvr",
8482d17280bSsbehera 				    chip_id));
8492d17280bSsbehera 				break;
8502d17280bSsbehera 			default:
8512d17280bSsbehera 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8522d17280bSsbehera 				    "nxge_setup_xcvr_table: "
8532d17280bSsbehera 				    "Unknown Chip ID [0x%x] for 10G xcvr",
8542d17280bSsbehera 				    chip_id));
8552d17280bSsbehera 				break;
8562d17280bSsbehera 			}
8572d17280bSsbehera 		}
8582d17280bSsbehera 	}
8592d17280bSsbehera 
86059ac0c16Sdavemq 	nxgep->statsp->mac_stats.xcvr_inuse = nxgep->xcvr.xcvr_inuse;
8612d17280bSsbehera 	nxgep->statsp->mac_stats.xcvr_portn = nxgep->xcvr_addr;
8622d17280bSsbehera 	nxgep->chip_id = chip_id;
8632e59129aSraghus 
8642e59129aSraghus 	/*
8652e59129aSraghus 	 * Get the actual device ID value returned by MDIO read.
8662e59129aSraghus 	 */
8672e59129aSraghus 	nxgep->statsp->mac_stats.xcvr_id = 0;
8682e59129aSraghus 
8692d17280bSsbehera 	pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, nxgep->xcvr_addr);
8702e59129aSraghus 	if (nxge_is_supported_phy(pma_pmd_id, CLAUSE_45_TYPE)) {
8712e59129aSraghus 		nxgep->statsp->mac_stats.xcvr_id = pma_pmd_id;
8722e59129aSraghus 	} else {
8732d17280bSsbehera 		pcs_id = nxge_get_cl45_pcs_id(nxgep, nxgep->xcvr_addr);
8742e59129aSraghus 		if (nxge_is_supported_phy(pcs_id, CLAUSE_45_TYPE)) {
8752e59129aSraghus 			nxgep->statsp->mac_stats.xcvr_id = pcs_id;
8762e59129aSraghus 		} else {
8772e59129aSraghus 			phy_id = nxge_get_cl22_phy_id(nxgep,
8782d17280bSsbehera 			    nxgep->xcvr_addr);
8792e59129aSraghus 			if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) {
8802e59129aSraghus 				nxgep->statsp->mac_stats.xcvr_id = phy_id;
8812e59129aSraghus 			}
8822e59129aSraghus 		}
8832e59129aSraghus 	}
8842e59129aSraghus 
88559ac0c16Sdavemq 	nxgep->mac.linkchkmode = LINKCHK_TIMER;
88659ac0c16Sdavemq 
8872e59129aSraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_setup_xcvr_table: niu_type"
88823b952a3SSantwona Behera 	    "[0x%x] platform type[0x%x] xcvr_addr[%d]", nxgep->niu_type,
8892d17280bSsbehera 	    nxgep->platform_type, nxgep->xcvr_addr));
8902e59129aSraghus 
89159ac0c16Sdavemq 	return (status);
89259ac0c16Sdavemq }
89359ac0c16Sdavemq 
89444961713Sgirish /* Initialize the entire MAC and physical layer */
89544961713Sgirish 
89644961713Sgirish nxge_status_t
nxge_mac_init(p_nxge_t nxgep)89744961713Sgirish nxge_mac_init(p_nxge_t nxgep)
89844961713Sgirish {
89944961713Sgirish 	uint8_t			portn;
90044961713Sgirish 	nxge_status_t		status = NXGE_OK;
90144961713Sgirish 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
90244961713Sgirish 
90344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn));
90444961713Sgirish 
90544961713Sgirish 	nxgep->mac.portnum = portn;
90644961713Sgirish 	nxgep->mac.porttype = PORT_TYPE_XMAC;
90744961713Sgirish 
90844961713Sgirish 	if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1))
90944961713Sgirish 		nxgep->mac.porttype = PORT_TYPE_BMAC;
91044961713Sgirish 
91100161856Syc 
91244961713Sgirish 	/* Initialize XIF to configure a network mode */
91344961713Sgirish 	if ((status = nxge_xif_init(nxgep)) != NXGE_OK) {
91444961713Sgirish 		goto fail;
91544961713Sgirish 	}
91644961713Sgirish 
91744961713Sgirish 	if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) {
91844961713Sgirish 		goto fail;
91944961713Sgirish 	}
92044961713Sgirish 
92144961713Sgirish 	/* Initialize TX and RX MACs */
92244961713Sgirish 	/*
92344961713Sgirish 	 * Always perform XIF init first, before TX and RX MAC init
92444961713Sgirish 	 */
92544961713Sgirish 	if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK)
92644961713Sgirish 		goto fail;
92744961713Sgirish 
92844961713Sgirish 	if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
92944961713Sgirish 		goto fail;
93044961713Sgirish 
93144961713Sgirish 	if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK)
93244961713Sgirish 		goto fail;
93344961713Sgirish 
93444961713Sgirish 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
93544961713Sgirish 		goto fail;
93644961713Sgirish 
93744961713Sgirish 	if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK)
93844961713Sgirish 		goto fail;
93944961713Sgirish 
940e759c33aSMichael Speer 	if (nxgep->nxge_mac_state == NXGE_MAC_STARTED) {
941e759c33aSMichael Speer 		if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
942e759c33aSMichael Speer 			goto fail;
943e759c33aSMichael Speer 	}
94444961713Sgirish 
945cb9d3ae6Smisaki 	/* Initialize MAC control configuration */
946cb9d3ae6Smisaki 	if ((status = nxge_mac_ctrl_init(nxgep)) != NXGE_OK) {
947cb9d3ae6Smisaki 		goto fail;
948cb9d3ae6Smisaki 	}
949cb9d3ae6Smisaki 
95044961713Sgirish 	nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize;
95144961713Sgirish 
952d81011f0Ssbehera 	/* The Neptune Serdes needs to be reinitialized again */
953d81011f0Ssbehera 	if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
954d81011f0Ssbehera 	    ((nxgep->mac.portmode == PORT_1G_SERDES) ||
95500161856Syc 	    (nxgep->mac.portmode == PORT_1G_TN1010) ||
956d81011f0Ssbehera 	    (nxgep->mac.portmode == PORT_1G_FIBER)) &&
957d81011f0Ssbehera 	    ((portn == 0) || (portn == 1))) {
958d81011f0Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
959d81011f0Ssbehera 		    "nxge_mac_init: reinit Neptune 1G Serdes "));
960d81011f0Ssbehera 		if ((status = nxge_1G_serdes_init(nxgep)) != NXGE_OK) {
961d81011f0Ssbehera 			goto fail;
962d81011f0Ssbehera 		}
963d81011f0Ssbehera 	}
964d81011f0Ssbehera 
9652e59129aSraghus 
96644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn));
96744961713Sgirish 
96844961713Sgirish 	return (NXGE_OK);
96944961713Sgirish fail:
97044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
97152ccf843Smisaki 	    "nxge_mac_init: failed to initialize MAC port<%d>", portn));
97244961713Sgirish 	return (status);
97344961713Sgirish }
97444961713Sgirish 
97544961713Sgirish /* Initialize the Ethernet Link */
97644961713Sgirish 
97744961713Sgirish nxge_status_t
nxge_link_init(p_nxge_t nxgep)97844961713Sgirish nxge_link_init(p_nxge_t nxgep)
97944961713Sgirish {
98044961713Sgirish 	nxge_status_t		status = NXGE_OK;
9812e59129aSraghus 	nxge_port_mode_t	portmode;
98244961713Sgirish #ifdef	NXGE_DEBUG
98344961713Sgirish 	uint8_t			portn;
98444961713Sgirish 
98544961713Sgirish 	portn = nxgep->mac.portnum;
98644961713Sgirish 
98744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn));
98844961713Sgirish #endif
9891c7408c9Stc 	/* For Opus NEM, Serdes always needs to be initialized */
99044961713Sgirish 
9912e59129aSraghus 	portmode = nxgep->mac.portmode;
9922d17280bSsbehera 
99300161856Syc 	/*
99400161856Syc 	 * Workaround to get link up in both NIU ports. Some portmodes require
99500161856Syc 	 * that the xcvr be initialized twice, the first time before calling
99600161856Syc 	 * nxge_serdes_init.
99700161856Syc 	 */
9982e59129aSraghus 	if (nxgep->niu_type == N2_NIU && (portmode != PORT_10G_SERDES) &&
99900161856Syc 	    (portmode != PORT_10G_TN1010) &&
100000161856Syc 	    (portmode != PORT_1G_TN1010) &&
10012e59129aSraghus 	    (portmode != PORT_1G_SERDES)) {
10022e59129aSraghus 		if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) {
100344961713Sgirish 			goto fail;
10042e59129aSraghus 		}
100544961713Sgirish 	}
100600161856Syc 
100744961713Sgirish 	NXGE_DELAY(200000);
100844961713Sgirish 	/* Initialize internal serdes */
100944961713Sgirish 	if ((status = nxge_serdes_init(nxgep)) != NXGE_OK)
101044961713Sgirish 		goto fail;
101144961713Sgirish 	NXGE_DELAY(200000);
101244961713Sgirish 	if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK)
101344961713Sgirish 		goto fail;
101444961713Sgirish 
101544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn));
101644961713Sgirish 
101744961713Sgirish 	return (NXGE_OK);
101844961713Sgirish 
101944961713Sgirish fail:
102052ccf843Smisaki 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_link_init: ",
102152ccf843Smisaki 	    "failed to initialize Ethernet link on port<%d>", portn));
102244961713Sgirish 
102344961713Sgirish 	return (status);
102444961713Sgirish }
102544961713Sgirish 
102644961713Sgirish 
102744961713Sgirish /* Initialize the XIF sub-block within the MAC */
102844961713Sgirish 
102944961713Sgirish nxge_status_t
nxge_xif_init(p_nxge_t nxgep)103044961713Sgirish nxge_xif_init(p_nxge_t nxgep)
103144961713Sgirish {
103244961713Sgirish 	uint32_t		xif_cfg = 0;
103344961713Sgirish 	npi_attr_t		ap;
103444961713Sgirish 	uint8_t			portn;
103544961713Sgirish 	nxge_port_t		portt;
103644961713Sgirish 	nxge_port_mode_t	portmode;
103744961713Sgirish 	p_nxge_stats_t		statsp;
103844961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
103944961713Sgirish 	npi_handle_t		handle;
104044961713Sgirish 
104144961713Sgirish 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
104244961713Sgirish 
104344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn));
104444961713Sgirish 
104544961713Sgirish 	handle = nxgep->npi_handle;
104644961713Sgirish 	portmode = nxgep->mac.portmode;
104744961713Sgirish 	portt = nxgep->mac.porttype;
104844961713Sgirish 	statsp = nxgep->statsp;
104944961713Sgirish 
1050d81011f0Ssbehera 	if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
1051d81011f0Ssbehera 	    ((nxgep->mac.portmode == PORT_1G_SERDES) ||
105200161856Syc 	    (nxgep->mac.portmode == PORT_1G_TN1010) ||
1053d81011f0Ssbehera 	    (nxgep->mac.portmode == PORT_1G_FIBER)) &&
1054d81011f0Ssbehera 	    ((portn == 0) || (portn == 1))) {
1055d81011f0Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1056d81011f0Ssbehera 		    "nxge_xcvr_init: set ATCA mode"));
1057d81011f0Ssbehera 		npi_mac_mif_set_atca_mode(nxgep->npi_handle, B_TRUE);
1058d81011f0Ssbehera 	}
1059d81011f0Ssbehera 
106044961713Sgirish 	if (portt == PORT_TYPE_XMAC) {
106144961713Sgirish 
106244961713Sgirish 		/* Setup XIF Configuration for XMAC */
106344961713Sgirish 
106444961713Sgirish 		if ((portmode == PORT_10G_FIBER) ||
10652e59129aSraghus 		    (portmode == PORT_10G_COPPER) ||
106600161856Syc 		    (portmode == PORT_10G_TN1010) ||
10671c7408c9Stc 		    (portmode == PORT_HSP_MODE) ||
10682e59129aSraghus 		    (portmode == PORT_10G_SERDES))
106944961713Sgirish 			xif_cfg |= CFG_XMAC_XIF_LFS;
107044961713Sgirish 
107100161856Syc 		/* Bypass PCS so that RGMII will be used */
107244961713Sgirish 		if (portmode == PORT_1G_COPPER) {
107344961713Sgirish 			xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS;
107444961713Sgirish 		}
107544961713Sgirish 
107644961713Sgirish 		/* Set MAC Internal Loopback if necessary */
107744961713Sgirish 		if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
107844961713Sgirish 			xif_cfg |= CFG_XMAC_XIF_LOOPBACK;
107944961713Sgirish 
108044961713Sgirish 		if (statsp->mac_stats.link_speed == 100)
108144961713Sgirish 			xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ;
108244961713Sgirish 
108344961713Sgirish 		xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT;
108444961713Sgirish 
10852e59129aSraghus 		if ((portmode == PORT_10G_FIBER) ||
108689282175SSantwona Behera 		    (portmode == PORT_10G_COPPER) ||
108700161856Syc 		    (portmode == PORT_10G_TN1010) ||
108800161856Syc 		    (portmode == PORT_1G_TN1010) ||
10891c7408c9Stc 		    (portmode == PORT_HSP_MODE) ||
10902e59129aSraghus 		    (portmode == PORT_10G_SERDES)) {
109100161856Syc 			/* Assume LED same for 1G and 10G */
109244961713Sgirish 			if (statsp->mac_stats.link_up) {
109344961713Sgirish 				xif_cfg |= CFG_XMAC_XIF_LED_POLARITY;
109444961713Sgirish 			} else {
109544961713Sgirish 				xif_cfg |= CFG_XMAC_XIF_LED_FORCE;
109644961713Sgirish 			}
109744961713Sgirish 		}
109844961713Sgirish 
109944961713Sgirish 		rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg);
110044961713Sgirish 		if (rs != NPI_SUCCESS)
110144961713Sgirish 			goto fail;
110244961713Sgirish 
110344961713Sgirish 		nxgep->mac.xif_config = xif_cfg;
110444961713Sgirish 
110544961713Sgirish 		/* Set Port Mode */
110644961713Sgirish 		if ((portmode == PORT_10G_FIBER) ||
11072e59129aSraghus 		    (portmode == PORT_10G_COPPER) ||
110800161856Syc 		    (portmode == PORT_10G_TN1010) ||
11091c7408c9Stc 		    (portmode == PORT_HSP_MODE) ||
11102e59129aSraghus 		    (portmode == PORT_10G_SERDES)) {
111144961713Sgirish 			SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
111252ccf843Smisaki 			    MAC_XGMII_MODE, rs);
111344961713Sgirish 			if (rs != NPI_SUCCESS)
111444961713Sgirish 				goto fail;
111544961713Sgirish 			if (statsp->mac_stats.link_up) {
111644961713Sgirish 				if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
111744961713Sgirish 					goto fail;
111844961713Sgirish 			} else {
111944961713Sgirish 				if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
112044961713Sgirish 					goto fail;
112144961713Sgirish 			}
112244961713Sgirish 		} else if ((portmode == PORT_1G_FIBER) ||
11232e59129aSraghus 		    (portmode == PORT_1G_COPPER) ||
1124d81011f0Ssbehera 		    (portmode == PORT_1G_SERDES) ||
112500161856Syc 		    (portmode == PORT_1G_TN1010) ||
1126d81011f0Ssbehera 		    (portmode == PORT_1G_RGMII_FIBER)) {
1127d81011f0Ssbehera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1128d81011f0Ssbehera 			    "nxge_xif_init: Port[%d] Mode[%d] Speed[%d]",
1129d81011f0Ssbehera 			    portn, portmode, statsp->mac_stats.link_speed));
113044961713Sgirish 			if (statsp->mac_stats.link_speed == 1000) {
113144961713Sgirish 				SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
113252ccf843Smisaki 				    MAC_GMII_MODE, rs);
113344961713Sgirish 			} else {
113444961713Sgirish 				SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
113552ccf843Smisaki 				    MAC_MII_MODE, rs);
113644961713Sgirish 			}
113744961713Sgirish 			if (rs != NPI_SUCCESS)
113844961713Sgirish 				goto fail;
113944961713Sgirish 		} else {
114044961713Sgirish 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
114152ccf843Smisaki 			    "nxge_xif_init: Unknown port mode (%d)"
114252ccf843Smisaki 			    " for port<%d>", portmode, portn));
114344961713Sgirish 			goto fail;
114444961713Sgirish 		}
114544961713Sgirish 
1146d81011f0Ssbehera 		/* Enable ATCA mode */
1147d81011f0Ssbehera 
114844961713Sgirish 	} else if (portt == PORT_TYPE_BMAC) {
114944961713Sgirish 
115044961713Sgirish 		/* Setup XIF Configuration for BMAC */
115144961713Sgirish 
1152d81011f0Ssbehera 		if ((portmode == PORT_1G_COPPER) ||
1153d81011f0Ssbehera 		    (portmode == PORT_1G_RGMII_FIBER)) {
115444961713Sgirish 			if (statsp->mac_stats.link_speed == 100)
115544961713Sgirish 				xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ;
115644961713Sgirish 		}
115744961713Sgirish 
115844961713Sgirish 		if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
115944961713Sgirish 			xif_cfg |= CFG_BMAC_XIF_LOOPBACK;
116044961713Sgirish 
116144961713Sgirish 		if (statsp->mac_stats.link_speed == 1000)
116244961713Sgirish 			xif_cfg |= CFG_BMAC_XIF_GMII_MODE;
116344961713Sgirish 
116444961713Sgirish 		xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT;
116544961713Sgirish 
116644961713Sgirish 		rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg);
116744961713Sgirish 		if (rs != NPI_SUCCESS)
116844961713Sgirish 			goto fail;
116944961713Sgirish 		nxgep->mac.xif_config = xif_cfg;
117044961713Sgirish 	}
117144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn));
117244961713Sgirish 	return (NXGE_OK);
117344961713Sgirish fail:
117444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
117552ccf843Smisaki 	    "nxge_xif_init: Failed to initialize XIF port<%d>", portn));
117644961713Sgirish 	return (NXGE_ERROR | rs);
117744961713Sgirish }
117844961713Sgirish 
117944961713Sgirish 
118000161856Syc /*
118100161856Syc  * Initialize the PCS sub-block in the MAC.  Note that PCS does not
118200161856Syc  * support loopback like XPCS.
118300161856Syc  */
118444961713Sgirish nxge_status_t
nxge_pcs_init(p_nxge_t nxgep)118544961713Sgirish nxge_pcs_init(p_nxge_t nxgep)
118644961713Sgirish {
118744961713Sgirish 	pcs_cfg_t		pcs_cfg;
118844961713Sgirish 	uint32_t		val;
118944961713Sgirish 	uint8_t			portn;
119044961713Sgirish 	nxge_port_mode_t	portmode;
119144961713Sgirish 	npi_handle_t		handle;
119244961713Sgirish 	p_nxge_stats_t		statsp;
119300161856Syc 	pcs_ctrl_t		pcs_ctrl;
119444961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
119500161856Syc 	uint8_t i;
119644961713Sgirish 
119744961713Sgirish 	handle = nxgep->npi_handle;
119844961713Sgirish 	portmode = nxgep->mac.portmode;
119944961713Sgirish 	portn = nxgep->mac.portnum;
120044961713Sgirish 	statsp = nxgep->statsp;
120144961713Sgirish 
120244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn));
120344961713Sgirish 
120400161856Syc 	if (portmode == PORT_1G_FIBER ||
120500161856Syc 	    portmode == PORT_1G_TN1010 ||
120600161856Syc 	    portmode == PORT_1G_SERDES) {
120700161856Syc 		if (portmode == PORT_1G_TN1010) {
120800161856Syc 			/* Reset PCS multiple time in PORT_1G_TN1010 mode */
120900161856Syc 			for (i = 0; i < 6; i ++) {
121000161856Syc 				if ((rs = npi_mac_pcs_reset(handle, portn))
121100161856Syc 				    != NPI_SUCCESS) {
121200161856Syc 					goto fail;
121300161856Syc 				}
121400161856Syc 			}
121500161856Syc 		} else {
121600161856Syc 			if ((rs = npi_mac_pcs_reset(handle, portn))
121700161856Syc 			    != NPI_SUCCESS)
121800161856Syc 				goto fail;
12192e59129aSraghus 		}
12202e59129aSraghus 
122144961713Sgirish 		/* Initialize port's PCS */
122244961713Sgirish 		pcs_cfg.value = 0;
122344961713Sgirish 		pcs_cfg.bits.w0.enable = 1;
122444961713Sgirish 		pcs_cfg.bits.w0.mask = 1;
122544961713Sgirish 		PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value);
122644961713Sgirish 		PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0);
122744961713Sgirish 
12282e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
12292e59129aSraghus 		    "==> nxge_pcs_init: (1G) port<%d> write config 0x%llx",
12302e59129aSraghus 		    portn, pcs_cfg.value));
123100161856Syc 
123200161856Syc 		if (portmode == PORT_1G_TN1010) {
123300161856Syc 			/*
123400161856Syc 			 * Must disable PCS auto-negotiation when the the driver
123500161856Syc 			 * is driving the TN1010 based XAUI card  Otherwise the
123600161856Syc 			 * autonegotiation between the PCS and the TN1010 PCS
123700161856Syc 			 * will never complete and the Neptune/NIU will not work
123800161856Syc 			 */
123900161856Syc 			pcs_ctrl.value = 0;
124000161856Syc 			PCS_REG_WR(handle, portn, PCS_MII_CTRL_REG,
124100161856Syc 			    pcs_ctrl.value);
124200161856Syc 		}
124300161856Syc 	} else if (portmode == PORT_10G_FIBER ||
124400161856Syc 	    portmode == PORT_10G_COPPER ||
124500161856Syc 	    portmode == PORT_10G_TN1010 ||
12461c7408c9Stc 	    portmode == PORT_HSP_MODE ||
124700161856Syc 	    portmode == PORT_10G_SERDES) {
124844961713Sgirish 		/* Use internal XPCS, bypass 1G PCS */
124944961713Sgirish 		XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val);
125044961713Sgirish 		val &= ~XMAC_XIF_XPCS_BYPASS;
125144961713Sgirish 		XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val);
125244961713Sgirish 
125344961713Sgirish 		if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS)
125444961713Sgirish 			goto fail;
125544961713Sgirish 
125644961713Sgirish 		/* Set XPCS Internal Loopback if necessary */
125744961713Sgirish 		if ((rs = npi_xmac_xpcs_read(handle, portn,
125852ccf843Smisaki 		    XPCS_REG_CONTROL1, &val)) != NPI_SUCCESS)
125944961713Sgirish 			goto fail;
126000161856Syc 
126144961713Sgirish 		if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) ||
126252ccf843Smisaki 		    (statsp->port_stats.lb_mode == nxge_lb_mac1000))
126344961713Sgirish 			val |= XPCS_CTRL1_LOOPBK;
126444961713Sgirish 		else
126544961713Sgirish 			val &= ~XPCS_CTRL1_LOOPBK;
126644961713Sgirish 		if ((rs = npi_xmac_xpcs_write(handle, portn,
126752ccf843Smisaki 		    XPCS_REG_CONTROL1, val)) != NPI_SUCCESS)
126844961713Sgirish 			goto fail;
126944961713Sgirish 
127044961713Sgirish 		/* Clear descw errors */
127144961713Sgirish 		if ((rs = npi_xmac_xpcs_write(handle, portn,
127252ccf843Smisaki 		    XPCS_REG_DESCWERR_COUNTER, 0)) != NPI_SUCCESS)
127344961713Sgirish 			goto fail;
127444961713Sgirish 		/* Clear symbol errors */
127544961713Sgirish 		if ((rs = npi_xmac_xpcs_read(handle, portn,
127652ccf843Smisaki 		    XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val)) != NPI_SUCCESS)
127744961713Sgirish 			goto fail;
127844961713Sgirish 		if ((rs = npi_xmac_xpcs_read(handle, portn,
127952ccf843Smisaki 		    XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val)) != NPI_SUCCESS)
128044961713Sgirish 			goto fail;
128144961713Sgirish 
1282d81011f0Ssbehera 	} else if ((portmode == PORT_1G_COPPER) ||
1283d81011f0Ssbehera 	    (portmode == PORT_1G_RGMII_FIBER)) {
1284d81011f0Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1285d81011f0Ssbehera 		    "==> nxge_pcs_init: (1G) copper port<%d>", portn));
128644961713Sgirish 		if (portn < 4) {
128744961713Sgirish 			PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG,
128852ccf843Smisaki 			    PCS_DATAPATH_MODE_MII);
128944961713Sgirish 		}
129044961713Sgirish 		if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS)
129144961713Sgirish 			goto fail;
129244961713Sgirish 
129344961713Sgirish 	} else {
129444961713Sgirish 		goto fail;
129544961713Sgirish 	}
129644961713Sgirish pass:
129744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn));
129844961713Sgirish 	return (NXGE_OK);
129944961713Sgirish fail:
130044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
130152ccf843Smisaki 	    "nxge_pcs_init: Failed to initialize PCS port<%d>", portn));
130244961713Sgirish 	return (NXGE_ERROR | rs);
130344961713Sgirish }
130444961713Sgirish 
1305cb9d3ae6Smisaki /*
1306cb9d3ae6Smisaki  * Initialize the MAC CTRL sub-block within the MAC
1307cb9d3ae6Smisaki  * Only the receive-pause-cap is supported.
1308cb9d3ae6Smisaki  */
1309cb9d3ae6Smisaki nxge_status_t
nxge_mac_ctrl_init(p_nxge_t nxgep)1310cb9d3ae6Smisaki nxge_mac_ctrl_init(p_nxge_t nxgep)
1311cb9d3ae6Smisaki {
1312cb9d3ae6Smisaki 	uint8_t			portn;
1313cb9d3ae6Smisaki 	nxge_port_t		portt;
1314cb9d3ae6Smisaki 	p_nxge_stats_t		statsp;
1315cb9d3ae6Smisaki 	npi_handle_t		handle;
1316cb9d3ae6Smisaki 	uint32_t		val;
1317cb9d3ae6Smisaki 
1318cb9d3ae6Smisaki 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
1319cb9d3ae6Smisaki 
1320cb9d3ae6Smisaki 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_ctrl_init: port<%d>",
1321cb9d3ae6Smisaki 	    portn));
1322cb9d3ae6Smisaki 
1323cb9d3ae6Smisaki 	handle = nxgep->npi_handle;
1324cb9d3ae6Smisaki 	portt = nxgep->mac.porttype;
1325cb9d3ae6Smisaki 	statsp = nxgep->statsp;
1326cb9d3ae6Smisaki 
1327cb9d3ae6Smisaki 	if (portt == PORT_TYPE_XMAC) {
132800161856Syc 		/* Reading the current XMAC Config Register for XMAC */
1329cb9d3ae6Smisaki 		XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val);
1330cb9d3ae6Smisaki 
1331cb9d3ae6Smisaki 		/*
1332cb9d3ae6Smisaki 		 * Setup XMAC Configuration for XMAC
1333cb9d3ae6Smisaki 		 * XMAC only supports receive-pause
1334cb9d3ae6Smisaki 		 */
1335cb9d3ae6Smisaki 		if (statsp->mac_stats.adv_cap_asmpause) {
1336cb9d3ae6Smisaki 			if (!statsp->mac_stats.adv_cap_pause) {
1337cb9d3ae6Smisaki 				/*
1338cb9d3ae6Smisaki 				 * If adv_cap_asmpause is 1 and adv_cap_pause
1339cb9d3ae6Smisaki 				 * is 0, enable receive pause.
1340cb9d3ae6Smisaki 				 */
1341cb9d3ae6Smisaki 				val |= XMAC_RX_CFG_RX_PAUSE_EN;
1342cb9d3ae6Smisaki 			} else {
1343cb9d3ae6Smisaki 				/*
1344cb9d3ae6Smisaki 				 * If adv_cap_asmpause is 1 and adv_cap_pause
1345cb9d3ae6Smisaki 				 * is 1, disable receive pause.  Send pause is
1346cb9d3ae6Smisaki 				 * not supported.
1347cb9d3ae6Smisaki 				 */
1348cb9d3ae6Smisaki 				val &= ~XMAC_RX_CFG_RX_PAUSE_EN;
1349cb9d3ae6Smisaki 			}
1350cb9d3ae6Smisaki 		} else {
13511bd6825cSml 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
13521bd6825cSml 			    "==> nxge_mac_ctrl_init: port<%d>: pause",
13531bd6825cSml 			    portn));
1354cb9d3ae6Smisaki 			if (statsp->mac_stats.adv_cap_pause) {
13551bd6825cSml 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
13561bd6825cSml 				    "==> nxge_mac_ctrl_init: port<%d>: "
13571bd6825cSml 				    "enable pause", portn));
1358cb9d3ae6Smisaki 				/*
1359cb9d3ae6Smisaki 				 * If adv_cap_asmpause is 0 and adv_cap_pause
1360cb9d3ae6Smisaki 				 * is 1, enable receive pause.
1361cb9d3ae6Smisaki 				 */
1362cb9d3ae6Smisaki 				val |= XMAC_RX_CFG_RX_PAUSE_EN;
1363cb9d3ae6Smisaki 			} else {
1364cb9d3ae6Smisaki 				/*
1365cb9d3ae6Smisaki 				 * If adv_cap_asmpause is 0 and adv_cap_pause
1366cb9d3ae6Smisaki 				 * is 0, disable receive pause. Send pause is
1367cb9d3ae6Smisaki 				 * not supported
1368cb9d3ae6Smisaki 				 */
13691bd6825cSml 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
13701bd6825cSml 				    "==> nxge_mac_ctrl_init: port<%d>: "
13711bd6825cSml 				    "disable pause", portn));
1372cb9d3ae6Smisaki 				val &= ~XMAC_RX_CFG_RX_PAUSE_EN;
1373cb9d3ae6Smisaki 			}
1374cb9d3ae6Smisaki 		}
1375cb9d3ae6Smisaki 		XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val);
1376cb9d3ae6Smisaki 	} else if (portt == PORT_TYPE_BMAC) {
137700161856Syc 		/* Reading the current MAC CTRL Config Register for BMAC */
1378cb9d3ae6Smisaki 		BMAC_REG_RD(handle, portn, MAC_CTRL_CONFIG_REG, &val);
1379cb9d3ae6Smisaki 
1380cb9d3ae6Smisaki 		/* Setup MAC CTRL Configuration for BMAC */
1381cb9d3ae6Smisaki 		if (statsp->mac_stats.adv_cap_asmpause) {
1382cb9d3ae6Smisaki 			if (statsp->mac_stats.adv_cap_pause) {
1383cb9d3ae6Smisaki 				/*
1384cb9d3ae6Smisaki 				 * If adv_cap_asmpause is 1 and adv_cap_pause
1385cb9d3ae6Smisaki 				 * is 1, disable receive pause. Send pause
1386cb9d3ae6Smisaki 				 * is not supported
1387cb9d3ae6Smisaki 				 */
1388cb9d3ae6Smisaki 				val &= ~MAC_CTRL_CFG_RECV_PAUSE_EN;
1389cb9d3ae6Smisaki 			} else {
1390cb9d3ae6Smisaki 				/*
1391cb9d3ae6Smisaki 				 * If adv_cap_asmpause is 1 and adv_cap_pause
1392cb9d3ae6Smisaki 				 * is 0, enable receive pause and disable
1393cb9d3ae6Smisaki 				 * send pause.
1394cb9d3ae6Smisaki 				 */
1395cb9d3ae6Smisaki 				val |= MAC_CTRL_CFG_RECV_PAUSE_EN;
1396cb9d3ae6Smisaki 				val &= ~MAC_CTRL_CFG_SEND_PAUSE_EN;
1397cb9d3ae6Smisaki 			}
1398cb9d3ae6Smisaki 		} else {
1399cb9d3ae6Smisaki 			if (statsp->mac_stats.adv_cap_pause) {
1400cb9d3ae6Smisaki 				/*
1401cb9d3ae6Smisaki 				 * If adv_cap_asmpause is 0 and adv_cap_pause
1402cb9d3ae6Smisaki 				 * is 1, enable receive pause. Send pause is
1403cb9d3ae6Smisaki 				 * not supported.
1404cb9d3ae6Smisaki 				 */
1405cb9d3ae6Smisaki 				val |= MAC_CTRL_CFG_RECV_PAUSE_EN;
1406cb9d3ae6Smisaki 			} else {
1407cb9d3ae6Smisaki 				/*
1408cb9d3ae6Smisaki 				 * If adv_cap_asmpause is 0 and adv_cap_pause
1409cb9d3ae6Smisaki 				 * is 0, pause capability is not available in
1410cb9d3ae6Smisaki 				 * either direction.
1411cb9d3ae6Smisaki 				 */
1412cb9d3ae6Smisaki 				val &= (~MAC_CTRL_CFG_SEND_PAUSE_EN &
141352ccf843Smisaki 				    ~MAC_CTRL_CFG_RECV_PAUSE_EN);
1414cb9d3ae6Smisaki 			}
1415cb9d3ae6Smisaki 		}
1416cb9d3ae6Smisaki 		BMAC_REG_WR(handle, portn, MAC_CTRL_CONFIG_REG, val);
1417cb9d3ae6Smisaki 	}
1418cb9d3ae6Smisaki 
1419cb9d3ae6Smisaki 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_ctrl_init: port<%d>",
1420cb9d3ae6Smisaki 	    portn));
1421cb9d3ae6Smisaki 
1422cb9d3ae6Smisaki 	return (NXGE_OK);
1423cb9d3ae6Smisaki }
1424cb9d3ae6Smisaki 
142544961713Sgirish /* Initialize the Internal Serdes */
142644961713Sgirish 
142744961713Sgirish nxge_status_t
nxge_serdes_init(p_nxge_t nxgep)142844961713Sgirish nxge_serdes_init(p_nxge_t nxgep)
142944961713Sgirish {
143044961713Sgirish 	p_nxge_stats_t		statsp;
143144961713Sgirish #ifdef	NXGE_DEBUG
143244961713Sgirish 	uint8_t			portn;
143344961713Sgirish #endif
143444961713Sgirish 	nxge_status_t		status = NXGE_OK;
143544961713Sgirish 
143644961713Sgirish #ifdef	NXGE_DEBUG
143744961713Sgirish 	portn = nxgep->mac.portnum;
143844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
143959ac0c16Sdavemq 	    "==> nxge_serdes_init port<%d>", portn));
144044961713Sgirish #endif
144144961713Sgirish 
144259ac0c16Sdavemq 	if (nxgep->xcvr.serdes_init) {
144359ac0c16Sdavemq 		statsp = nxgep->statsp;
144459ac0c16Sdavemq 		status = nxgep->xcvr.serdes_init(nxgep);
144559ac0c16Sdavemq 		if (status != NXGE_OK)
144644961713Sgirish 			goto fail;
144759ac0c16Sdavemq 		statsp->mac_stats.serdes_inits++;
144844961713Sgirish 	}
144944961713Sgirish 
145044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>",
145159ac0c16Sdavemq 	    portn));
145244961713Sgirish 
145344961713Sgirish 	return (NXGE_OK);
145444961713Sgirish 
145544961713Sgirish fail:
145644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
145759ac0c16Sdavemq 	    "nxge_serdes_init: Failed to initialize serdes for port<%d>",
145859ac0c16Sdavemq 	    portn));
145944961713Sgirish 
146044961713Sgirish 	return (status);
146144961713Sgirish }
146244961713Sgirish 
146344961713Sgirish /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */
146444961713Sgirish 
146559ac0c16Sdavemq static nxge_status_t
nxge_n2_serdes_init(p_nxge_t nxgep)146644961713Sgirish nxge_n2_serdes_init(p_nxge_t nxgep)
146744961713Sgirish {
146844961713Sgirish 	uint8_t portn;
146944961713Sgirish 	int chan;
147044961713Sgirish 	esr_ti_cfgpll_l_t pll_cfg_l;
14712e59129aSraghus 	esr_ti_cfgpll_l_t pll_sts_l;
147244961713Sgirish 	esr_ti_cfgrx_l_t rx_cfg_l;
147344961713Sgirish 	esr_ti_cfgrx_h_t rx_cfg_h;
147444961713Sgirish 	esr_ti_cfgtx_l_t tx_cfg_l;
147544961713Sgirish 	esr_ti_cfgtx_h_t tx_cfg_h;
14762e59129aSraghus #ifdef NXGE_DEBUG
14772e59129aSraghus 	esr_ti_testcfg_t cfg;
14782e59129aSraghus #endif
147944961713Sgirish 	esr_ti_testcfg_t test_cfg;
148044961713Sgirish 	nxge_status_t status = NXGE_OK;
148144961713Sgirish 
148244961713Sgirish 	portn = nxgep->mac.portnum;
148344961713Sgirish 
148444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>",
148552ccf843Smisaki 	    portn));
14864df55fdeSJanie Lu 	if (nxgep->niu_hw_type == NIU_HW_TYPE_RF) {
14874df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
14884df55fdeSJanie Lu 		    "==> nxge_n2_serdes_init port<%d>: KT-NIU", portn));
14894df55fdeSJanie Lu 		return (nxge_n2_kt_serdes_init(nxgep));
14904df55fdeSJanie Lu 	}
149144961713Sgirish 
149244961713Sgirish 	tx_cfg_l.value = 0;
149344961713Sgirish 	tx_cfg_h.value = 0;
149444961713Sgirish 	rx_cfg_l.value = 0;
149544961713Sgirish 	rx_cfg_h.value = 0;
149644961713Sgirish 	pll_cfg_l.value = 0;
14972e59129aSraghus 	pll_sts_l.value = 0;
149844961713Sgirish 	test_cfg.value = 0;
149944961713Sgirish 
150000161856Syc 	/*
150100161856Syc 	 * If the nxge driver has been plumbed without a link, then it will
150200161856Syc 	 * detect a link up when a cable connecting to an anto-negotiation
150300161856Syc 	 * partner is plugged into the port. Because the TN1010 PHY supports
150400161856Syc 	 * both 1G and 10G speeds, the driver must re-configure the
150500161856Syc 	 * Neptune/NIU according to the negotiated speed.  nxge_n2_serdes_init
150600161856Syc 	 * is called at the post-link-up reconfiguration time. Here it calls
150700161856Syc 	 * nxge_set_tn1010_param to set portmode before re-initializing
150800161856Syc 	 * the serdes.
150900161856Syc 	 */
151000161856Syc 	if (nxgep->mac.portmode == PORT_1G_TN1010 ||
151100161856Syc 	    nxgep->mac.portmode == PORT_10G_TN1010) {
151200161856Syc 		if (nxge_set_tn1010_param(nxgep) != NXGE_OK) {
151300161856Syc 			goto fail;
151400161856Syc 		}
151500161856Syc 	}
151600161856Syc 
151700161856Syc 	if (nxgep->mac.portmode == PORT_10G_FIBER ||
151889282175SSantwona Behera 	    nxgep->mac.portmode == PORT_10G_COPPER ||
151900161856Syc 	    nxgep->mac.portmode == PORT_10G_TN1010 ||
15201c7408c9Stc 	    nxgep->mac.portmode == PORT_HSP_MODE ||
152100161856Syc 	    nxgep->mac.portmode == PORT_10G_SERDES) {
152244961713Sgirish 		/* 0x0E01 */
152344961713Sgirish 		tx_cfg_l.bits.entx = 1;
152444961713Sgirish 		tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
152544961713Sgirish 
152644961713Sgirish 		/* 0x9101 */
152744961713Sgirish 		rx_cfg_l.bits.enrx = 1;
152844961713Sgirish 		rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
152944961713Sgirish 		rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
153044961713Sgirish 		rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
153144961713Sgirish 
153244961713Sgirish 		/* 0x0008 */
153344961713Sgirish 		rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
153444961713Sgirish 
153544961713Sgirish 		/* Set loopback mode if necessary */
153644961713Sgirish 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
153744961713Sgirish 			tx_cfg_l.bits.entest = 1;
153844961713Sgirish 			rx_cfg_l.bits.entest = 1;
153944961713Sgirish 			test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
154044961713Sgirish 			if ((status = nxge_mdio_write(nxgep, portn,
154152ccf843Smisaki 			    ESR_N2_DEV_ADDR,
154252ccf843Smisaki 			    ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK)
15434df3b64dSToomas Soome 				goto fail;
154444961713Sgirish 		}
154544961713Sgirish 
154600161856Syc 		/* Initialize PLL for 10G */
154700161856Syc 		pll_cfg_l.bits.mpy = CFGPLL_MPY_10X;
154800161856Syc 		pll_cfg_l.bits.enpll = 1;
154900161856Syc 		pll_sts_l.bits.enpll = 1;
155000161856Syc 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
155100161856Syc 		    ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK)
155200161856Syc 			goto fail;
155300161856Syc 
155400161856Syc 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
155500161856Syc 		    ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK)
155600161856Syc 			goto fail;
155744961713Sgirish 
155800161856Syc #ifdef  NXGE_DEBUG
155900161856Syc 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
156000161856Syc 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
156100161856Syc 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
156200161856Syc 		    "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
156300161856Syc 		    portn, pll_cfg_l.value, cfg.value));
156444961713Sgirish 
156500161856Syc 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
156600161856Syc 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
156700161856Syc 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
156800161856Syc 		    "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)",
156900161856Syc 		    portn, pll_sts_l.value, cfg.value));
157000161856Syc #endif
157100161856Syc 	} else if (nxgep->mac.portmode == PORT_1G_FIBER ||
157200161856Syc 	    nxgep->mac.portmode == PORT_1G_TN1010 ||
157300161856Syc 	    nxgep->mac.portmode == PORT_1G_SERDES) {
157444961713Sgirish 		/* 0x0E21 */
157544961713Sgirish 		tx_cfg_l.bits.entx = 1;
157644961713Sgirish 		tx_cfg_l.bits.rate = CFGTX_RATE_HALF;
157744961713Sgirish 		tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
157844961713Sgirish 
157944961713Sgirish 		/* 0x9121 */
158044961713Sgirish 		rx_cfg_l.bits.enrx = 1;
158144961713Sgirish 		rx_cfg_l.bits.rate = CFGRX_RATE_HALF;
158244961713Sgirish 		rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
158344961713Sgirish 		rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
158444961713Sgirish 		rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
158544961713Sgirish 
15862e59129aSraghus 		if (portn == 0) {
15872e59129aSraghus 			/* 0x8 */
15882e59129aSraghus 			rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
15892e59129aSraghus 		}
159044961713Sgirish 
159100161856Syc 		/* Initialize PLL for 1G */
159244961713Sgirish 		pll_cfg_l.bits.mpy = CFGPLL_MPY_8X;
159344961713Sgirish 		pll_cfg_l.bits.enpll = 1;
15942e59129aSraghus 		pll_sts_l.bits.enpll = 1;
159544961713Sgirish 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
159652ccf843Smisaki 		    ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK)
159744961713Sgirish 			goto fail;
15982e59129aSraghus 
15992e59129aSraghus 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
16002e59129aSraghus 		    ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK)
16012e59129aSraghus 			goto fail;
16022e59129aSraghus 
16032e59129aSraghus #ifdef  NXGE_DEBUG
16042e59129aSraghus 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
16052e59129aSraghus 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
16062e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16072e59129aSraghus 		    "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
16082e59129aSraghus 		    portn, pll_cfg_l.value, cfg.value));
16092e59129aSraghus 
16102e59129aSraghus 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
16112e59129aSraghus 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
16122e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16132e59129aSraghus 		    "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)",
16142e59129aSraghus 		    portn, pll_sts_l.value, cfg.value));
16152e59129aSraghus #endif
16162e59129aSraghus 
16172e59129aSraghus 		/* Set loopback mode if necessary */
16182e59129aSraghus 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
16192e59129aSraghus 			tx_cfg_l.bits.entest = 1;
16202e59129aSraghus 			rx_cfg_l.bits.entest = 1;
16212e59129aSraghus 			test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
16222e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16232e59129aSraghus 			    "==> nxge_n2_serdes_init port<%d>: loopback 0x%x",
16242e59129aSraghus 			    portn, test_cfg.value));
16252e59129aSraghus 			if ((status = nxge_mdio_write(nxgep, portn,
16262e59129aSraghus 			    ESR_N2_DEV_ADDR,
16272e59129aSraghus 			    ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) {
16282e59129aSraghus 				goto fail;
16292e59129aSraghus 			}
16302e59129aSraghus 		}
163144961713Sgirish 	} else {
163244961713Sgirish 		goto fail;
163344961713Sgirish 	}
163444961713Sgirish 
163544961713Sgirish 	/*   MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */
163644961713Sgirish 
163744961713Sgirish 	NXGE_DELAY(20);
163844961713Sgirish 
163944961713Sgirish 	/* init TX channels */
164044961713Sgirish 	for (chan = 0; chan < 4; chan++) {
164144961713Sgirish 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
164252ccf843Smisaki 		    ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) != NXGE_OK)
164344961713Sgirish 			goto fail;
164444961713Sgirish 
164544961713Sgirish 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
164652ccf843Smisaki 		    ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) != NXGE_OK)
164744961713Sgirish 			goto fail;
16482e59129aSraghus 
16492e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16502e59129aSraghus 		    "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_l 0x%x",
16512e59129aSraghus 		    portn, chan, tx_cfg_l.value));
16522e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16532e59129aSraghus 		    "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_h 0x%x",
16542e59129aSraghus 		    portn, chan, tx_cfg_h.value));
165544961713Sgirish 	}
165644961713Sgirish 
165744961713Sgirish 	/* init RX channels */
165844961713Sgirish 	for (chan = 0; chan < 4; chan++) {
165944961713Sgirish 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
166052ccf843Smisaki 		    ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value)) != NXGE_OK)
166144961713Sgirish 			goto fail;
166244961713Sgirish 
166344961713Sgirish 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
166452ccf843Smisaki 		    ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value)) != NXGE_OK)
166544961713Sgirish 			goto fail;
16662e59129aSraghus 
16672e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16682e59129aSraghus 		    "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_l 0x%x",
16692e59129aSraghus 		    portn, chan, rx_cfg_l.value));
167000161856Syc 
16712e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
16722e59129aSraghus 		    "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_h 0x%x",
16732e59129aSraghus 		    portn, chan, rx_cfg_h.value));
167444961713Sgirish 	}
167544961713Sgirish 
167644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>",
167752ccf843Smisaki 	    portn));
167844961713Sgirish 
167944961713Sgirish 	return (NXGE_OK);
168044961713Sgirish fail:
16812d17280bSsbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16822d17280bSsbehera 	    "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>",
16832d17280bSsbehera 	    portn));
168444961713Sgirish 
168544961713Sgirish 	return (status);
16864df55fdeSJanie Lu 
16874df55fdeSJanie Lu }
16884df55fdeSJanie Lu 
16894df55fdeSJanie Lu /* Initialize the TI Hedwig Internal Serdes (N2-KT-NIU only) */
16904df55fdeSJanie Lu 
16914df55fdeSJanie Lu static nxge_status_t
nxge_n2_kt_serdes_init(p_nxge_t nxgep)16924df55fdeSJanie Lu nxge_n2_kt_serdes_init(p_nxge_t nxgep)
16934df55fdeSJanie Lu {
16944df55fdeSJanie Lu 	uint8_t portn;
169589282175SSantwona Behera 	int chan, i;
16964df55fdeSJanie Lu 	k_esr_ti_cfgpll_l_t pll_cfg_l;
16974df55fdeSJanie Lu 	k_esr_ti_cfgrx_l_t rx_cfg_l;
16984df55fdeSJanie Lu 	k_esr_ti_cfgrx_h_t rx_cfg_h;
16994df55fdeSJanie Lu 	k_esr_ti_cfgtx_l_t tx_cfg_l;
17004df55fdeSJanie Lu 	k_esr_ti_cfgtx_h_t tx_cfg_h;
17014df55fdeSJanie Lu #ifdef NXGE_DEBUG
17024df55fdeSJanie Lu 	k_esr_ti_testcfg_t cfg;
17034df55fdeSJanie Lu #endif
17044df55fdeSJanie Lu 	k_esr_ti_testcfg_t test_cfg;
17054df55fdeSJanie Lu 	nxge_status_t status = NXGE_OK;
17064df55fdeSJanie Lu 	boolean_t mode_1g = B_FALSE;
170789282175SSantwona Behera 	uint64_t val;
170889282175SSantwona Behera 	npi_handle_t handle;
17094df55fdeSJanie Lu 
17104df55fdeSJanie Lu 	portn = nxgep->mac.portnum;
17114df55fdeSJanie Lu 
17124df55fdeSJanie Lu 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
17134df55fdeSJanie Lu 	    "==> nxge_n2_kt_serdes_init port<%d>", portn));
171489282175SSantwona Behera 	handle = nxgep->npi_handle;
17154df55fdeSJanie Lu 
17164df55fdeSJanie Lu 	tx_cfg_l.value = 0;
17174df55fdeSJanie Lu 	tx_cfg_h.value = 0;
17184df55fdeSJanie Lu 	rx_cfg_l.value = 0;
17194df55fdeSJanie Lu 	rx_cfg_h.value = 0;
17204df55fdeSJanie Lu 	pll_cfg_l.value = 0;
17214df55fdeSJanie Lu 	test_cfg.value = 0;
17224df55fdeSJanie Lu 
17234df55fdeSJanie Lu 	/*
17244df55fdeSJanie Lu 	 * The following setting assumes the reference clock frquency
17254df55fdeSJanie Lu 	 * is 156.25 MHz.
17264df55fdeSJanie Lu 	 */
17274df55fdeSJanie Lu 	/*
17284df55fdeSJanie Lu 	 * If the nxge driver has been plumbed without a link, then it will
17294df55fdeSJanie Lu 	 * detect a link up when a cable connecting to an anto-negotiation
17304df55fdeSJanie Lu 	 * partner is plugged into the port. Because the TN1010 PHY supports
17314df55fdeSJanie Lu 	 * both 1G and 10G speeds, the driver must re-configure the
17324df55fdeSJanie Lu 	 * Neptune/NIU according to the negotiated speed.  nxge_n2_serdes_init
17334df55fdeSJanie Lu 	 * is called at the post-link-up reconfiguration time. Here it calls
17344df55fdeSJanie Lu 	 * nxge_set_tn1010_param to set portmode before re-initializing
17354df55fdeSJanie Lu 	 * the serdes.
17364df55fdeSJanie Lu 	 */
17374df55fdeSJanie Lu 	if (nxgep->mac.portmode == PORT_1G_TN1010 ||
17384df55fdeSJanie Lu 	    nxgep->mac.portmode == PORT_10G_TN1010) {
17394df55fdeSJanie Lu 		if (nxge_set_tn1010_param(nxgep) != NXGE_OK) {
17404df55fdeSJanie Lu 			goto fail;
17414df55fdeSJanie Lu 		}
17424df55fdeSJanie Lu 	}
17434df55fdeSJanie Lu 	if (nxgep->mac.portmode == PORT_10G_FIBER ||
174489282175SSantwona Behera 	    nxgep->mac.portmode == PORT_10G_COPPER ||
17454df55fdeSJanie Lu 	    nxgep->mac.portmode == PORT_10G_TN1010 ||
17464df55fdeSJanie Lu 	    nxgep->mac.portmode == PORT_10G_SERDES) {
17479d587972SSantwona Behera 
17489d587972SSantwona Behera 		/* Take tunables from OBP if present, otherwise use defaults */
17499d587972SSantwona Behera 		if (nxgep->srds_prop.prop_set & NXGE_SRDS_TXCFGL) {
17509d587972SSantwona Behera 			tx_cfg_l.value = nxgep->srds_prop.tx_cfg_l;
17519d587972SSantwona Behera 		} else {
17529d587972SSantwona Behera 			tx_cfg_l.bits.entx = K_CFGTX_ENABLE_TX;
17539d587972SSantwona Behera 			/* 0x1e21 */
17549d587972SSantwona Behera 			tx_cfg_l.bits.swing = K_CFGTX_SWING_2000MV;
17559d587972SSantwona Behera 			tx_cfg_l.bits.rate = K_CFGTX_RATE_HALF;
17569d587972SSantwona Behera 		}
17574df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
17584df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_l 0x%x",
17594df55fdeSJanie Lu 		    portn, tx_cfg_l.value));
17604df55fdeSJanie Lu 
17619d587972SSantwona Behera 		if (nxgep->srds_prop.prop_set & NXGE_SRDS_TXCFGH) {
17629d587972SSantwona Behera 			tx_cfg_h.value = nxgep->srds_prop.tx_cfg_h;
17639d587972SSantwona Behera 		} else {
17649d587972SSantwona Behera 			/* channel 0: enable syn. master */
17659d587972SSantwona Behera 			/* 0x40 */
17669d587972SSantwona Behera 			tx_cfg_h.bits.msync = K_CFGTX_ENABLE_MSYNC;
17679d587972SSantwona Behera 		}
17684df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
17694df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x",
17704df55fdeSJanie Lu 		    portn, tx_cfg_h.value));
17719d587972SSantwona Behera 
17729d587972SSantwona Behera 		if (nxgep->srds_prop.prop_set & NXGE_SRDS_RXCFGL) {
17739d587972SSantwona Behera 			rx_cfg_l.value = nxgep->srds_prop.rx_cfg_l;
17749d587972SSantwona Behera 		} else {
17759d587972SSantwona Behera 			/* 0x4821 */
17769d587972SSantwona Behera 			rx_cfg_l.bits.enrx = K_CFGRX_ENABLE_RX;
17779d587972SSantwona Behera 			rx_cfg_l.bits.rate = K_CFGRX_RATE_HALF;
17789d587972SSantwona Behera 			rx_cfg_l.bits.align = K_CFGRX_ALIGN_EN;
17799d587972SSantwona Behera 			rx_cfg_l.bits.los = K_CFGRX_LOS_ENABLE;
17809d587972SSantwona Behera 		}
17814df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
17824df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_l 0x%x",
17834df55fdeSJanie Lu 		    portn, rx_cfg_l.value));
17844df55fdeSJanie Lu 
17859d587972SSantwona Behera 		if (nxgep->srds_prop.prop_set & NXGE_SRDS_RXCFGH) {
17869d587972SSantwona Behera 			rx_cfg_h.value = nxgep->srds_prop.rx_cfg_h;
17879d587972SSantwona Behera 		} else {
17889d587972SSantwona Behera 			/* 0x0008 */
17899d587972SSantwona Behera 			rx_cfg_h.bits.eq = K_CFGRX_EQ_ADAPTIVE;
17909d587972SSantwona Behera 		}
17914df55fdeSJanie Lu 
17924df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
17934df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_h 0x%x",
17944df55fdeSJanie Lu 		    portn, rx_cfg_h.value));
17954df55fdeSJanie Lu 
17969d587972SSantwona Behera 		if (nxgep->srds_prop.prop_set & NXGE_SRDS_PLLCFGL) {
17979d587972SSantwona Behera 			pll_cfg_l.value = nxgep->srds_prop.pll_cfg_l;
17989d587972SSantwona Behera 		} else {
17999d587972SSantwona Behera 			/* 0xa1: Initialize PLL for 10G */
18009d587972SSantwona Behera 			pll_cfg_l.bits.mpy = K_CFGPLL_MPY_20X;
18019d587972SSantwona Behera 			pll_cfg_l.bits.enpll = K_CFGPLL_ENABLE_PLL;
18024df55fdeSJanie Lu 		}
18034df55fdeSJanie Lu 
18044df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
18054df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x",
18064df55fdeSJanie Lu 		    portn, pll_cfg_l.value));
18074df55fdeSJanie Lu 
18084df55fdeSJanie Lu 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
18094df55fdeSJanie Lu 		    ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK)
18104df55fdeSJanie Lu 			goto fail;
18114df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
18124df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x",
18134df55fdeSJanie Lu 		    portn, pll_cfg_l.value));
18149d587972SSantwona Behera 
18159d587972SSantwona Behera 		/* Set loopback mode if necessary */
18169d587972SSantwona Behera 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
18179d587972SSantwona Behera 			tx_cfg_h.bits.loopback = K_CFGTX_INNER_CML_ENA_LOOPBACK;
18189d587972SSantwona Behera 			rx_cfg_h.bits.loopback = K_CFGTX_INNER_CML_ENA_LOOPBACK;
18199d587972SSantwona Behera 			rx_cfg_l.bits.los = 0;
18209d587972SSantwona Behera 
18219d587972SSantwona Behera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
18229d587972SSantwona Behera 			    "==> nxge_n2_kt_serdes_init port<%d>: "
18239d587972SSantwona Behera 			    "loopback 0x%x", portn, tx_cfg_h.value));
18249d587972SSantwona Behera 		}
18254df55fdeSJanie Lu #ifdef  NXGE_DEBUG
18264df55fdeSJanie Lu 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
18274df55fdeSJanie Lu 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
18284df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18294df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d>: "
18304df55fdeSJanie Lu 		    "PLL cfg.l 0x%x (0x%x)",
18314df55fdeSJanie Lu 		    portn, pll_cfg_l.value, cfg.value));
18324df55fdeSJanie Lu 
18334df55fdeSJanie Lu 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
18344df55fdeSJanie Lu 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
18354df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18364df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d>: (0x%x)",
18374df55fdeSJanie Lu 		    portn, cfg.value));
18384df55fdeSJanie Lu #endif
18394df55fdeSJanie Lu 	} else if (nxgep->mac.portmode == PORT_1G_FIBER ||
18404df55fdeSJanie Lu 	    nxgep->mac.portmode == PORT_1G_TN1010 ||
18414df55fdeSJanie Lu 	    nxgep->mac.portmode == PORT_1G_SERDES) {
18424df55fdeSJanie Lu 		mode_1g = B_TRUE;
18434df55fdeSJanie Lu 		/* 0x1e41 */
18444df55fdeSJanie Lu 		tx_cfg_l.bits.entx = 1;
18454df55fdeSJanie Lu 		tx_cfg_l.bits.rate = K_CFGTX_RATE_HALF;
18464df55fdeSJanie Lu 		tx_cfg_l.bits.swing = K_CFGTX_SWING_2000MV;
18474df55fdeSJanie Lu 
18484df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
18494df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_l 0x%x",
18504df55fdeSJanie Lu 		    portn, tx_cfg_l.value));
18514df55fdeSJanie Lu 
18524df55fdeSJanie Lu 
18534df55fdeSJanie Lu 		/* channel 0: enable syn. master */
18544df55fdeSJanie Lu 		tx_cfg_h.bits.msync = K_CFGTX_ENABLE_MSYNC;
18554df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
18564df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x",
18574df55fdeSJanie Lu 		    portn, tx_cfg_h.value));
18584df55fdeSJanie Lu 
18594df55fdeSJanie Lu 
18604df55fdeSJanie Lu 		/* 0x4841 */
18614df55fdeSJanie Lu 		rx_cfg_l.bits.enrx = 1;
18624df55fdeSJanie Lu 		rx_cfg_l.bits.rate = K_CFGRX_RATE_HALF;
18634df55fdeSJanie Lu 		rx_cfg_l.bits.align = K_CFGRX_ALIGN_EN;
18644df55fdeSJanie Lu 		rx_cfg_l.bits.los = K_CFGRX_LOS_ENABLE;
18654df55fdeSJanie Lu 
18664df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
18674df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_l 0x%x",
18684df55fdeSJanie Lu 		    portn, rx_cfg_l.value));
18694df55fdeSJanie Lu 
18704df55fdeSJanie Lu 		/* 0x0008 */
18714df55fdeSJanie Lu 		rx_cfg_h.bits.eq = K_CFGRX_EQ_ADAPTIVE_LF_365MHZ_ZF;
18724df55fdeSJanie Lu 
18734df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
18744df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x",
18754df55fdeSJanie Lu 		    portn, rx_cfg_h.value));
18764df55fdeSJanie Lu 
18774df55fdeSJanie Lu 		/* 0xa1: Initialize PLL for 1G */
18784df55fdeSJanie Lu 		pll_cfg_l.bits.mpy = K_CFGPLL_MPY_20X;
18794df55fdeSJanie Lu 		pll_cfg_l.bits.enpll = K_CFGPLL_ENABLE_PLL;
18804df55fdeSJanie Lu 
18814df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
18824df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x",
18834df55fdeSJanie Lu 		    portn, pll_cfg_l.value));
18844df55fdeSJanie Lu 
18854df55fdeSJanie Lu 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
18864df55fdeSJanie Lu 		    ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value))
18874df55fdeSJanie Lu 		    != NXGE_OK)
18884df55fdeSJanie Lu 			goto fail;
18894df55fdeSJanie Lu 
18904df55fdeSJanie Lu 
18914df55fdeSJanie Lu #ifdef  NXGE_DEBUG
18924df55fdeSJanie Lu 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
18934df55fdeSJanie Lu 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
18944df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18954df55fdeSJanie Lu 		    "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
18964df55fdeSJanie Lu 		    portn, pll_cfg_l.value, cfg.value));
18974df55fdeSJanie Lu 
18984df55fdeSJanie Lu 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
18994df55fdeSJanie Lu 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
19004df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19014df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d>: (0x%x)",
19024df55fdeSJanie Lu 		    portn, cfg.value));
19034df55fdeSJanie Lu #endif
19044df55fdeSJanie Lu 
19054df55fdeSJanie Lu 		/* Set loopback mode if necessary */
19064df55fdeSJanie Lu 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
19074df55fdeSJanie Lu 			tx_cfg_h.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
19084df55fdeSJanie Lu 
19094df55fdeSJanie Lu 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
19104df55fdeSJanie Lu 			    "==> nxge_n2_kt_serdes_init port<%d>: "
19114df55fdeSJanie Lu 			    "loopback 0x%x", portn, test_cfg.value));
19124df55fdeSJanie Lu 			if ((status = nxge_mdio_write(nxgep, portn,
19134df55fdeSJanie Lu 			    ESR_N2_DEV_ADDR,
19144df55fdeSJanie Lu 			    ESR_N2_TX_CFG_L_REG_ADDR(0),
19154df55fdeSJanie Lu 			    tx_cfg_h.value)) != NXGE_OK) {
19164df55fdeSJanie Lu 				goto fail;
19174df55fdeSJanie Lu 			}
19184df55fdeSJanie Lu 		}
19194df55fdeSJanie Lu 	} else {
19204df55fdeSJanie Lu 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19214df55fdeSJanie Lu 		    "nxge_n2_kt_serdes_init:port<%d> - "
19224df55fdeSJanie Lu 		    "unsupported port mode %d",
19234df55fdeSJanie Lu 		    portn, nxgep->mac.portmode));
19244df55fdeSJanie Lu 		goto fail;
19254df55fdeSJanie Lu 	}
19264df55fdeSJanie Lu 
19274df55fdeSJanie Lu 	NXGE_DELAY(20);
19284df55fdeSJanie Lu 	/* Clear the test register (offset 0x8004) */
19294df55fdeSJanie Lu 	if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
19304df55fdeSJanie Lu 	    ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) {
19314df55fdeSJanie Lu 		goto fail;
19324df55fdeSJanie Lu 	}
19334df55fdeSJanie Lu 	NXGE_DELAY(20);
19344df55fdeSJanie Lu 
19354df55fdeSJanie Lu 	/* init TX channels */
19364df55fdeSJanie Lu 	for (chan = 0; chan < 4; chan++) {
19374df55fdeSJanie Lu 		if (mode_1g)
19384df55fdeSJanie Lu 			tx_cfg_l.value = 0;
19394df55fdeSJanie Lu 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
19404df55fdeSJanie Lu 		    ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) != NXGE_OK)
19414df55fdeSJanie Lu 			goto fail;
19424df55fdeSJanie Lu 
19434df55fdeSJanie Lu 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
19444df55fdeSJanie Lu 		    ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) != NXGE_OK)
19454df55fdeSJanie Lu 			goto fail;
19464df55fdeSJanie Lu 
19474df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
19484df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d>: "
19494df55fdeSJanie Lu 		    "chan %d tx_cfg_l 0x%x", portn, chan, tx_cfg_l.value));
19504df55fdeSJanie Lu 
19514df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
19524df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d>: "
19534df55fdeSJanie Lu 		    "chan %d tx_cfg_h 0x%x", portn, chan, tx_cfg_h.value));
19544df55fdeSJanie Lu 	}
19554df55fdeSJanie Lu 
19564df55fdeSJanie Lu 	/* init RX channels */
19574df55fdeSJanie Lu 	/* 1G mode only write to the first channel */
19584df55fdeSJanie Lu 	for (chan = 0; chan < 4; chan++) {
19594df55fdeSJanie Lu 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
19604df55fdeSJanie Lu 		    ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value))
19614df55fdeSJanie Lu 		    != NXGE_OK)
19624df55fdeSJanie Lu 			goto fail;
19634df55fdeSJanie Lu 
19644df55fdeSJanie Lu 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
19654df55fdeSJanie Lu 		    ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value))
19664df55fdeSJanie Lu 		    != NXGE_OK)
19674df55fdeSJanie Lu 			goto fail;
19684df55fdeSJanie Lu 
19694df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
19704df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d>: "
19714df55fdeSJanie Lu 		    "chan %d rx_cfg_l 0x%x", portn, chan, rx_cfg_l.value));
19724df55fdeSJanie Lu 
19734df55fdeSJanie Lu 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
19744df55fdeSJanie Lu 		    "==> nxge_n2_kt_serdes_init port<%d>: "
19754df55fdeSJanie Lu 		    "chan %d rx_cfg_h 0x%x", portn, chan, rx_cfg_h.value));
19764df55fdeSJanie Lu 	}
19774df55fdeSJanie Lu 
197889282175SSantwona Behera 	if (portn == 0) {
197989282175SSantwona Behera 		/* Wait for serdes to be ready */
198089282175SSantwona Behera 		for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) {
198189282175SSantwona Behera 			ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
198289282175SSantwona Behera 			if ((val & ESR_SIG_P0_BITS_MASK) !=
198389282175SSantwona Behera 			    (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 |
198489282175SSantwona Behera 			    ESR_SIG_XSERDES_RDY_P0 |
198589282175SSantwona Behera 			    ESR_SIG_XDETECT_P0_CH3 |
198689282175SSantwona Behera 			    ESR_SIG_XDETECT_P0_CH2 |
198789282175SSantwona Behera 			    ESR_SIG_XDETECT_P0_CH1 |
198889282175SSantwona Behera 			    ESR_SIG_XDETECT_P0_CH0))
198989282175SSantwona Behera 
199089282175SSantwona Behera 				NXGE_DELAY(SERDES_RDY_WT_INTERVAL);
199189282175SSantwona Behera 			else
199289282175SSantwona Behera 				break;
199389282175SSantwona Behera 		}
199489282175SSantwona Behera 
199589282175SSantwona Behera 		if (i == MAX_SERDES_RDY_RETRIES) {
199689282175SSantwona Behera 			/*
199789282175SSantwona Behera 			 * RDY signal stays low may due to the absent of the
199889282175SSantwona Behera 			 * external PHY, it is not an error condition.
199989282175SSantwona Behera 			 * But still print the message for the debugging
200089282175SSantwona Behera 			 * purpose when link stays down
200189282175SSantwona Behera 			 */
200289282175SSantwona Behera 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
200389282175SSantwona Behera 			    "nxge_n2_kt_serdes_init: "
200489282175SSantwona Behera 			    "Serdes/signal for port<%d> not ready", portn));
20054df3b64dSToomas Soome 			goto done;
200689282175SSantwona Behera 		}
200789282175SSantwona Behera 	} else if (portn == 1) {
200889282175SSantwona Behera 		/* Wait for serdes to be ready */
200989282175SSantwona Behera 		for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) {
201089282175SSantwona Behera 			ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
201189282175SSantwona Behera 			if ((val & ESR_SIG_P1_BITS_MASK) !=
201289282175SSantwona Behera 			    (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 |
201389282175SSantwona Behera 			    ESR_SIG_XSERDES_RDY_P1 |
201489282175SSantwona Behera 			    ESR_SIG_XDETECT_P1_CH3 |
201589282175SSantwona Behera 			    ESR_SIG_XDETECT_P1_CH2 |
201689282175SSantwona Behera 			    ESR_SIG_XDETECT_P1_CH1 |
201789282175SSantwona Behera 			    ESR_SIG_XDETECT_P1_CH0))
201889282175SSantwona Behera 
201989282175SSantwona Behera 				NXGE_DELAY(SERDES_RDY_WT_INTERVAL);
202089282175SSantwona Behera 			else
202189282175SSantwona Behera 				break;
202289282175SSantwona Behera 		}
202389282175SSantwona Behera 
202489282175SSantwona Behera 		if (i == MAX_SERDES_RDY_RETRIES) {
202589282175SSantwona Behera 			/*
202689282175SSantwona Behera 			 * RDY signal stays low may due to the absent of the
202789282175SSantwona Behera 			 * external PHY, it is not an error condition.
202889282175SSantwona Behera 			 * But still print the message for the debugging
202989282175SSantwona Behera 			 * purpose when link stays down
203089282175SSantwona Behera 			 */
203189282175SSantwona Behera 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
203289282175SSantwona Behera 			    "nxge_n2_kt_serdes_init: "
203389282175SSantwona Behera 			    "Serdes/signal for port<%d> not ready", portn));
20344df3b64dSToomas Soome 			goto done;
203589282175SSantwona Behera 		}
203689282175SSantwona Behera 	}
203789282175SSantwona Behera done:
203889282175SSantwona Behera 
20394df55fdeSJanie Lu 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
20404df55fdeSJanie Lu 	    "<== nxge_n2_kt_serdes_init port<%d>", portn));
20414df55fdeSJanie Lu 
20424df55fdeSJanie Lu 	return (NXGE_OK);
20434df55fdeSJanie Lu fail:
20444df55fdeSJanie Lu 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
20454df55fdeSJanie Lu 	    "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>",
20464df55fdeSJanie Lu 	    portn));
20474df55fdeSJanie Lu 
20484df55fdeSJanie Lu 	return (status);
204944961713Sgirish }
205044961713Sgirish 
205159ac0c16Sdavemq /* Initialize the Neptune Internal Serdes for 10G (Neptune only) */
205244961713Sgirish 
205359ac0c16Sdavemq static nxge_status_t
nxge_neptune_10G_serdes_init(p_nxge_t nxgep)205459ac0c16Sdavemq nxge_neptune_10G_serdes_init(p_nxge_t nxgep)
205544961713Sgirish {
205644961713Sgirish 	npi_handle_t		handle;
205744961713Sgirish 	uint8_t			portn;
2058321febdeSsbehera 	int			chan, i;
205944961713Sgirish 	sr_rx_tx_ctrl_l_t	rx_tx_ctrl_l;
206044961713Sgirish 	sr_rx_tx_ctrl_h_t	rx_tx_ctrl_h;
206144961713Sgirish 	sr_glue_ctrl0_l_t	glue_ctrl0_l;
206244961713Sgirish 	sr_glue_ctrl0_h_t	glue_ctrl0_h;
206344961713Sgirish 	uint64_t		val;
206444961713Sgirish 	uint16_t		val16l;
206544961713Sgirish 	uint16_t		val16h;
206644961713Sgirish 	nxge_status_t		status = NXGE_OK;
206744961713Sgirish 
206844961713Sgirish 	portn = nxgep->mac.portnum;
206944961713Sgirish 
207044961713Sgirish 	if ((portn != 0) && (portn != 1))
207144961713Sgirish 		return (NXGE_OK);
207244961713Sgirish 
207359ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
207459ac0c16Sdavemq 	    "==> nxge_neptune_10G_serdes_init port<%d>", portn));
207544961713Sgirish 	handle = nxgep->npi_handle;
207659ac0c16Sdavemq 	switch (portn) {
207759ac0c16Sdavemq 	case 0:
20784202ea4bSsbehera 		/* Reset Serdes */
20794202ea4bSsbehera 		ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0);
20804202ea4bSsbehera 		NXGE_DELAY(20);
20814202ea4bSsbehera 		ESR_REG_WR(handle, ESR_RESET_REG, 0x0);
20824202ea4bSsbehera 		NXGE_DELAY(2000);
20834202ea4bSsbehera 
20844202ea4bSsbehera 		/* Configure Serdes to 10G mode */
20854202ea4bSsbehera 		ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG,
20864202ea4bSsbehera 		    ESR_PLL_CFG_10G_SERDES);
20874202ea4bSsbehera 
208859ac0c16Sdavemq 		ESR_REG_WR(handle, ESR_0_CONTROL_REG,
208959ac0c16Sdavemq 		    ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
209059ac0c16Sdavemq 		    ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
209159ac0c16Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
209259ac0c16Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
209359ac0c16Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
209459ac0c16Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
209559ac0c16Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
209659ac0c16Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
209759ac0c16Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
209859ac0c16Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
209959ac0c16Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
210059ac0c16Sdavemq 
210159ac0c16Sdavemq 		/* Set Serdes0 Internal Loopback if necessary */
210259ac0c16Sdavemq 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
210359ac0c16Sdavemq 			ESR_REG_WR(handle,
210459ac0c16Sdavemq 			    ESR_0_TEST_CONFIG_REG,
210559ac0c16Sdavemq 			    ESR_PAD_LOOPBACK_CH3 |
210659ac0c16Sdavemq 			    ESR_PAD_LOOPBACK_CH2 |
210759ac0c16Sdavemq 			    ESR_PAD_LOOPBACK_CH1 |
210859ac0c16Sdavemq 			    ESR_PAD_LOOPBACK_CH0);
210959ac0c16Sdavemq 		} else {
211059ac0c16Sdavemq 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0);
211144961713Sgirish 		}
211259ac0c16Sdavemq 		break;
211359ac0c16Sdavemq 	case 1:
21144202ea4bSsbehera 		/* Reset Serdes */
21154202ea4bSsbehera 		ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_1);
21164202ea4bSsbehera 		NXGE_DELAY(20);
21174202ea4bSsbehera 		ESR_REG_WR(handle, ESR_RESET_REG, 0x0);
21184202ea4bSsbehera 		NXGE_DELAY(2000);
21194202ea4bSsbehera 
21204202ea4bSsbehera 		/* Configure Serdes to 10G mode */
21214202ea4bSsbehera 		ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG,
21224202ea4bSsbehera 		    ESR_PLL_CFG_10G_SERDES);
21234202ea4bSsbehera 
212459ac0c16Sdavemq 		ESR_REG_WR(handle, ESR_1_CONTROL_REG,
212559ac0c16Sdavemq 		    ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
212659ac0c16Sdavemq 		    ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
212759ac0c16Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
212859ac0c16Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
212959ac0c16Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
213059ac0c16Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
213159ac0c16Sdavemq 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
213259ac0c16Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
213359ac0c16Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
213459ac0c16Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
213559ac0c16Sdavemq 		    (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
213659ac0c16Sdavemq 
213759ac0c16Sdavemq 		/* Set Serdes1 Internal Loopback if necessary */
213859ac0c16Sdavemq 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
213959ac0c16Sdavemq 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG,
214059ac0c16Sdavemq 			    ESR_PAD_LOOPBACK_CH3 | ESR_PAD_LOOPBACK_CH2 |
214159ac0c16Sdavemq 			    ESR_PAD_LOOPBACK_CH1 | ESR_PAD_LOOPBACK_CH0);
214259ac0c16Sdavemq 		} else {
214359ac0c16Sdavemq 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0);
214444961713Sgirish 		}
214559ac0c16Sdavemq 		break;
214659ac0c16Sdavemq 	default:
214759ac0c16Sdavemq 		/* Nothing to do here */
214859ac0c16Sdavemq 		goto done;
214959ac0c16Sdavemq 	}
215044961713Sgirish 
215159ac0c16Sdavemq 	/* init TX RX channels */
215259ac0c16Sdavemq 	for (chan = 0; chan < 4; chan++) {
215359ac0c16Sdavemq 		if ((status = nxge_mdio_read(nxgep, portn,
215459ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
215559ac0c16Sdavemq 		    &rx_tx_ctrl_l.value)) != NXGE_OK)
215644961713Sgirish 			goto fail;
215759ac0c16Sdavemq 		if ((status = nxge_mdio_read(nxgep, portn,
215859ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
215959ac0c16Sdavemq 		    &rx_tx_ctrl_h.value)) != NXGE_OK)
216044961713Sgirish 			goto fail;
216159ac0c16Sdavemq 		if ((status = nxge_mdio_read(nxgep, portn,
216259ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
216359ac0c16Sdavemq 		    &glue_ctrl0_l.value)) != NXGE_OK)
216459ac0c16Sdavemq 			goto fail;
216559ac0c16Sdavemq 		if ((status = nxge_mdio_read(nxgep, portn,
216659ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
216759ac0c16Sdavemq 		    &glue_ctrl0_h.value)) != NXGE_OK)
216859ac0c16Sdavemq 			goto fail;
216959ac0c16Sdavemq 		rx_tx_ctrl_l.bits.enstretch = 1;
217059ac0c16Sdavemq 		rx_tx_ctrl_h.bits.vmuxlo = 2;
217159ac0c16Sdavemq 		rx_tx_ctrl_h.bits.vpulselo = 2;
217259ac0c16Sdavemq 		glue_ctrl0_l.bits.rxlosenable = 1;
217359ac0c16Sdavemq 		glue_ctrl0_l.bits.samplerate = 0xF;
217459ac0c16Sdavemq 		glue_ctrl0_l.bits.thresholdcount = 0xFF;
217559ac0c16Sdavemq 		glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
217644961713Sgirish 		if ((status = nxge_mdio_write(nxgep, portn,
217759ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
217859ac0c16Sdavemq 		    rx_tx_ctrl_l.value)) != NXGE_OK)
217944961713Sgirish 			goto fail;
218044961713Sgirish 		if ((status = nxge_mdio_write(nxgep, portn,
218159ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
218259ac0c16Sdavemq 		    rx_tx_ctrl_h.value)) != NXGE_OK)
218344961713Sgirish 			goto fail;
218459ac0c16Sdavemq 		if ((status = nxge_mdio_write(nxgep, portn,
218559ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
218659ac0c16Sdavemq 		    glue_ctrl0_l.value)) != NXGE_OK)
218744961713Sgirish 			goto fail;
218859ac0c16Sdavemq 		if ((status = nxge_mdio_write(nxgep, portn,
218959ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
219059ac0c16Sdavemq 		    glue_ctrl0_h.value)) != NXGE_OK)
219144961713Sgirish 			goto fail;
219244961713Sgirish 		}
219344961713Sgirish 
219459ac0c16Sdavemq 	/* Apply Tx core reset */
219559ac0c16Sdavemq 	if ((status = nxge_mdio_write(nxgep, portn,
219659ac0c16Sdavemq 	    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
219759ac0c16Sdavemq 	    (uint16_t)0)) != NXGE_OK)
219859ac0c16Sdavemq 		goto fail;
219959ac0c16Sdavemq 
220059ac0c16Sdavemq 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
220159ac0c16Sdavemq 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) !=
220259ac0c16Sdavemq 	    NXGE_OK)
220359ac0c16Sdavemq 		goto fail;
220459ac0c16Sdavemq 
220559ac0c16Sdavemq 	NXGE_DELAY(200);
220659ac0c16Sdavemq 
220759ac0c16Sdavemq 	/* Apply Rx core reset */
220859ac0c16Sdavemq 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
220959ac0c16Sdavemq 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) !=
221059ac0c16Sdavemq 	    NXGE_OK)
221159ac0c16Sdavemq 		goto fail;
221259ac0c16Sdavemq 
221359ac0c16Sdavemq 	NXGE_DELAY(200);
221459ac0c16Sdavemq 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
221559ac0c16Sdavemq 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK)
221659ac0c16Sdavemq 		goto fail;
221759ac0c16Sdavemq 
221859ac0c16Sdavemq 	NXGE_DELAY(200);
221959ac0c16Sdavemq 	if ((status = nxge_mdio_read(nxgep, portn,
222059ac0c16Sdavemq 	    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
222159ac0c16Sdavemq 	    &val16l)) != NXGE_OK)
222259ac0c16Sdavemq 		goto fail;
222359ac0c16Sdavemq 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
222459ac0c16Sdavemq 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK)
222559ac0c16Sdavemq 		goto fail;
222659ac0c16Sdavemq 	if ((val16l != 0) || (val16h != 0)) {
222759ac0c16Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2228d81011f0Ssbehera 		    "Failed to reset port<%d> XAUI Serdes "
2229d81011f0Ssbehera 		    "(val16l 0x%x val16h 0x%x)",
2230d81011f0Ssbehera 		    portn, val16l, val16h));
223159ac0c16Sdavemq 	}
223259ac0c16Sdavemq 
223359ac0c16Sdavemq 	if (portn == 0) {
2234321febdeSsbehera 		/* Wait for serdes to be ready */
2235321febdeSsbehera 		for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) {
2236321febdeSsbehera 			ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
2237321febdeSsbehera 			if ((val & ESR_SIG_P0_BITS_MASK) !=
2238321febdeSsbehera 			    (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 |
2239321febdeSsbehera 			    ESR_SIG_XSERDES_RDY_P0 |
2240321febdeSsbehera 			    ESR_SIG_XDETECT_P0_CH3 |
2241321febdeSsbehera 			    ESR_SIG_XDETECT_P0_CH2 |
2242321febdeSsbehera 			    ESR_SIG_XDETECT_P0_CH1 |
2243321febdeSsbehera 			    ESR_SIG_XDETECT_P0_CH0))
2244321febdeSsbehera 
2245321febdeSsbehera 				NXGE_DELAY(SERDES_RDY_WT_INTERVAL);
2246321febdeSsbehera 			else
2247321febdeSsbehera 				break;
2248321febdeSsbehera 		}
2249321febdeSsbehera 
2250321febdeSsbehera 		if (i == MAX_SERDES_RDY_RETRIES) {
2251ab6abb7aSjoycey 			/*
2252ab6abb7aSjoycey 			 * RDY signal stays low may due to the absent of the
2253ab6abb7aSjoycey 			 * external PHY, it is not an error condition. But still
2254ab6abb7aSjoycey 			 * print the message for the debugging purpose when link
2255ab6abb7aSjoycey 			 * stays down
2256ab6abb7aSjoycey 			 */
2257774da109Stc 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2258321febdeSsbehera 			    "nxge_neptune_10G_serdes_init: "
2259321febdeSsbehera 			    "Serdes/signal for port<%d> not ready", portn));
226000161856Syc 				goto done;
226159ac0c16Sdavemq 		}
226259ac0c16Sdavemq 	} else if (portn == 1) {
2263321febdeSsbehera 		/* Wait for serdes to be ready */
2264321febdeSsbehera 		for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) {
2265321febdeSsbehera 			ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
2266321febdeSsbehera 			if ((val & ESR_SIG_P1_BITS_MASK) !=
2267321febdeSsbehera 			    (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 |
2268321febdeSsbehera 			    ESR_SIG_XSERDES_RDY_P1 |
2269321febdeSsbehera 			    ESR_SIG_XDETECT_P1_CH3 |
2270321febdeSsbehera 			    ESR_SIG_XDETECT_P1_CH2 |
2271321febdeSsbehera 			    ESR_SIG_XDETECT_P1_CH1 |
2272321febdeSsbehera 			    ESR_SIG_XDETECT_P1_CH0))
2273321febdeSsbehera 
2274321febdeSsbehera 				NXGE_DELAY(SERDES_RDY_WT_INTERVAL);
2275321febdeSsbehera 			else
2276321febdeSsbehera 				break;
2277321febdeSsbehera 		}
2278321febdeSsbehera 
2279321febdeSsbehera 		if (i == MAX_SERDES_RDY_RETRIES) {
2280ab6abb7aSjoycey 			/*
2281ab6abb7aSjoycey 			 * RDY signal stays low may due to the absent of the
2282ab6abb7aSjoycey 			 * external PHY, it is not an error condition. But still
2283ab6abb7aSjoycey 			 * print the message for the debugging purpose when link
2284ab6abb7aSjoycey 			 * stays down
2285ab6abb7aSjoycey 			 */
2286774da109Stc 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2287321febdeSsbehera 			    "nxge_neptune_10G_serdes_init: "
2288321febdeSsbehera 			    "Serdes/signal for port<%d> not ready", portn));
228900161856Syc 				goto done;
229044961713Sgirish 		}
229144961713Sgirish 	}
229244961713Sgirish 
229344961713Sgirish done:
229459ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
229559ac0c16Sdavemq 	    "<== nxge_neptune_10G_serdes_init port<%d>", portn));
229659ac0c16Sdavemq 
229744961713Sgirish 	return (NXGE_OK);
229844961713Sgirish fail:
22992d17280bSsbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
230059ac0c16Sdavemq 	    "nxge_neptune_10G_serdes_init: "
230159ac0c16Sdavemq 	    "Failed to initialize Neptune serdes for port<%d>", portn));
230244961713Sgirish 
230344961713Sgirish 	return (status);
230444961713Sgirish }
230544961713Sgirish 
230659ac0c16Sdavemq /* Initialize Neptune Internal Serdes for 1G (Neptune only) */
230744961713Sgirish 
230859ac0c16Sdavemq static nxge_status_t
nxge_1G_serdes_init(p_nxge_t nxgep)230959ac0c16Sdavemq nxge_1G_serdes_init(p_nxge_t nxgep)
231044961713Sgirish {
231159ac0c16Sdavemq 	npi_handle_t		handle;
231259ac0c16Sdavemq 	uint8_t			portn;
2313d81011f0Ssbehera 	int			chan;
2314d81011f0Ssbehera 	sr_rx_tx_ctrl_l_t	rx_tx_ctrl_l;
2315d81011f0Ssbehera 	sr_rx_tx_ctrl_h_t	rx_tx_ctrl_h;
2316d81011f0Ssbehera 	sr_glue_ctrl0_l_t	glue_ctrl0_l;
2317d81011f0Ssbehera 	sr_glue_ctrl0_h_t	glue_ctrl0_h;
231859ac0c16Sdavemq 	uint64_t		val;
2319d81011f0Ssbehera 	uint16_t		val16l;
2320d81011f0Ssbehera 	uint16_t		val16h;
2321d81011f0Ssbehera 	nxge_status_t		status = NXGE_OK;
232244961713Sgirish 
232344961713Sgirish 	portn = nxgep->mac.portnum;
232444961713Sgirish 
232559ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
232659ac0c16Sdavemq 	    "==> nxge_1G_serdes_init port<%d>", portn));
232744961713Sgirish 
232859ac0c16Sdavemq 	handle = nxgep->npi_handle;
232944961713Sgirish 
233059ac0c16Sdavemq 	switch (portn) {
233159ac0c16Sdavemq 	case 0:
2332d81011f0Ssbehera 		/* Assert the reset register */
2333d81011f0Ssbehera 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
2334d81011f0Ssbehera 		val |= ESR_RESET_0;
2335d81011f0Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, val);
2336d81011f0Ssbehera 
2337d81011f0Ssbehera 		/* Set the PLL register to 0x79 */
2338d81011f0Ssbehera 		ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG,
2339d81011f0Ssbehera 		    ESR_PLL_CFG_1G_SERDES);
2340d81011f0Ssbehera 
2341d81011f0Ssbehera 		/* Set the control register to 0x249249f */
2342d81011f0Ssbehera 		ESR_REG_WR(handle, ESR_0_CONTROL_REG, ESR_CTL_1G_SERDES);
2343d81011f0Ssbehera 
2344d81011f0Ssbehera 		/* Set Serdes0 Internal Loopback if necessary */
2345d81011f0Ssbehera 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
2346d81011f0Ssbehera 			/* Set pad loopback modes 0xaa */
2347d81011f0Ssbehera 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG,
2348d81011f0Ssbehera 			    ESR_TSTCFG_LBTEST_PAD);
2349d81011f0Ssbehera 		} else {
2350d81011f0Ssbehera 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0);
2351d81011f0Ssbehera 		}
2352d81011f0Ssbehera 
2353d81011f0Ssbehera 		/* Deassert the reset register */
2354d81011f0Ssbehera 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
2355d81011f0Ssbehera 		val &= ~ESR_RESET_0;
2356d81011f0Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, val);
235759ac0c16Sdavemq 		break;
2358d81011f0Ssbehera 
235959ac0c16Sdavemq 	case 1:
2360d81011f0Ssbehera 		/* Assert the reset register */
2361d81011f0Ssbehera 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
2362d81011f0Ssbehera 		val |= ESR_RESET_1;
2363d81011f0Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, val);
2364d81011f0Ssbehera 
2365d81011f0Ssbehera 		/* Set PLL register to 0x79 */
2366d81011f0Ssbehera 		ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG,
2367d81011f0Ssbehera 		    ESR_PLL_CFG_1G_SERDES);
2368d81011f0Ssbehera 
2369d81011f0Ssbehera 		/* Set the control register to 0x249249f */
2370d81011f0Ssbehera 		ESR_REG_WR(handle, ESR_1_CONTROL_REG, ESR_CTL_1G_SERDES);
2371d81011f0Ssbehera 
2372d81011f0Ssbehera 		/* Set Serdes1 Internal Loopback if necessary */
2373d81011f0Ssbehera 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
2374d81011f0Ssbehera 			/* Set pad loopback mode 0xaa */
2375d81011f0Ssbehera 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG,
2376d81011f0Ssbehera 			    ESR_TSTCFG_LBTEST_PAD);
2377d81011f0Ssbehera 		} else {
2378d81011f0Ssbehera 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0);
2379d81011f0Ssbehera 		}
2380d81011f0Ssbehera 
2381d81011f0Ssbehera 		/* Deassert the reset register */
2382d81011f0Ssbehera 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
2383d81011f0Ssbehera 		val &= ~ESR_RESET_1;
2384d81011f0Ssbehera 		ESR_REG_WR(handle, ESR_RESET_REG, val);
238559ac0c16Sdavemq 		break;
2386d81011f0Ssbehera 
238759ac0c16Sdavemq 	default:
2388d81011f0Ssbehera 		/* Nothing to do here */
2389d81011f0Ssbehera 		goto done;
2390d81011f0Ssbehera 	}
2391d81011f0Ssbehera 
2392d81011f0Ssbehera 	/* init TX RX channels */
2393d81011f0Ssbehera 	for (chan = 0; chan < 4; chan++) {
2394d81011f0Ssbehera 		if ((status = nxge_mdio_read(nxgep, portn,
2395d81011f0Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
2396d81011f0Ssbehera 		    &rx_tx_ctrl_l.value)) != NXGE_OK) {
2397d81011f0Ssbehera 			goto fail;
2398d81011f0Ssbehera 		}
2399d81011f0Ssbehera 		if ((status = nxge_mdio_read(nxgep, portn,
2400d81011f0Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
2401d81011f0Ssbehera 		    &rx_tx_ctrl_h.value)) != NXGE_OK) {
2402d81011f0Ssbehera 			goto fail;
2403d81011f0Ssbehera 		}
2404d81011f0Ssbehera 		if ((status = nxge_mdio_read(nxgep, portn,
2405d81011f0Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
2406d81011f0Ssbehera 		    &glue_ctrl0_l.value)) != NXGE_OK) {
2407d81011f0Ssbehera 			goto fail;
2408d81011f0Ssbehera 		}
2409d81011f0Ssbehera 		if ((status = nxge_mdio_read(nxgep, portn,
2410d81011f0Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
2411d81011f0Ssbehera 		    &glue_ctrl0_h.value)) != NXGE_OK) {
2412d81011f0Ssbehera 			goto fail;
2413d81011f0Ssbehera 		}
2414d81011f0Ssbehera 
2415d81011f0Ssbehera 		rx_tx_ctrl_l.bits.enstretch = 1;
2416d81011f0Ssbehera 		rx_tx_ctrl_h.bits.vmuxlo = 2;
2417d81011f0Ssbehera 		rx_tx_ctrl_h.bits.vpulselo = 2;
2418d81011f0Ssbehera 		glue_ctrl0_l.bits.rxlosenable = 1;
2419d81011f0Ssbehera 		glue_ctrl0_l.bits.samplerate = 0xF;
2420d81011f0Ssbehera 		glue_ctrl0_l.bits.thresholdcount = 0xFF;
2421d81011f0Ssbehera 		glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
2422d81011f0Ssbehera 		if ((status = nxge_mdio_write(nxgep, portn,
2423d81011f0Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
2424d81011f0Ssbehera 		    rx_tx_ctrl_l.value)) != NXGE_OK) {
2425d81011f0Ssbehera 			goto fail;
2426d81011f0Ssbehera 		}
2427d81011f0Ssbehera 		if ((status = nxge_mdio_write(nxgep, portn,
2428d81011f0Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
2429d81011f0Ssbehera 		    rx_tx_ctrl_h.value)) != NXGE_OK) {
2430d81011f0Ssbehera 			goto fail;
2431d81011f0Ssbehera 		}
2432d81011f0Ssbehera 		if ((status = nxge_mdio_write(nxgep, portn,
2433d81011f0Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
2434d81011f0Ssbehera 		    glue_ctrl0_l.value)) != NXGE_OK) {
2435d81011f0Ssbehera 			goto fail;
2436d81011f0Ssbehera 		}
2437d81011f0Ssbehera 		if ((status = nxge_mdio_write(nxgep, portn,
2438d81011f0Ssbehera 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
2439d81011f0Ssbehera 		    glue_ctrl0_h.value)) != NXGE_OK) {
2440d81011f0Ssbehera 			goto fail;
2441d81011f0Ssbehera 		}
2442d81011f0Ssbehera 	}
2443d81011f0Ssbehera 
2444d81011f0Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
2445d81011f0Ssbehera 	    ESR_NEP_RX_POWER_CONTROL_L_ADDR(), 0xfff)) != NXGE_OK) {
2446d81011f0Ssbehera 		goto fail;
2447d81011f0Ssbehera 	}
2448d81011f0Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
2449d81011f0Ssbehera 	    ESR_NEP_RX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) {
2450d81011f0Ssbehera 		goto fail;
2451d81011f0Ssbehera 	}
2452d81011f0Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
2453d81011f0Ssbehera 	    ESR_NEP_TX_POWER_CONTROL_L_ADDR(), 0x70)) != NXGE_OK) {
2454d81011f0Ssbehera 		goto fail;
2455d81011f0Ssbehera 	}
2456d81011f0Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
2457d81011f0Ssbehera 	    ESR_NEP_TX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) {
245859ac0c16Sdavemq 		goto fail;
245944961713Sgirish 	}
246044961713Sgirish 
2461d81011f0Ssbehera 	/* Apply Tx core reset */
2462d81011f0Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
2463d81011f0Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0)) != NXGE_OK) {
2464d81011f0Ssbehera 		goto fail;
2465d81011f0Ssbehera 	}
2466d81011f0Ssbehera 
2467d81011f0Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
2468d81011f0Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) !=
2469d81011f0Ssbehera 	    NXGE_OK) {
2470d81011f0Ssbehera 		goto fail;
2471d81011f0Ssbehera 	}
2472d81011f0Ssbehera 
2473d81011f0Ssbehera 	NXGE_DELAY(200);
2474d81011f0Ssbehera 
2475d81011f0Ssbehera 	/* Apply Rx core reset */
2476d81011f0Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
2477d81011f0Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) !=
2478d81011f0Ssbehera 	    NXGE_OK) {
2479d81011f0Ssbehera 		goto fail;
2480d81011f0Ssbehera 	}
2481d81011f0Ssbehera 
2482d81011f0Ssbehera 	NXGE_DELAY(200);
2483d81011f0Ssbehera 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
2484d81011f0Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) {
2485d81011f0Ssbehera 		goto fail;
2486d81011f0Ssbehera 	}
2487d81011f0Ssbehera 
2488d81011f0Ssbehera 	NXGE_DELAY(200);
2489d81011f0Ssbehera 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
2490d81011f0Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), &val16l)) != NXGE_OK) {
2491d81011f0Ssbehera 		goto fail;
2492d81011f0Ssbehera 	}
2493d81011f0Ssbehera 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
2494d81011f0Ssbehera 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) {
2495d81011f0Ssbehera 		goto fail;
2496d81011f0Ssbehera 	}
2497d81011f0Ssbehera 	if ((val16l != 0) || (val16h != 0)) {
2498d81011f0Ssbehera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2499d81011f0Ssbehera 		    "Failed to reset port<%d> XAUI Serdes "
2500d81011f0Ssbehera 		    "(val16l 0x%x val16h 0x%x)", portn, val16l, val16h));
2501d81011f0Ssbehera 		status = NXGE_ERROR;
2502d81011f0Ssbehera 		goto fail;
2503d81011f0Ssbehera 	}
2504d81011f0Ssbehera 
2505d81011f0Ssbehera 	NXGE_DELAY(200);
2506d81011f0Ssbehera 	ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
2507d81011f0Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2508d81011f0Ssbehera 	    "nxge_neptune_serdes_init: read internal signal reg port<%d> "
2509d81011f0Ssbehera 	    "val 0x%x", portn, val));
2510d81011f0Ssbehera 	if (portn == 0) {
2511d81011f0Ssbehera 		if ((val & ESR_SIG_P0_BITS_MASK_1G) !=
2512d81011f0Ssbehera 		    (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0)) {
2513ab6abb7aSjoycey 			/*
2514ab6abb7aSjoycey 			 * RDY signal stays low may due to the absent of the
2515ab6abb7aSjoycey 			 * external PHY, it is not an error condition. But still
2516ab6abb7aSjoycey 			 * print the message for the debugging purpose when link
2517ab6abb7aSjoycey 			 * stays down
2518ab6abb7aSjoycey 			 */
2519d81011f0Ssbehera 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2520ab6abb7aSjoycey 			    "nxge_neptune_1G_serdes_init: "
2521ab6abb7aSjoycey 			    "Serdes/signal for port<%d> not ready", portn));
25224df3b64dSToomas Soome 			goto done;
2523d81011f0Ssbehera 		}
2524d81011f0Ssbehera 	} else if (portn == 1) {
2525d81011f0Ssbehera 		if ((val & ESR_SIG_P1_BITS_MASK_1G) !=
2526d81011f0Ssbehera 		    (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1)) {
2527ab6abb7aSjoycey 			/*
2528ab6abb7aSjoycey 			 * RDY signal stays low may due to the absent of the
2529ab6abb7aSjoycey 			 * external PHY, it is not an error condition. But still
2530ab6abb7aSjoycey 			 * print the message for the debugging purpose when link
2531ab6abb7aSjoycey 			 * stays down
2532ab6abb7aSjoycey 			 */
2533d81011f0Ssbehera 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2534ab6abb7aSjoycey 			    "nxge_neptune_1G_serdes_init: "
2535ab6abb7aSjoycey 			    "Serdes/signal for port<%d> not ready", portn));
25364df3b64dSToomas Soome 			goto done;
253700161856Syc 
2538d81011f0Ssbehera 		}
2539d81011f0Ssbehera 	}
2540d81011f0Ssbehera done:
254159ac0c16Sdavemq 
254259ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
254359ac0c16Sdavemq 	    "<== nxge_1G_serdes_init port<%d>", portn));
254444961713Sgirish 	return (NXGE_OK);
254559ac0c16Sdavemq fail:
2546d81011f0Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
254759ac0c16Sdavemq 	    "nxge_1G_serdes_init: "
254859ac0c16Sdavemq 	    "Failed to initialize Neptune serdes for port<%d>",
254959ac0c16Sdavemq 	    portn));
255059ac0c16Sdavemq 
2551d81011f0Ssbehera 	return (status);
255244961713Sgirish }
255344961713Sgirish 
25549d587972SSantwona Behera #define	NXGE_SET_PHY_TUNABLES(nxgep, phy_port, stat)			\
25559d587972SSantwona Behera {									\
25569d587972SSantwona Behera 	int i;								\
25579d587972SSantwona Behera 									\
25589d587972SSantwona Behera 	if (nxgep->phy_prop.cnt > 0) {					\
25599d587972SSantwona Behera 		for (i = 0; i < nxgep->phy_prop.cnt; i++) {		\
25609d587972SSantwona Behera 			if ((stat = nxge_mdio_write(nxgep, phy_port,	\
25619d587972SSantwona Behera 			    nxgep->phy_prop.arr[i].dev,			\
25629d587972SSantwona Behera 			    nxgep->phy_prop.arr[i].reg,			\
25639d587972SSantwona Behera 			    nxgep->phy_prop.arr[i].val)) != NXGE_OK) {	\
25649d587972SSantwona Behera 				break;					\
25659d587972SSantwona Behera 			}						\
25669d587972SSantwona Behera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,			\
25679d587972SSantwona Behera 			    "From OBP, write<dev.reg.val> = "		\
25689d587972SSantwona Behera 			    "<0x%x.0x%x.0x%x>",				\
25699d587972SSantwona Behera 			    nxgep->phy_prop.arr[i].dev,			\
25709d587972SSantwona Behera 			    nxgep->phy_prop.arr[i].reg,			\
25719d587972SSantwona Behera 			    nxgep->phy_prop.arr[i].val));		\
25729d587972SSantwona Behera 		}							\
25739d587972SSantwona Behera 	}								\
25749d587972SSantwona Behera }
25759d587972SSantwona Behera 
25762d17280bSsbehera /* Initialize the BCM 8704 xcvr */
257744961713Sgirish 
257859ac0c16Sdavemq static nxge_status_t
nxge_BCM8704_xcvr_init(p_nxge_t nxgep)25792d17280bSsbehera nxge_BCM8704_xcvr_init(p_nxge_t nxgep)
258044961713Sgirish {
258144961713Sgirish 	uint16_t		val;
258244961713Sgirish #ifdef	NXGE_DEBUG
258314ea4bb7Ssd 	uint8_t			portn;
258444961713Sgirish 	uint16_t		val1;
258544961713Sgirish #endif
258644961713Sgirish 	uint8_t			phy_port_addr;
258744961713Sgirish 	pmd_tx_control_t	tx_ctl;
258844961713Sgirish 	control_t		ctl;
258944961713Sgirish 	phyxs_control_t		phyxs_ctl;
259044961713Sgirish 	pcs_control_t		pcs_ctl;
259144961713Sgirish 	uint32_t		delay = 0;
259244961713Sgirish 	optics_dcntr_t		op_ctr;
259344961713Sgirish 	nxge_status_t		status = NXGE_OK;
259414ea4bb7Ssd #ifdef	NXGE_DEBUG
259544961713Sgirish 	portn = nxgep->mac.portnum;
259614ea4bb7Ssd #endif
25979d587972SSantwona Behera 
25982d17280bSsbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>",
259959ac0c16Sdavemq 	    portn));
260044961713Sgirish 
260159ac0c16Sdavemq 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
260259ac0c16Sdavemq 
260359ac0c16Sdavemq 	/* Reset the transceiver */
260459ac0c16Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
260559ac0c16Sdavemq 	    BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK)
260659ac0c16Sdavemq 		goto fail;
260759ac0c16Sdavemq 
260859ac0c16Sdavemq 	phyxs_ctl.bits.reset = 1;
260959ac0c16Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
261059ac0c16Sdavemq 	    BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK)
261159ac0c16Sdavemq 		goto fail;
261259ac0c16Sdavemq 
261359ac0c16Sdavemq 	do {
261459ac0c16Sdavemq 		drv_usecwait(500);
261559ac0c16Sdavemq 		if ((status = nxge_mdio_read(nxgep, phy_port_addr,
261659ac0c16Sdavemq 		    BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG,
261759ac0c16Sdavemq 		    &phyxs_ctl.value)) != NXGE_OK)
261859ac0c16Sdavemq 			goto fail;
261959ac0c16Sdavemq 		delay++;
262059ac0c16Sdavemq 	} while ((phyxs_ctl.bits.reset) && (delay < 100));
262159ac0c16Sdavemq 	if (delay == 100) {
262259ac0c16Sdavemq 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
262359ac0c16Sdavemq 		    "failed to reset Transceiver on port<%d>", portn));
262459ac0c16Sdavemq 		status = NXGE_ERROR;
262559ac0c16Sdavemq 		goto fail;
262659ac0c16Sdavemq 	}
262744961713Sgirish 
262859ac0c16Sdavemq 	/* Set to 0x7FBF */
262959ac0c16Sdavemq 	ctl.value = 0;
263059ac0c16Sdavemq 	ctl.bits.res1 = 0x3F;
263159ac0c16Sdavemq 	ctl.bits.optxon_lvl = 1;
263259ac0c16Sdavemq 	ctl.bits.oprxflt_lvl = 1;
263359ac0c16Sdavemq 	ctl.bits.optrxlos_lvl = 1;
263459ac0c16Sdavemq 	ctl.bits.optxflt_lvl = 1;
263559ac0c16Sdavemq 	ctl.bits.opprflt_lvl = 1;
263659ac0c16Sdavemq 	ctl.bits.obtmpflt_lvl = 1;
263759ac0c16Sdavemq 	ctl.bits.opbiasflt_lvl = 1;
263859ac0c16Sdavemq 	ctl.bits.optxrst_lvl = 1;
263959ac0c16Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
264059ac0c16Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, ctl.value))
264159ac0c16Sdavemq 	    != NXGE_OK)
264259ac0c16Sdavemq 		goto fail;
264359ac0c16Sdavemq 
264459ac0c16Sdavemq 	/* Set to 0x164 */
264559ac0c16Sdavemq 	tx_ctl.value = 0;
264659ac0c16Sdavemq 	tx_ctl.bits.tsck_lpwren = 1;
264759ac0c16Sdavemq 	tx_ctl.bits.tx_dac_txck = 0x2;
264859ac0c16Sdavemq 	tx_ctl.bits.tx_dac_txd = 0x1;
264959ac0c16Sdavemq 	tx_ctl.bits.xfp_clken = 1;
265059ac0c16Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
265159ac0c16Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG,
265259ac0c16Sdavemq 	    tx_ctl.value)) != NXGE_OK)
265359ac0c16Sdavemq 		goto fail;
265444961713Sgirish 	/*
265559ac0c16Sdavemq 	 * According to Broadcom's instruction, SW needs to read
265659ac0c16Sdavemq 	 * back these registers twice after written.
265744961713Sgirish 	 */
265859ac0c16Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
265959ac0c16Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
266059ac0c16Sdavemq 	    != NXGE_OK)
266159ac0c16Sdavemq 		goto fail;
266244961713Sgirish 
266359ac0c16Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
266459ac0c16Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
266559ac0c16Sdavemq 	    != NXGE_OK)
266659ac0c16Sdavemq 		goto fail;
266744961713Sgirish 
266859ac0c16Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
266959ac0c16Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
267059ac0c16Sdavemq 	    != NXGE_OK)
267159ac0c16Sdavemq 		goto fail;
267244961713Sgirish 
267359ac0c16Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
267459ac0c16Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
267559ac0c16Sdavemq 	    != NXGE_OK)
267659ac0c16Sdavemq 		goto fail;
267744961713Sgirish 
267859ac0c16Sdavemq 	/* Enable Tx and Rx LEDs to be driven by traffic */
267959ac0c16Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
268059ac0c16Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
268159ac0c16Sdavemq 	    &op_ctr.value)) != NXGE_OK)
268259ac0c16Sdavemq 		goto fail;
2683cb9d3ae6Smisaki 	if (NXGE_IS_XAUI_PLATFORM(nxgep)) {
2684cb9d3ae6Smisaki 		op_ctr.bits.gpio_sel = 0x1;
2685cb9d3ae6Smisaki 	} else {
2686cb9d3ae6Smisaki 		op_ctr.bits.gpio_sel = 0x3;
2687cb9d3ae6Smisaki 	}
268859ac0c16Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
268959ac0c16Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
269059ac0c16Sdavemq 	    op_ctr.value)) != NXGE_OK)
269159ac0c16Sdavemq 		goto fail;
269244961713Sgirish 
269359ac0c16Sdavemq 	NXGE_DELAY(1000000);
269444961713Sgirish 
26959d587972SSantwona Behera 	/*
26969d587972SSantwona Behera 	 * Set XAUI link tunables from OBP if present.
26979d587972SSantwona Behera 	 */
26989d587972SSantwona Behera 	NXGE_SET_PHY_TUNABLES(nxgep, phy_port_addr, status);
26999d587972SSantwona Behera 	if (status != NXGE_OK) {
27009d587972SSantwona Behera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27019d587972SSantwona Behera 		    "nxge_BCM8704_xcvr_init: Failed setting PHY tunables"));
27029d587972SSantwona Behera 		goto fail;
27039d587972SSantwona Behera 	}
27049d587972SSantwona Behera 
270559ac0c16Sdavemq 	/* Set BCM8704 Internal Loopback mode if necessary */
270659ac0c16Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
270759ac0c16Sdavemq 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value))
270859ac0c16Sdavemq 	    != NXGE_OK)
270959ac0c16Sdavemq 		goto fail;
271059ac0c16Sdavemq 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
271159ac0c16Sdavemq 		pcs_ctl.bits.loopback = 1;
271259ac0c16Sdavemq 	else
271359ac0c16Sdavemq 		pcs_ctl.bits.loopback = 0;
271459ac0c16Sdavemq 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
271559ac0c16Sdavemq 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value))
271659ac0c16Sdavemq 	    != NXGE_OK)
271759ac0c16Sdavemq 		goto fail;
271844961713Sgirish 
271959ac0c16Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x1, 0xA, &val);
272059ac0c16Sdavemq 	if (status != NXGE_OK)
272159ac0c16Sdavemq 		goto fail;
272259ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
272359ac0c16Sdavemq 	    "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", portn, val));
272459ac0c16Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val);
272559ac0c16Sdavemq 	if (status != NXGE_OK)
272659ac0c16Sdavemq 		goto fail;
272759ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
272859ac0c16Sdavemq 	    "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", portn, val));
272959ac0c16Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val);
273059ac0c16Sdavemq 	if (status != NXGE_OK)
273159ac0c16Sdavemq 		goto fail;
273259ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
273359ac0c16Sdavemq 	    "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", portn, val));
273444961713Sgirish 
273559ac0c16Sdavemq #ifdef	NXGE_DEBUG
273659ac0c16Sdavemq 	/* Diagnose link issue if link is not up */
273759ac0c16Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_USER_DEV3_ADDR,
273859ac0c16Sdavemq 	    BCM8704_USER_ANALOG_STATUS0_REG,
273959ac0c16Sdavemq 	    &val);
274059ac0c16Sdavemq 	if (status != NXGE_OK)
274159ac0c16Sdavemq 		goto fail;
274244961713Sgirish 
274359ac0c16Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr,
274452ccf843Smisaki 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_ANALOG_STATUS0_REG, &val);
274559ac0c16Sdavemq 	if (status != NXGE_OK)
274659ac0c16Sdavemq 		goto fail;
274744961713Sgirish 
274859ac0c16Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr,
274952ccf843Smisaki 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1);
275059ac0c16Sdavemq 	if (status != NXGE_OK)
275159ac0c16Sdavemq 		goto fail;
275244961713Sgirish 
275359ac0c16Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr,
275452ccf843Smisaki 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1);
275559ac0c16Sdavemq 	if (status != NXGE_OK)
275659ac0c16Sdavemq 		goto fail;
275744961713Sgirish 
275859ac0c16Sdavemq 	if (val != 0x3FC) {
275959ac0c16Sdavemq 		if ((val == 0x43BC) && (val1 != 0)) {
276059ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
276159ac0c16Sdavemq 			    "Cable not connected to peer or bad"
276259ac0c16Sdavemq 			    " cable on port<%d>\n", portn));
276359ac0c16Sdavemq 		} else if (val == 0x639C) {
276459ac0c16Sdavemq 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
276559ac0c16Sdavemq 			    "Optical module (XFP) is bad or absent"
276659ac0c16Sdavemq 			    " on port<%d>\n", portn));
276759ac0c16Sdavemq 		}
276859ac0c16Sdavemq 	}
276959ac0c16Sdavemq #endif
277044961713Sgirish 
27712d17280bSsbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>",
27722d17280bSsbehera 	    portn));
27732d17280bSsbehera 	return (NXGE_OK);
27742d17280bSsbehera 
27752d17280bSsbehera fail:
27762d17280bSsbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
27772d17280bSsbehera 	    "nxge_BCM8704_xcvr_init: failed to initialize transceiver for "
27782d17280bSsbehera 	    "port<%d>", nxgep->mac.portnum));
27792d17280bSsbehera 	return (NXGE_ERROR);
27802d17280bSsbehera }
27812d17280bSsbehera 
27822d17280bSsbehera /* Initialize the BCM 8706 Transceiver */
27832d17280bSsbehera 
27842d17280bSsbehera static nxge_status_t
nxge_BCM8706_xcvr_init(p_nxge_t nxgep)27852d17280bSsbehera nxge_BCM8706_xcvr_init(p_nxge_t nxgep)
27862d17280bSsbehera {
27872d17280bSsbehera 	uint8_t			phy_port_addr;
27882d17280bSsbehera 	phyxs_control_t		phyxs_ctl;
27892d17280bSsbehera 	pcs_control_t		pcs_ctl;
27902d17280bSsbehera 	uint32_t		delay = 0;
27912d17280bSsbehera 	optics_dcntr_t		op_ctr;
27922d17280bSsbehera 	nxge_status_t		status = NXGE_OK;
27932d17280bSsbehera #ifdef	NXGE_DEBUG
27942d17280bSsbehera 	uint8_t			portn = nxgep->mac.portnum;
27952d17280bSsbehera #endif
27962d17280bSsbehera 
27972d17280bSsbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>",
27982d17280bSsbehera 	    portn));
27992d17280bSsbehera 
28002d17280bSsbehera 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
28012d17280bSsbehera 
28022d17280bSsbehera 	/* Reset the transceiver */
28032d17280bSsbehera 	if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
28042d17280bSsbehera 	    BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK)
28052d17280bSsbehera 		goto fail;
28062d17280bSsbehera 
28072d17280bSsbehera 	phyxs_ctl.bits.reset = 1;
28082d17280bSsbehera 	if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
28092d17280bSsbehera 	    BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK)
28102d17280bSsbehera 		goto fail;
28112d17280bSsbehera 	do {
28122d17280bSsbehera 		drv_usecwait(500);
28132d17280bSsbehera 		if ((status = nxge_mdio_read(nxgep, phy_port_addr,
28142d17280bSsbehera 		    BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG,
28152d17280bSsbehera 		    &phyxs_ctl.value)) != NXGE_OK)
28162d17280bSsbehera 			goto fail;
28172d17280bSsbehera 		delay++;
28182d17280bSsbehera 	} while ((phyxs_ctl.bits.reset) && (delay < 100));
28192d17280bSsbehera 
28202d17280bSsbehera 	if (delay == 100) {
28212d17280bSsbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
28222d17280bSsbehera 		    "failed to reset Transceiver on port<%d>", portn));
28232d17280bSsbehera 		status = NXGE_ERROR;
28242d17280bSsbehera 		goto fail;
28252d17280bSsbehera 	}
28262d17280bSsbehera 
28272d17280bSsbehera 	NXGE_DELAY(1000000);
28282d17280bSsbehera 
28299d587972SSantwona Behera 	/*
28309d587972SSantwona Behera 	 * Set XAUI link tunables from OBP if present.
28319d587972SSantwona Behera 	 */
28329d587972SSantwona Behera 	NXGE_SET_PHY_TUNABLES(nxgep, phy_port_addr, status);
28339d587972SSantwona Behera 	if (status != NXGE_OK) {
28349d587972SSantwona Behera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
28359d587972SSantwona Behera 		    "nxge_BCM8706_xcvr_init: Failed setting PHY tunables"));
28369d587972SSantwona Behera 		goto fail;
28379d587972SSantwona Behera 	}
28389d587972SSantwona Behera 
28392d17280bSsbehera 	/* Set BCM8706 Internal Loopback mode if necessary */
28402d17280bSsbehera 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
28412d17280bSsbehera 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value))
28422d17280bSsbehera 	    != NXGE_OK)
28432d17280bSsbehera 		goto fail;
28442d17280bSsbehera 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
28452d17280bSsbehera 		pcs_ctl.bits.loopback = 1;
28462d17280bSsbehera 	else
28472d17280bSsbehera 		pcs_ctl.bits.loopback = 0;
28482d17280bSsbehera 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
28492d17280bSsbehera 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value))
28502d17280bSsbehera 	    != NXGE_OK)
28512d17280bSsbehera 		goto fail;
28522d17280bSsbehera 
28532d17280bSsbehera 	/* Enable Tx and Rx LEDs to be driven by traffic */
28542d17280bSsbehera 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
28552d17280bSsbehera 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
28562d17280bSsbehera 	    &op_ctr.value)) != NXGE_OK)
28572d17280bSsbehera 		goto fail;
28582d17280bSsbehera 	op_ctr.bits.gpio_sel = 0x3;
28592d17280bSsbehera 	op_ctr.bits.res2 = 0x1;
28602d17280bSsbehera 
28612d17280bSsbehera 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
28622d17280bSsbehera 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
28632d17280bSsbehera 	    op_ctr.value)) != NXGE_OK)
28642d17280bSsbehera 		goto fail;
28652d17280bSsbehera 
28662d17280bSsbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>",
28672d17280bSsbehera 	    portn));
28682d17280bSsbehera 	return (NXGE_OK);
28692d17280bSsbehera 
28702d17280bSsbehera fail:
28712d17280bSsbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
28722d17280bSsbehera 	    "nxge_BCM8706_xcvr_init: failed to initialize transceiver for "
28732d17280bSsbehera 	    "port<%d>", nxgep->mac.portnum));
28742d17280bSsbehera 	return (status);
28752d17280bSsbehera }
28762d17280bSsbehera 
287789282175SSantwona Behera static int
nxge_nlp2020_i2c_read(p_nxge_t nxgep,uint8_t ctrl_port,uint16_t address,uint16_t reg,uint8_t * data)287889282175SSantwona Behera nxge_nlp2020_i2c_read(p_nxge_t nxgep, uint8_t ctrl_port, uint16_t address,
287991f84442SToomas Soome     uint16_t reg, uint8_t *data)
288089282175SSantwona Behera {
288189282175SSantwona Behera 	int  phy_dev, phy_reg;
288289282175SSantwona Behera 	uint16_t phy_data = 0;
288389282175SSantwona Behera 	uint16_t stat;
288489282175SSantwona Behera 	uint8_t count = 100;
288589282175SSantwona Behera 
288689282175SSantwona Behera 	/*
288789282175SSantwona Behera 	 * NLP2020_I2C_SNOOP_ADDR_REG [15:9][1] - Address
288889282175SSantwona Behera 	 * NLP2020_I2C_SNOOP_ADDR_REG[7:0] - register in the xcvr's i2c
288989282175SSantwona Behera 	 */
289089282175SSantwona Behera 	phy_dev = NLP2020_I2C_SNOOP_DEV_ADDR;
289189282175SSantwona Behera 	phy_reg = NLP2020_I2C_SNOOP_ADDR_REG;
289289282175SSantwona Behera 	phy_data = ((address + 1) << NLP2020_XCVR_I2C_ADDR_SH) | reg;
289389282175SSantwona Behera 	if (nxge_mdio_write(nxgep, ctrl_port,
289489282175SSantwona Behera 	    phy_dev, phy_reg, phy_data) != NXGE_OK)
289589282175SSantwona Behera 		goto fail;
289689282175SSantwona Behera 
289789282175SSantwona Behera 	phy_reg = NLP2020_I2C_SNOOP_STAT_REG;
289889282175SSantwona Behera 	(void) nxge_mdio_read(nxgep, ctrl_port, phy_dev, phy_reg, &stat);
289989282175SSantwona Behera 	while ((stat != 0x01) && (count-- > 0)) {
290089282175SSantwona Behera 		(void) nxge_mdio_read(nxgep, ctrl_port, phy_dev, phy_reg,
290189282175SSantwona Behera 		    &stat);
290289282175SSantwona Behera 	}
290389282175SSantwona Behera 	if (count) {
290489282175SSantwona Behera 		phy_reg = NLP2020_I2C_SNOOP_DATA_REG;
290589282175SSantwona Behera 		(void) nxge_mdio_read(nxgep, ctrl_port, phy_dev, phy_reg,
290689282175SSantwona Behera 		    &phy_data);
290789282175SSantwona Behera 		*data = (phy_data >> 8);
290889282175SSantwona Behera 		return (0);
290989282175SSantwona Behera 	}
291089282175SSantwona Behera fail:
291189282175SSantwona Behera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
291289282175SSantwona Behera 	    "nxge_nlp2020_i2c_read: FAILED"));
291389282175SSantwona Behera 	return (1);
291489282175SSantwona Behera 
291589282175SSantwona Behera }
291689282175SSantwona Behera 
291789282175SSantwona Behera /* Initialize the Netlogic AEL2020 Transceiver */
291889282175SSantwona Behera 
291989282175SSantwona Behera #define	NLP_INI_WAIT	1
292089282175SSantwona Behera #define	NLP_INI_STOP	0
292189282175SSantwona Behera 
292289282175SSantwona Behera static nxge_nlp_initseq_t nlp2020_revC_fiber_init[] = {
292389282175SSantwona Behera 	{0x1C003, 0x3101},
292489282175SSantwona Behera 	{0x1CC01, 0x488a},
292589282175SSantwona Behera 	{0x1CB1B, 0x0200},
292689282175SSantwona Behera 	{0x1CB1C, 0x00f0},
292789282175SSantwona Behera 	{0x1CC06, 0x00e0},
292889282175SSantwona Behera 	{NLP_INI_STOP, 0},
292989282175SSantwona Behera };
293089282175SSantwona Behera 
293189282175SSantwona Behera static nxge_nlp_initseq_t nlp2020_revC_copper_init[] = {
293289282175SSantwona Behera 
293389282175SSantwona Behera 	{0x1C003, 0x3101},
293489282175SSantwona Behera 	{0x1CD40, 0x0001},
293589282175SSantwona Behera 
293689282175SSantwona Behera 	{0x1CA12, 0x0100},
293789282175SSantwona Behera 	{0x1CA22, 0x0100},
293889282175SSantwona Behera 	{0x1CA42, 0x0100},
293989282175SSantwona Behera 	{0x1C20D, 0x0002},
294089282175SSantwona Behera 	{NLP_INI_WAIT, 100},
294189282175SSantwona Behera 
294289282175SSantwona Behera 	{0x1ff28, 0x4001},
294389282175SSantwona Behera 	{0x1ff2A, 0x004A},
294489282175SSantwona Behera 	{NLP_INI_WAIT, 500},
294589282175SSantwona Behera 
294689282175SSantwona Behera 	{0x1d000, 0x5200},
294789282175SSantwona Behera 	{NLP_INI_WAIT, 500},
294889282175SSantwona Behera 
294989282175SSantwona Behera 	{0x1d800, 0x4009},
295089282175SSantwona Behera 	{0x1d801, 0x2fff},
295189282175SSantwona Behera 	{0x1d802, 0x300f},
295289282175SSantwona Behera 	{0x1d803, 0x40aa},
295389282175SSantwona Behera 	{0x1d804, 0x401c},
295489282175SSantwona Behera 	{0x1d805, 0x401e},
295589282175SSantwona Behera 	{0x1d806, 0x20c5},
295689282175SSantwona Behera 	{0x1d807, 0x3c05},
295789282175SSantwona Behera 	{0x1d808, 0x6536},
295889282175SSantwona Behera 	{0x1d809, 0x2fe4},
295989282175SSantwona Behera 	{0x1d80a, 0x3dc4},
296089282175SSantwona Behera 	{0x1d80b, 0x6624},
296189282175SSantwona Behera 	{0x1d80c, 0x2ff4},
296289282175SSantwona Behera 	{0x1d80d, 0x3dc4},
296389282175SSantwona Behera 	{0x1d80e, 0x2035},
296489282175SSantwona Behera 	{0x1d80f, 0x30a5},
296589282175SSantwona Behera 	{0x1d810, 0x6524},
296689282175SSantwona Behera 	{0x1d811, 0x2ca2},
296789282175SSantwona Behera 	{0x1d812, 0x3012},
296889282175SSantwona Behera 	{0x1d813, 0x1002},
296989282175SSantwona Behera 	{0x1d814, 0x2882},
297089282175SSantwona Behera 	{0x1d815, 0x3022},
297189282175SSantwona Behera 	{0x1d816, 0x1002},
297289282175SSantwona Behera 	{0x1d817, 0x2972},
297389282175SSantwona Behera 	{0x1d818, 0x3022},
297489282175SSantwona Behera 	{0x1d819, 0x1002},
297589282175SSantwona Behera 	{0x1d81a, 0x2892},
297689282175SSantwona Behera 	{0x1d81b, 0x3012},
297789282175SSantwona Behera 	{0x1d81c, 0x1002},
297889282175SSantwona Behera 	{0x1d81d, 0x24e2},
297989282175SSantwona Behera 	{0x1d81e, 0x3022},
298089282175SSantwona Behera 	{0x1d81f, 0x1002},
298189282175SSantwona Behera 	{0x1d820, 0x27e2},
298289282175SSantwona Behera 	{0x1d821, 0x3012},
298389282175SSantwona Behera 	{0x1d822, 0x1002},
298489282175SSantwona Behera 	{0x1d823, 0x2422},
298589282175SSantwona Behera 	{0x1d824, 0x3022},
298689282175SSantwona Behera 	{0x1d825, 0x1002},
298789282175SSantwona Behera 	{0x1d826, 0x22cd},
298889282175SSantwona Behera 	{0x1d827, 0x301d},
298989282175SSantwona Behera 	{0x1d828, 0x2992},
299089282175SSantwona Behera 	{0x1d829, 0x3022},
299189282175SSantwona Behera 	{0x1d82a, 0x1002},
299289282175SSantwona Behera 	{0x1d82b, 0x5553},
299389282175SSantwona Behera 	{0x1d82c, 0x0307},
299489282175SSantwona Behera 	{0x1d82d, 0x2572},
299589282175SSantwona Behera 	{0x1d82e, 0x3022},
299689282175SSantwona Behera 	{0x1d82f, 0x1002},
299789282175SSantwona Behera 	{0x1d830, 0x21a2},
299889282175SSantwona Behera 	{0x1d831, 0x3012},
299989282175SSantwona Behera 	{0x1d832, 0x1002},
300089282175SSantwona Behera 	{0x1d833, 0x4016},
300189282175SSantwona Behera 	{0x1d834, 0x5e63},
300289282175SSantwona Behera 	{0x1d835, 0x0344},
300389282175SSantwona Behera 	{0x1d836, 0x21a2},
300489282175SSantwona Behera 	{0x1d837, 0x3012},
300589282175SSantwona Behera 	{0x1d838, 0x1002},
300689282175SSantwona Behera 	{0x1d839, 0x400e},
300789282175SSantwona Behera 	{0x1d83a, 0x2572},
300889282175SSantwona Behera 	{0x1d83b, 0x3022},
300989282175SSantwona Behera 	{0x1d83c, 0x1002},
301089282175SSantwona Behera 	{0x1d83d, 0x2b22},
301189282175SSantwona Behera 	{0x1d83e, 0x3012},
301289282175SSantwona Behera 	{0x1d83f, 0x1002},
301389282175SSantwona Behera 	{0x1d840, 0x28e2},
301489282175SSantwona Behera 	{0x1d841, 0x3022},
301589282175SSantwona Behera 	{0x1d842, 0x1002},
301689282175SSantwona Behera 	{0x1d843, 0x2782},
301789282175SSantwona Behera 	{0x1d844, 0x3022},
301889282175SSantwona Behera 	{0x1d845, 0x1002},
301989282175SSantwona Behera 	{0x1d846, 0x2fa4},
302089282175SSantwona Behera 	{0x1d847, 0x3dc4},
302189282175SSantwona Behera 	{0x1d848, 0x6624},
302289282175SSantwona Behera 	{0x1d849, 0x2e8b},
302389282175SSantwona Behera 	{0x1d84a, 0x303b},
302489282175SSantwona Behera 	{0x1d84b, 0x56b3},
302589282175SSantwona Behera 	{0x1d84c, 0x03c6},
302689282175SSantwona Behera 	{0x1d84d, 0x866b},
302789282175SSantwona Behera 	{0x1d84e, 0x400c},
302889282175SSantwona Behera 	{0x1d84f, 0x2782},
302989282175SSantwona Behera 	{0x1d850, 0x3012},
303089282175SSantwona Behera 	{0x1d851, 0x1002},
303189282175SSantwona Behera 	{0x1d852, 0x2c4b},
303289282175SSantwona Behera 	{0x1d853, 0x309b},
303389282175SSantwona Behera 	{0x1d854, 0x56b3},
303489282175SSantwona Behera 	{0x1d855, 0x03c3},
303589282175SSantwona Behera 	{0x1d856, 0x866b},
303689282175SSantwona Behera 	{0x1d857, 0x400c},
303789282175SSantwona Behera 	{0x1d858, 0x22a2},
303889282175SSantwona Behera 	{0x1d859, 0x3022},
303989282175SSantwona Behera 	{0x1d85a, 0x1002},
304089282175SSantwona Behera 	{0x1d85b, 0x28e2},
304189282175SSantwona Behera 	{0x1d85c, 0x3022},
304289282175SSantwona Behera 	{0x1d85d, 0x1002},
304389282175SSantwona Behera 	{0x1d85e, 0x2782},
304489282175SSantwona Behera 	{0x1d85f, 0x3022},
304589282175SSantwona Behera 	{0x1d860, 0x1002},
304689282175SSantwona Behera 	{0x1d861, 0x2fb4},
304789282175SSantwona Behera 	{0x1d862, 0x3dc4},
304889282175SSantwona Behera 	{0x1d863, 0x6624},
304989282175SSantwona Behera 	{0x1d864, 0x56b3},
305089282175SSantwona Behera 	{0x1d865, 0x03c3},
305189282175SSantwona Behera 	{0x1d866, 0x866b},
305289282175SSantwona Behera 	{0x1d867, 0x401c},
305389282175SSantwona Behera 	{0x1d868, 0x2c45},
305489282175SSantwona Behera 	{0x1d869, 0x3095},
305589282175SSantwona Behera 	{0x1d86a, 0x5b53},
305689282175SSantwona Behera 	{0x1d86b, 0x23d2},
305789282175SSantwona Behera 	{0x1d86c, 0x3012},
305889282175SSantwona Behera 	{0x1d86d, 0x13c2},
305989282175SSantwona Behera 	{0x1d86e, 0x5cc3},
306089282175SSantwona Behera 	{0x1d86f, 0x2782},
306189282175SSantwona Behera 	{0x1d870, 0x3012},
306289282175SSantwona Behera 	{0x1d871, 0x1312},
306389282175SSantwona Behera 	{0x1d872, 0x2b22},
306489282175SSantwona Behera 	{0x1d873, 0x3012},
306589282175SSantwona Behera 	{0x1d874, 0x1002},
306689282175SSantwona Behera 	{0x1d875, 0x28e2},
306789282175SSantwona Behera 	{0x1d876, 0x3022},
306889282175SSantwona Behera 	{0x1d877, 0x1002},
306989282175SSantwona Behera 	{0x1d878, 0x2672},
307089282175SSantwona Behera 	{0x1d879, 0x3022},
307189282175SSantwona Behera 	{0x1d87a, 0x1002},
307289282175SSantwona Behera 	{0x1d87b, 0x21a2},
307389282175SSantwona Behera 	{0x1d87c, 0x3012},
307489282175SSantwona Behera 	{0x1d87d, 0x1002},
307589282175SSantwona Behera 	{0x1d87e, 0x628f},
307689282175SSantwona Behera 	{0x1d87f, 0x2985},
307789282175SSantwona Behera 	{0x1d880, 0x33a5},
307889282175SSantwona Behera 	{0x1d881, 0x2782},
307989282175SSantwona Behera 	{0x1d882, 0x3022},
308089282175SSantwona Behera 	{0x1d883, 0x1002},
308189282175SSantwona Behera 	{0x1d884, 0x5653},
308289282175SSantwona Behera 	{0x1d885, 0x03d2},
308389282175SSantwona Behera 	{0x1d886, 0x401e},
308489282175SSantwona Behera 	{0x1d887, 0x6f72},
308589282175SSantwona Behera 	{0x1d888, 0x1002},
308689282175SSantwona Behera 	{0x1d889, 0x628f},
308789282175SSantwona Behera 	{0x1d88a, 0x2304},
308889282175SSantwona Behera 	{0x1d88b, 0x3c84},
308989282175SSantwona Behera 	{0x1d88c, 0x6436},
309089282175SSantwona Behera 	{0x1d88d, 0xdff4},
309189282175SSantwona Behera 	{0x1d88e, 0x6436},
309289282175SSantwona Behera 	{0x1d88f, 0x2ff5},
309389282175SSantwona Behera 	{0x1d890, 0x3005},
309489282175SSantwona Behera 	{0x1d891, 0x8656},
309589282175SSantwona Behera 	{0x1d892, 0xdfba},
309689282175SSantwona Behera 	{0x1d893, 0x56a3},
309789282175SSantwona Behera 	{0x1d894, 0xd05a},
309889282175SSantwona Behera 	{0x1d895, 0x29e2},
309989282175SSantwona Behera 	{0x1d896, 0x3012},
310089282175SSantwona Behera 	{0x1d897, 0x1392},
310189282175SSantwona Behera 	{0x1d898, 0xd05a},
310289282175SSantwona Behera 	{0x1d899, 0x56a3},
310389282175SSantwona Behera 	{0x1d89a, 0xdfba},
310489282175SSantwona Behera 	{0x1d89b, 0x0383},
310589282175SSantwona Behera 	{0x1d89c, 0x6f72},
310689282175SSantwona Behera 	{0x1d89d, 0x1002},
310789282175SSantwona Behera 	{0x1d89e, 0x2a64},
310889282175SSantwona Behera 	{0x1d89f, 0x3014},
310989282175SSantwona Behera 	{0x1d8a0, 0x2005},
311089282175SSantwona Behera 	{0x1d8a1, 0x3d75},
311189282175SSantwona Behera 	{0x1d8a2, 0xc451},
311289282175SSantwona Behera 	{0x1d8a3, 0x2a42},
311389282175SSantwona Behera 	{0x1d8a4, 0x3022},
311489282175SSantwona Behera 	{0x1d8a5, 0x1002},
311589282175SSantwona Behera 	{0x1d8a6, 0x178c},
311689282175SSantwona Behera 	{0x1d8a7, 0x1898},
311789282175SSantwona Behera 	{0x1d8a8, 0x19a4},
311889282175SSantwona Behera 	{0x1d8a9, 0x1ab0},
311989282175SSantwona Behera 	{0x1d8aa, 0x1bbc},
312089282175SSantwona Behera 	{0x1d8ab, 0x1cc8},
312189282175SSantwona Behera 	{0x1d8ac, 0x1dd3},
312289282175SSantwona Behera 	{0x1d8ad, 0x1ede},
312389282175SSantwona Behera 	{0x1d8ae, 0x1fe9},
312489282175SSantwona Behera 	{0x1d8af, 0x20f4},
312589282175SSantwona Behera 	{0x1d8b0, 0x21ff},
312689282175SSantwona Behera 	{0x1d8b1, 0x0000},
312789282175SSantwona Behera 	{0x1d8b2, 0x27e1},
312889282175SSantwona Behera 	{0x1d8b3, 0x3021},
312989282175SSantwona Behera 	{0x1d8b4, 0x1001},
313089282175SSantwona Behera 	{0x1d8b5, 0xc620},
313189282175SSantwona Behera 	{0x1d8b6, 0x0000},
313289282175SSantwona Behera 	{0x1d8b7, 0xc621},
313389282175SSantwona Behera 	{0x1d8b8, 0x0000},
313489282175SSantwona Behera 	{0x1d8b9, 0xc622},
313589282175SSantwona Behera 	{0x1d8ba, 0x00e2},
313689282175SSantwona Behera 	{0x1d8bb, 0xc623},
313789282175SSantwona Behera 	{0x1d8bc, 0x007f},
313889282175SSantwona Behera 	{0x1d8bd, 0xc624},
313989282175SSantwona Behera 	{0x1d8be, 0x00ce},
314089282175SSantwona Behera 	{0x1d8bf, 0xc625},
314189282175SSantwona Behera 	{0x1d8c0, 0x0000},
314289282175SSantwona Behera 	{0x1d8c1, 0xc627},
314389282175SSantwona Behera 	{0x1d8c2, 0x0000},
314489282175SSantwona Behera 	{0x1d8c3, 0xc628},
314589282175SSantwona Behera 	{0x1d8c4, 0x0000},
314689282175SSantwona Behera 	{0x1d8c5, 0xc90a},
314789282175SSantwona Behera 	{0x1d8c6, 0x3a7c},
314889282175SSantwona Behera 	{0x1d8c7, 0xc62c},
314989282175SSantwona Behera 	{0x1d8c8, 0x0000},
315089282175SSantwona Behera 	{0x1d8c9, 0x0000},
315189282175SSantwona Behera 	{0x1d8ca, 0x27e1},
315289282175SSantwona Behera 	{0x1d8cb, 0x3021},
315389282175SSantwona Behera 	{0x1d8cc, 0x1001},
315489282175SSantwona Behera 	{0x1d8cd, 0xc502},
315589282175SSantwona Behera 	{0x1d8ce, 0x53ac},
315689282175SSantwona Behera 	{0x1d8cf, 0xc503},
315789282175SSantwona Behera 	{0x1d8d0, 0x2cd3},
315889282175SSantwona Behera 	{0x1d8d1, 0xc600},
315989282175SSantwona Behera 	{0x1d8d2, 0x2a6e},
316089282175SSantwona Behera 	{0x1d8d3, 0xc601},
316189282175SSantwona Behera 	{0x1d8d4, 0x2a2c},
316289282175SSantwona Behera 	{0x1d8d5, 0xc605},
316389282175SSantwona Behera 	{0x1d8d6, 0x5557},
316489282175SSantwona Behera 	{0x1d8d7, 0xc60c},
316589282175SSantwona Behera 	{0x1d8d8, 0x5400},
316689282175SSantwona Behera 	{0x1d8d9, 0xc710},
316789282175SSantwona Behera 	{0x1d8da, 0x0700},
316889282175SSantwona Behera 	{0x1d8db, 0xc711},
316989282175SSantwona Behera 	{0x1d8dc, 0x0f06},
317089282175SSantwona Behera 	{0x1d8dd, 0xc718},
317189282175SSantwona Behera 	{0x1d8de, 0x0700},
317289282175SSantwona Behera 	{0x1d8df, 0xc719},
317389282175SSantwona Behera 	{0x1d8e0, 0x0f06},
317489282175SSantwona Behera 	{0x1d8e1, 0xc720},
317589282175SSantwona Behera 	{0x1d8e2, 0x4700},
317689282175SSantwona Behera 	{0x1d8e3, 0xc721},
317789282175SSantwona Behera 	{0x1d8e4, 0x0f06},
317889282175SSantwona Behera 	{0x1d8e5, 0xc728},
317989282175SSantwona Behera 	{0x1d8e6, 0x0700},
318089282175SSantwona Behera 	{0x1d8e7, 0xc729},
318189282175SSantwona Behera 	{0x1d8e8, 0x1207},
318289282175SSantwona Behera 	{0x1d8e9, 0xc801},
318389282175SSantwona Behera 	{0x1d8ea, 0x7f50},
318489282175SSantwona Behera 	{0x1d8eb, 0xc802},
318589282175SSantwona Behera 	{0x1d8ec, 0x7760},
318689282175SSantwona Behera 	{0x1d8ed, 0xc803},
318789282175SSantwona Behera 	{0x1d8ee, 0x7fce},
318889282175SSantwona Behera 	{0x1d8ef, 0xc804},
318989282175SSantwona Behera 	{0x1d8f0, 0x520e},
319089282175SSantwona Behera 	{0x1d8f1, 0xc805},
319189282175SSantwona Behera 	{0x1d8f2, 0x5c11},
319289282175SSantwona Behera 	{0x1d8f3, 0xc806},
319389282175SSantwona Behera 	{0x1d8f4, 0x3c51},
319489282175SSantwona Behera 	{0x1d8f5, 0xc807},
319589282175SSantwona Behera 	{0x1d8f6, 0x4061},
319689282175SSantwona Behera 	{0x1d8f7, 0xc808},
319789282175SSantwona Behera 	{0x1d8f8, 0x49c1},
319889282175SSantwona Behera 	{0x1d8f9, 0xc809},
319989282175SSantwona Behera 	{0x1d8fa, 0x3840},
320089282175SSantwona Behera 	{0x1d8fb, 0xc80a},
320189282175SSantwona Behera 	{0x1d8fc, 0x0000},
320289282175SSantwona Behera 	{0x1d8fd, 0xc821},
320389282175SSantwona Behera 	{0x1d8fe, 0x0002},
320489282175SSantwona Behera 	{0x1d8ff, 0xc822},
320589282175SSantwona Behera 	{0x1d900, 0x0046},
320689282175SSantwona Behera 	{0x1d901, 0xc844},
320789282175SSantwona Behera 	{0x1d902, 0x182f},
320889282175SSantwona Behera 	{0x1d903, 0xc849},
320989282175SSantwona Behera 	{0x1d904, 0x0400},
321089282175SSantwona Behera 	{0x1d905, 0xc84a},
321189282175SSantwona Behera 	{0x1d906, 0x0002},
321289282175SSantwona Behera 	{0x1d907, 0xc013},
321389282175SSantwona Behera 	{0x1d908, 0xf341},
321489282175SSantwona Behera 	{0x1d909, 0xc084},
321589282175SSantwona Behera 	{0x1d90a, 0x0030},
321689282175SSantwona Behera 	{0x1d90b, 0xc904},
321789282175SSantwona Behera 	{0x1d90c, 0x1401},
321889282175SSantwona Behera 	{0x1d90d, 0xcb0c},
321989282175SSantwona Behera 	{0x1d90e, 0x0004},
322089282175SSantwona Behera 	{0x1d90f, 0xcb0e},
322189282175SSantwona Behera 	{0x1d910, 0xa00a},
322289282175SSantwona Behera 	{0x1d911, 0xcb0f},
322389282175SSantwona Behera 	{0x1d912, 0xc0c0},
322489282175SSantwona Behera 	{0x1d913, 0xcb10},
322589282175SSantwona Behera 	{0x1d914, 0xc0c0},
322689282175SSantwona Behera 	{0x1d915, 0xcb11},
322789282175SSantwona Behera 	{0x1d916, 0x00a0},
322889282175SSantwona Behera 	{0x1d917, 0xcb12},
322989282175SSantwona Behera 	{0x1d918, 0x0007},
323089282175SSantwona Behera 	{0x1d919, 0xc241},
323189282175SSantwona Behera 	{0x1d91a, 0xa000},
323289282175SSantwona Behera 	{0x1d91b, 0xc243},
323389282175SSantwona Behera 	{0x1d91c, 0x7fe0},
323489282175SSantwona Behera 	{0x1d91d, 0xc604},
323589282175SSantwona Behera 	{0x1d91e, 0x000e},
323689282175SSantwona Behera 	{0x1d91f, 0xc609},
323789282175SSantwona Behera 	{0x1d920, 0x00f5},
323889282175SSantwona Behera 	{0x1d921, 0x0c61},
323989282175SSantwona Behera 	{0x1d922, 0x000e},
324089282175SSantwona Behera 	{0x1d923, 0xc660},
324189282175SSantwona Behera 	{0x1d924, 0x9600},
324289282175SSantwona Behera 	{0x1d925, 0xc687},
324389282175SSantwona Behera 	{0x1d926, 0x0004},
324489282175SSantwona Behera 	{0x1d927, 0xc60a},
324589282175SSantwona Behera 	{0x1d928, 0x04f5},
324689282175SSantwona Behera 	{0x1d929, 0x0000},
324789282175SSantwona Behera 	{0x1d92a, 0x27e1},
324889282175SSantwona Behera 	{0x1d92b, 0x3021},
324989282175SSantwona Behera 	{0x1d92c, 0x1001},
325089282175SSantwona Behera 	{0x1d92d, 0xc620},
325189282175SSantwona Behera 	{0x1d92e, 0x14e5},
325289282175SSantwona Behera 	{0x1d92f, 0xc621},
325389282175SSantwona Behera 	{0x1d930, 0xc53d},
325489282175SSantwona Behera 	{0x1d931, 0xc622},
325589282175SSantwona Behera 	{0x1d932, 0x3cbe},
325689282175SSantwona Behera 	{0x1d933, 0xc623},
325789282175SSantwona Behera 	{0x1d934, 0x4452},
325889282175SSantwona Behera 	{0x1d935, 0xc624},
325989282175SSantwona Behera 	{0x1d936, 0xc5c5},
326089282175SSantwona Behera 	{0x1d937, 0xc625},
326189282175SSantwona Behera 	{0x1d938, 0xe01e},
326289282175SSantwona Behera 	{0x1d939, 0xc627},
326389282175SSantwona Behera 	{0x1d93a, 0x0000},
326489282175SSantwona Behera 	{0x1d93b, 0xc628},
326589282175SSantwona Behera 	{0x1d93c, 0x0000},
326689282175SSantwona Behera 	{0x1d93d, 0xc62c},
326789282175SSantwona Behera 	{0x1d93e, 0x0000},
326889282175SSantwona Behera 	{0x1d93f, 0xc90a},
326989282175SSantwona Behera 	{0x1d940, 0x3a7c},
327089282175SSantwona Behera 	{0x1d941, 0x0000},
327189282175SSantwona Behera 	{0x1d942, 0x2b84},
327289282175SSantwona Behera 	{0x1d943, 0x3c74},
327389282175SSantwona Behera 	{0x1d944, 0x6435},
327489282175SSantwona Behera 	{0x1d945, 0xdff4},
327589282175SSantwona Behera 	{0x1d946, 0x6435},
327689282175SSantwona Behera 	{0x1d947, 0x2806},
327789282175SSantwona Behera 	{0x1d948, 0x3006},
327889282175SSantwona Behera 	{0x1d949, 0x8565},
327989282175SSantwona Behera 	{0x1d94a, 0x2b24},
328089282175SSantwona Behera 	{0x1d94b, 0x3c24},
328189282175SSantwona Behera 	{0x1d94c, 0x6436},
328289282175SSantwona Behera 	{0x1d94d, 0x1002},
328389282175SSantwona Behera 	{0x1d94e, 0x2b24},
328489282175SSantwona Behera 	{0x1d94f, 0x3c24},
328589282175SSantwona Behera 	{0x1d950, 0x6436},
328689282175SSantwona Behera 	{0x1d951, 0x4045},
328789282175SSantwona Behera 	{0x1d952, 0x8656},
328889282175SSantwona Behera 	{0x1d953, 0x5663},
328989282175SSantwona Behera 	{0x1d954, 0x0302},
329089282175SSantwona Behera 	{0x1d955, 0x401e},
329189282175SSantwona Behera 	{0x1d956, 0x1002},
329289282175SSantwona Behera 	{0x1d957, 0x2017},
329389282175SSantwona Behera 	{0x1d958, 0x3b17},
329489282175SSantwona Behera 	{0x1d959, 0x2084},
329589282175SSantwona Behera 	{0x1d95a, 0x3c14},
329689282175SSantwona Behera 	{0x1d95b, 0x6724},
329789282175SSantwona Behera 	{0x1d95c, 0x2807},
329889282175SSantwona Behera 	{0x1d95d, 0x31a7},
329989282175SSantwona Behera 	{0x1d95e, 0x20c4},
330089282175SSantwona Behera 	{0x1d95f, 0x3c24},
330189282175SSantwona Behera 	{0x1d960, 0x6724},
330289282175SSantwona Behera 	{0x1d961, 0x2ff7},
330389282175SSantwona Behera 	{0x1d962, 0x30f7},
330489282175SSantwona Behera 	{0x1d963, 0x20c4},
330589282175SSantwona Behera 	{0x1d964, 0x3c04},
330689282175SSantwona Behera 	{0x1d965, 0x6724},
330789282175SSantwona Behera 	{0x1d966, 0x1002},
330889282175SSantwona Behera 	{0x1d967, 0x2807},
330989282175SSantwona Behera 	{0x1d968, 0x3187},
331089282175SSantwona Behera 	{0x1d969, 0x20c4},
331189282175SSantwona Behera 	{0x1d96a, 0x3c24},
331289282175SSantwona Behera 	{0x1d96b, 0x6724},
331389282175SSantwona Behera 	{0x1d96c, 0x2fe4},
331489282175SSantwona Behera 	{0x1d96d, 0x3dc4},
331589282175SSantwona Behera 	{0x1d96e, 0x6437},
331689282175SSantwona Behera 	{0x1d96f, 0x20c4},
331789282175SSantwona Behera 	{0x1d970, 0x3c04},
331889282175SSantwona Behera 	{0x1d971, 0x6724},
331989282175SSantwona Behera 	{0x1d972, 0x2017},
332089282175SSantwona Behera 	{0x1d973, 0x3d17},
332189282175SSantwona Behera 	{0x1d974, 0x2084},
332289282175SSantwona Behera 	{0x1d975, 0x3c14},
332389282175SSantwona Behera 	{0x1d976, 0x6724},
332489282175SSantwona Behera 	{0x1d977, 0x1002},
332589282175SSantwona Behera 	{0x1d978, 0x24f4},
332689282175SSantwona Behera 	{0x1d979, 0x3c64},
332789282175SSantwona Behera 	{0x1d97a, 0x6436},
332889282175SSantwona Behera 	{0x1d97b, 0xdff4},
332989282175SSantwona Behera 	{0x1d97c, 0x6436},
333089282175SSantwona Behera 	{0x1d97d, 0x1002},
333189282175SSantwona Behera 	{0x1d97e, 0x2006},
333289282175SSantwona Behera 	{0x1d97f, 0x3d76},
333389282175SSantwona Behera 	{0x1d980, 0xc161},
333489282175SSantwona Behera 	{0x1d981, 0x6134},
333589282175SSantwona Behera 	{0x1d982, 0x6135},
333689282175SSantwona Behera 	{0x1d983, 0x5443},
333789282175SSantwona Behera 	{0x1d984, 0x0303},
333889282175SSantwona Behera 	{0x1d985, 0x6524},
333989282175SSantwona Behera 	{0x1d986, 0x00fb},
334089282175SSantwona Behera 	{0x1d987, 0x1002},
334189282175SSantwona Behera 	{0x1d988, 0x20d4},
334289282175SSantwona Behera 	{0x1d989, 0x3c24},
334389282175SSantwona Behera 	{0x1d98a, 0x2025},
334489282175SSantwona Behera 	{0x1d98b, 0x3005},
334589282175SSantwona Behera 	{0x1d98c, 0x6524},
334689282175SSantwona Behera 	{0x1d98d, 0x1002},
334789282175SSantwona Behera 	{0x1d98e, 0xd019},
334889282175SSantwona Behera 	{0x1d98f, 0x2104},
334989282175SSantwona Behera 	{0x1d990, 0x3c24},
335089282175SSantwona Behera 	{0x1d991, 0x2105},
335189282175SSantwona Behera 	{0x1d992, 0x3805},
335289282175SSantwona Behera 	{0x1d993, 0x6524},
335389282175SSantwona Behera 	{0x1d994, 0xdff4},
335489282175SSantwona Behera 	{0x1d995, 0x4005},
335589282175SSantwona Behera 	{0x1d996, 0x6524},
335689282175SSantwona Behera 	{0x1d997, 0x2e8d},
335789282175SSantwona Behera 	{0x1d998, 0x303d},
335889282175SSantwona Behera 	{0x1d999, 0x2408},
335989282175SSantwona Behera 	{0x1d99a, 0x35d8},
336089282175SSantwona Behera 	{0x1d99b, 0x5dd3},
336189282175SSantwona Behera 	{0x1d99c, 0x0307},
336289282175SSantwona Behera 	{0x1d99d, 0x8887},
336389282175SSantwona Behera 	{0x1d99e, 0x63a7},
336489282175SSantwona Behera 	{0x1d99f, 0x8887},
336589282175SSantwona Behera 	{0x1d9a0, 0x63a7},
336689282175SSantwona Behera 	{0x1d9a1, 0xdffd},
336789282175SSantwona Behera 	{0x1d9a2, 0x00f9},
336889282175SSantwona Behera 	{0x1d9a3, 0x1002},
336989282175SSantwona Behera 	{0x1d9a4, 0x866a},
337089282175SSantwona Behera 	{0x1d9a5, 0x6138},
337189282175SSantwona Behera 	{0x1d9a6, 0x5883},
337289282175SSantwona Behera 	{0x1d9a7, 0x2b42},
337389282175SSantwona Behera 	{0x1d9a8, 0x3022},
337489282175SSantwona Behera 	{0x1d9a9, 0x1302},
337589282175SSantwona Behera 	{0x1d9aa, 0x2ff7},
337689282175SSantwona Behera 	{0x1d9ab, 0x3007},
337789282175SSantwona Behera 	{0x1d9ac, 0x8785},
337889282175SSantwona Behera 	{0x1d9ad, 0xb887},
337989282175SSantwona Behera 	{0x1d9ae, 0x8786},
338089282175SSantwona Behera 	{0x1d9af, 0xb8c6},
338189282175SSantwona Behera 	{0x1d9b0, 0x5a53},
338289282175SSantwona Behera 	{0x1d9b1, 0x2a52},
338389282175SSantwona Behera 	{0x1d9b2, 0x3022},
338489282175SSantwona Behera 	{0x1d9b3, 0x13c2},
338589282175SSantwona Behera 	{0x1d9b4, 0x2474},
338689282175SSantwona Behera 	{0x1d9b5, 0x3c84},
338789282175SSantwona Behera 	{0x1d9b6, 0x64d7},
338889282175SSantwona Behera 	{0x1d9b7, 0x64d7},
338989282175SSantwona Behera 	{0x1d9b8, 0x2ff5},
339089282175SSantwona Behera 	{0x1d9b9, 0x3c05},
339189282175SSantwona Behera 	{0x1d9ba, 0x8757},
339289282175SSantwona Behera 	{0x1d9bb, 0xb886},
339389282175SSantwona Behera 	{0x1d9bc, 0x9767},
339489282175SSantwona Behera 	{0x1d9bd, 0x67c4},
339589282175SSantwona Behera 	{0x1d9be, 0x6f72},
339689282175SSantwona Behera 	{0x1d9bf, 0x1002},
339789282175SSantwona Behera 	{0x1d9c0, 0x0000},
339889282175SSantwona Behera 	{0x1d080, 0x0100},
339989282175SSantwona Behera 	{0x1d092, 0x0000},
340089282175SSantwona Behera 	{NLP_INI_STOP, 0},
340189282175SSantwona Behera };
340289282175SSantwona Behera 
340389282175SSantwona Behera static nxge_status_t
nxge_nlp2020_xcvr_init(p_nxge_t nxgep)340489282175SSantwona Behera nxge_nlp2020_xcvr_init(p_nxge_t nxgep)
340589282175SSantwona Behera {
340689282175SSantwona Behera 	uint8_t			phy_port_addr;
340789282175SSantwona Behera 	nxge_status_t		status = NXGE_OK;
340889282175SSantwona Behera 	uint16_t		ctrl_reg, rst_val, pmd_ctl, rx_los;
340989282175SSantwona Behera 	int			i = 0, count = 1000;
341089282175SSantwona Behera 
341189282175SSantwona Behera 	uint8_t			connector = 0, len, lpm;
341289282175SSantwona Behera 	p_nxge_nlp_initseq_t	initseq;
341389282175SSantwona Behera 	uint16_t		dev, reg, val;
341489282175SSantwona Behera 
341589282175SSantwona Behera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_nlp2020_xcvr_init: "
341689282175SSantwona Behera 	    "port<%d>, phyaddr[0x%x]", nxgep->mac.portnum,
341789282175SSantwona Behera 	    nxgep->statsp->mac_stats.xcvr_portn));
341889282175SSantwona Behera 
341989282175SSantwona Behera 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
342089282175SSantwona Behera 
342189282175SSantwona Behera 	/* Reset the transceiver */
342289282175SSantwona Behera 	rst_val = ctrl_reg = NLP2020_PMA_PMD_PHY_RST;
342389282175SSantwona Behera 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
342489282175SSantwona Behera 	    NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, rst_val))
342589282175SSantwona Behera 	    != NXGE_OK)
342689282175SSantwona Behera 		goto fail;
342789282175SSantwona Behera 	while ((count--) && (ctrl_reg & rst_val)) {
342889282175SSantwona Behera 		drv_usecwait(1000);
342989282175SSantwona Behera 		(void) nxge_mdio_read(nxgep, phy_port_addr,
343089282175SSantwona Behera 		    NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, &ctrl_reg);
343189282175SSantwona Behera 	}
343289282175SSantwona Behera 	if (count == 0) {
343389282175SSantwona Behera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_nlp2020_xcvr_init: "
343489282175SSantwona Behera 		    "PMA_PMD reset failed"));
343589282175SSantwona Behera 		goto fail;
343689282175SSantwona Behera 	}
343789282175SSantwona Behera 
343889282175SSantwona Behera 	/* Set loopback mode if required */
343989282175SSantwona Behera 	/* Set PMA PMD system loopback */
344089282175SSantwona Behera 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
344189282175SSantwona Behera 	    NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, &pmd_ctl))
344289282175SSantwona Behera 	    != NXGE_OK)
344389282175SSantwona Behera 		goto fail;
344489282175SSantwona Behera 
344589282175SSantwona Behera 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
344689282175SSantwona Behera 		pmd_ctl |= 0x0001;
344789282175SSantwona Behera 	else
344889282175SSantwona Behera 		pmd_ctl &= 0xfffe;
344989282175SSantwona Behera 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
345089282175SSantwona Behera 	    NLP2020_PMA_PMD_ADDR, NLP2020_PMA_PMD_CTL_REG, pmd_ctl))
345189282175SSantwona Behera 	    != NXGE_OK)
345289282175SSantwona Behera 		goto fail;
345389282175SSantwona Behera 
345489282175SSantwona Behera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_nlp2020_xcvr_init: "
345589282175SSantwona Behera 	    "setting LB, wrote NLP2020_PMA_PMD_CTL_REG[0x%x]", pmd_ctl));
345689282175SSantwona Behera 
345789282175SSantwona Behera 	/* Check connector details using I2c */
345889282175SSantwona Behera 	if (nxge_nlp2020_i2c_read(nxgep, phy_port_addr, NLP2020_XCVR_I2C_ADDR,
345989282175SSantwona Behera 	    QSFP_MSA_CONN_REG, &connector) == 1) {
346089282175SSantwona Behera 		goto fail;
346189282175SSantwona Behera 	}
346289282175SSantwona Behera 
346389282175SSantwona Behera 	switch (connector) {
346489282175SSantwona Behera 	case SFPP_FIBER:
346589282175SSantwona Behera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
346689282175SSantwona Behera 		    "nxge_nlp2020_xcvr_init: SFPP_FIBER detected"));
346789282175SSantwona Behera 		initseq = nlp2020_revC_fiber_init;
346889282175SSantwona Behera 		nxgep->nlp_conn = NXGE_NLP_CONN_FIBER;
346989282175SSantwona Behera 		break;
347089282175SSantwona Behera 	case QSFP_FIBER:
347189282175SSantwona Behera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
347289282175SSantwona Behera 		    "nxge_nlp2020_xcvr_init: QSFP_FIBER detected"));
347389282175SSantwona Behera 		initseq = nlp2020_revC_fiber_init;
347489282175SSantwona Behera 		nxgep->nlp_conn = NXGE_NLP_CONN_FIBER;
347589282175SSantwona Behera 		break;
347689282175SSantwona Behera 	case QSFP_COPPER_TWINAX:
347789282175SSantwona Behera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
347889282175SSantwona Behera 		    "nxge_nlp2020_xcvr_init: QSFP_COPPER_TWINAX/"
347989282175SSantwona Behera 		    "SFPP_COPPER_TWINAX detected"));
348089282175SSantwona Behera 
348189282175SSantwona Behera 		initseq = nlp2020_revC_copper_init;
348289282175SSantwona Behera 		nxgep->nlp_conn = NXGE_NLP_CONN_COPPER_LT_7M;
348389282175SSantwona Behera 		break;
348489282175SSantwona Behera 	default:
348589282175SSantwona Behera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
348689282175SSantwona Behera 		    "nxge_nlp2020_xcvr_init: Unknown type [0x%x] detected",
348789282175SSantwona Behera 		    "...setting to QSFP_FIBER",
348889282175SSantwona Behera 		    connector));
348989282175SSantwona Behera 		initseq = nlp2020_revC_fiber_init;
349089282175SSantwona Behera 		nxgep->nlp_conn = NXGE_NLP_CONN_FIBER;
349189282175SSantwona Behera 		break;
349289282175SSantwona Behera 	}
349389282175SSantwona Behera 
349489282175SSantwona Behera 	/* Run appropriate init sequence */
349589282175SSantwona Behera 	for (i = 0; initseq[i].dev_reg != NLP_INI_STOP; i++) {
349689282175SSantwona Behera 		dev = initseq[i].dev_reg >> 16;
349789282175SSantwona Behera 		reg = initseq[i].dev_reg & 0xffff;
349889282175SSantwona Behera 		val = initseq[i].val;
349989282175SSantwona Behera 
350089282175SSantwona Behera 		if (reg == NLP_INI_WAIT) {
350189282175SSantwona Behera 			drv_usecwait(1000 * val);
350289282175SSantwona Behera 		} else {
350389282175SSantwona Behera 			if ((status = nxge_mdio_write(nxgep, phy_port_addr,
350489282175SSantwona Behera 			    dev, reg, val)) != NXGE_OK)
350589282175SSantwona Behera 				goto fail;
350689282175SSantwona Behera 		}
350789282175SSantwona Behera 	}
350889282175SSantwona Behera 
350989282175SSantwona Behera 	/* rx_los inversion */
351089282175SSantwona Behera 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
351189282175SSantwona Behera 	    NLP2020_PMA_PMD_ADDR, NLP2020_OPT_SET_REG, &rx_los)) != NXGE_OK)
351289282175SSantwona Behera 			goto fail;
351389282175SSantwona Behera 
351489282175SSantwona Behera 	rx_los &= ~(NLP2020_RXLOS_ACT_H);
351589282175SSantwona Behera 
351689282175SSantwona Behera 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
351789282175SSantwona Behera 	    NLP2020_PMA_PMD_ADDR, NLP2020_OPT_SET_REG, rx_los)) != NXGE_OK)
351889282175SSantwona Behera 			goto fail;
351989282175SSantwona Behera 
352089282175SSantwona Behera 	if (nxge_nlp2020_i2c_read(nxgep, phy_port_addr, NLP2020_XCVR_I2C_ADDR,
352189282175SSantwona Behera 	    QSFP_MSA_LEN_REG, &len) == 1) {
352289282175SSantwona Behera 		goto fail;
352389282175SSantwona Behera 	}
352489282175SSantwona Behera 
352589282175SSantwona Behera 	if (nxge_nlp2020_i2c_read(nxgep, phy_port_addr, NLP2020_XCVR_I2C_ADDR,
352689282175SSantwona Behera 	    QSFP_MSA_LPM_REG, &lpm) == 1) {
352789282175SSantwona Behera 		goto fail;
352889282175SSantwona Behera 	}
352989282175SSantwona Behera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
353089282175SSantwona Behera 	    "nxge_nlp2020_xcvr_init: len[0x%x] lpm[0x%x]", len, lpm));
353189282175SSantwona Behera 
353289282175SSantwona Behera 	if (connector == QSFP_COPPER_TWINAX) {
353389282175SSantwona Behera 		if (len >= 7) {
353489282175SSantwona Behera 			nxgep->nlp_conn = NXGE_NLP_CONN_COPPER_7M_ABOVE;
353589282175SSantwona Behera 			/* enable pre-emphasis */
353689282175SSantwona Behera 			(void) nxge_mdio_write(nxgep, phy_port_addr,
353789282175SSantwona Behera 			    NLP2020_PMA_PMD_ADDR, NLP2020_TX_DRV_CTL1_REG,
353889282175SSantwona Behera 			    NLP2020_TX_DRV_CTL1_PREEMP_EN);
353989282175SSantwona Behera 			/* write emphasis value */
354089282175SSantwona Behera 			(void) nxge_mdio_write(nxgep, phy_port_addr,
354189282175SSantwona Behera 			    NLP2020_PMA_PMD_ADDR, NLP2020_TX_DRV_CTL2_REG,
354289282175SSantwona Behera 			    NLP2020_TX_DRV_CTL2_EMP_VAL);
354389282175SSantwona Behera 			/* stop microcontroller */
354489282175SSantwona Behera 			(void) nxge_mdio_write(nxgep, phy_port_addr,
354589282175SSantwona Behera 			    NLP2020_PMA_PMD_ADDR, NLP2020_UC_CTL_REG,
354689282175SSantwona Behera 			    NLP2020_UC_CTL_STOP);
354789282175SSantwona Behera 			/* reset program counter */
354889282175SSantwona Behera 			(void) nxge_mdio_write(nxgep, phy_port_addr,
354989282175SSantwona Behera 			    NLP2020_PMA_PMD_ADDR, NLP2020_UC_PC_START_REG,
355089282175SSantwona Behera 			    NLP2020_UC_PC_START_VAL);
355189282175SSantwona Behera 			/* start microcontroller */
355289282175SSantwona Behera 			(void) nxge_mdio_write(nxgep, phy_port_addr,
355389282175SSantwona Behera 			    NLP2020_PMA_PMD_ADDR, NLP2020_UC_CTL_REG,
355489282175SSantwona Behera 			    NLP2020_UC_CTL_START);
355589282175SSantwona Behera 		}
355689282175SSantwona Behera 	}
355789282175SSantwona Behera 	if (lpm & QSFP_MSA_LPM_HIGH) {
355889282175SSantwona Behera 		/* enable high power mode */
355989282175SSantwona Behera 		(void) nxge_mdio_write(nxgep, phy_port_addr,
356089282175SSantwona Behera 		    NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG,
356189282175SSantwona Behera 		    NLP2020_GPIO_ACT);
356289282175SSantwona Behera 	} else {
356389282175SSantwona Behera 		/* revert to low power mode */
356489282175SSantwona Behera 		(void) nxge_mdio_write(nxgep, phy_port_addr,
356589282175SSantwona Behera 		    NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG,
356689282175SSantwona Behera 		    NLP2020_GPIO_INACT);
356789282175SSantwona Behera 	}
35689d587972SSantwona Behera 
35699d587972SSantwona Behera 	/*
35709d587972SSantwona Behera 	 * Set XAUI link tunables from OBP if present.
35719d587972SSantwona Behera 	 */
35729d587972SSantwona Behera 	NXGE_SET_PHY_TUNABLES(nxgep, phy_port_addr, status);
35739d587972SSantwona Behera 	if (status != NXGE_OK) {
35749d587972SSantwona Behera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
35759d587972SSantwona Behera 		    "nxge_nlp2020_xcvr_init: Failed setting PHY tunables"));
35769d587972SSantwona Behera 		goto fail;
35779d587972SSantwona Behera 	}
35789d587972SSantwona Behera 
357989282175SSantwona Behera 	/* It takes ~2s for EDC to settle */
358089282175SSantwona Behera 	drv_usecwait(2000000);
358189282175SSantwona Behera 
358289282175SSantwona Behera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_nlp2020_xcvr_init: "
358389282175SSantwona Behera 	    "port<%d> phyaddr[0x%x]", nxgep->mac.portnum, phy_port_addr));
358489282175SSantwona Behera 
358589282175SSantwona Behera 	return (NXGE_OK);
358689282175SSantwona Behera 
358789282175SSantwona Behera fail:
358889282175SSantwona Behera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
358989282175SSantwona Behera 	    "nxge_nlp2020_xcvr_init: failed to initialize transceiver for "
359089282175SSantwona Behera 	    "port<%d>", nxgep->mac.portnum));
359189282175SSantwona Behera 	return (status);
359289282175SSantwona Behera }
359389282175SSantwona Behera 
nxge_is_nlp2020_phy(p_nxge_t nxgep)359489282175SSantwona Behera static boolean_t nxge_is_nlp2020_phy(p_nxge_t nxgep)
359589282175SSantwona Behera {
359689282175SSantwona Behera 	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
359789282175SSantwona Behera 	uint32_t	pcs_id = 0;
359889282175SSantwona Behera 	uint32_t	pma_pmd_id = 0;
359989282175SSantwona Behera 	uint8_t		xcvr_addr =  nxgep->nxge_hw_p->xcvr_addr[portn];
360089282175SSantwona Behera 
360189282175SSantwona Behera 	pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, xcvr_addr);
360289282175SSantwona Behera 	pcs_id = nxge_get_cl45_pcs_id(nxgep, xcvr_addr);
360389282175SSantwona Behera 
360489282175SSantwona Behera 	if (((pma_pmd_id & NLP2020_DEV_ID_MASK) == NLP2020_DEV_ID) ||
360589282175SSantwona Behera 	    ((pcs_id & NLP2020_DEV_ID_MASK) == NLP2020_DEV_ID)) {
360689282175SSantwona Behera 		return (B_TRUE);
360789282175SSantwona Behera 	} else {
360889282175SSantwona Behera 		return (B_FALSE);
360989282175SSantwona Behera 	}
361089282175SSantwona Behera }
361189282175SSantwona Behera 
nxge_get_nlp2020_connector_type(p_nxge_t nxgep)361289282175SSantwona Behera static uint8_t nxge_get_nlp2020_connector_type(p_nxge_t nxgep)
361389282175SSantwona Behera {
361489282175SSantwona Behera 	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
361589282175SSantwona Behera 	uint8_t xcvr_addr =  nxgep->nxge_hw_p->xcvr_addr[portn];
361689282175SSantwona Behera 	uint8_t	connector = 0;
361789282175SSantwona Behera 
361889282175SSantwona Behera 	(void) nxge_nlp2020_i2c_read(nxgep, xcvr_addr, NLP2020_XCVR_I2C_ADDR,
361989282175SSantwona Behera 	    QSFP_MSA_CONN_REG, &connector);
362089282175SSantwona Behera 
362189282175SSantwona Behera 	return (connector);
362289282175SSantwona Behera }
362389282175SSantwona Behera 
nxge_set_nlp2020_param(p_nxge_t nxgep)362489282175SSantwona Behera static nxge_status_t nxge_set_nlp2020_param(p_nxge_t nxgep)
362589282175SSantwona Behera {
362689282175SSantwona Behera 	uint8_t connector = 0;
362789282175SSantwona Behera 
362889282175SSantwona Behera 	connector = nxge_get_nlp2020_connector_type(nxgep);
362989282175SSantwona Behera 
363089282175SSantwona Behera 	switch (connector) {
363189282175SSantwona Behera 	case SFPP_FIBER:
363289282175SSantwona Behera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
363389282175SSantwona Behera 		    "nxge_set_nlp2020_param: SFPP_FIBER detected"));
363489282175SSantwona Behera 		nxgep->mac.portmode = PORT_10G_FIBER;
363589282175SSantwona Behera 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
363689282175SSantwona Behera 		break;
363789282175SSantwona Behera 	case QSFP_FIBER:
363889282175SSantwona Behera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
363989282175SSantwona Behera 		    "nxge_set_nlp2020_param: QSFP_FIBER detected"));
364089282175SSantwona Behera 		nxgep->mac.portmode = PORT_10G_FIBER;
364189282175SSantwona Behera 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
364289282175SSantwona Behera 		break;
364389282175SSantwona Behera 	case QSFP_COPPER_TWINAX:
364489282175SSantwona Behera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
364589282175SSantwona Behera 		    "nxge_set_nlp2020_param: QSFP_COPPER_TWINAX/"
364689282175SSantwona Behera 		    "SFPP_COPPER_TWINAX detected"));
364789282175SSantwona Behera 		nxgep->mac.portmode = PORT_10G_COPPER;
364889282175SSantwona Behera 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
364989282175SSantwona Behera 		break;
365089282175SSantwona Behera 	default:
365189282175SSantwona Behera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
365289282175SSantwona Behera 		    "nxge_set_nlp2020_param: Unknown type [0x%x] detected"
365389282175SSantwona Behera 		    "...setting to QSFP_FIBER",
365489282175SSantwona Behera 		    connector));
365589282175SSantwona Behera 		nxgep->mac.portmode = PORT_10G_FIBER;
365689282175SSantwona Behera 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
365789282175SSantwona Behera 		break;
365889282175SSantwona Behera 	}
365989282175SSantwona Behera 
366089282175SSantwona Behera 	return (NXGE_OK);
366189282175SSantwona Behera }
366289282175SSantwona Behera 
366352cdd236Ssbehera #define	CHK_STAT(x)	status = (x); if (status != NXGE_OK) goto fail
366452cdd236Ssbehera 
366552cdd236Ssbehera #define	MRVL88X2011_RD(nxgep, port, d, r, p) \
366652cdd236Ssbehera 	CHK_STAT(nxge_mdio_read(nxgep, port, d, r, p))
366752cdd236Ssbehera 
366852cdd236Ssbehera #define	MRVL88X2011_WR(nxgep, port, d, r, p) \
366952cdd236Ssbehera 	CHK_STAT(nxge_mdio_write(nxgep, port, d, r, p))
367052cdd236Ssbehera 
367152cdd236Ssbehera 
367252cdd236Ssbehera static void
nxge_mrvl88x2011_led_blink_rate(p_nxge_t nxgep,uint16_t rate)367352cdd236Ssbehera nxge_mrvl88x2011_led_blink_rate(p_nxge_t nxgep, uint16_t rate)
367452cdd236Ssbehera {
367552cdd236Ssbehera 	uint16_t	value;
367652cdd236Ssbehera 	uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn;
367752cdd236Ssbehera 
367852cdd236Ssbehera 	if (nxge_mdio_read(nxgep, phy, MRVL_88X2011_USER_DEV2_ADDR,
367952cdd236Ssbehera 	    MRVL_88X2011_LED_BLINK_CTL, &value) == NXGE_OK) {
368052cdd236Ssbehera 		value &= ~MRVL_88X2011_LED_BLK_MASK;
368152cdd236Ssbehera 		value |= (rate << MRVL_88X2011_LED_BLK_SHIFT);
368252cdd236Ssbehera 		(void) nxge_mdio_write(nxgep, phy,
368352cdd236Ssbehera 		    MRVL_88X2011_USER_DEV2_ADDR, MRVL_88X2011_LED_BLINK_CTL,
368452cdd236Ssbehera 		    value);
368552cdd236Ssbehera 	}
368652cdd236Ssbehera }
368752cdd236Ssbehera 
368852cdd236Ssbehera static nxge_status_t
nxge_mrvl88x2011_setup_lb(p_nxge_t nxgep)368952cdd236Ssbehera nxge_mrvl88x2011_setup_lb(p_nxge_t nxgep)
369052cdd236Ssbehera {
369152cdd236Ssbehera 	nxge_status_t	status;
369252cdd236Ssbehera 	pcs_control_t	pcs_ctl;
369352cdd236Ssbehera 	uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn;
369452cdd236Ssbehera 
369552cdd236Ssbehera 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
369652cdd236Ssbehera 	    MRVL_88X2011_PMA_PMD_CTL_1, &pcs_ctl.value);
369752cdd236Ssbehera 
369852cdd236Ssbehera 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
369952cdd236Ssbehera 		pcs_ctl.bits.loopback = 1;
370052cdd236Ssbehera 	else
370152cdd236Ssbehera 		pcs_ctl.bits.loopback = 0;
370252cdd236Ssbehera 
370352cdd236Ssbehera 	MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
370452cdd236Ssbehera 	    MRVL_88X2011_PMA_PMD_CTL_1, pcs_ctl.value);
370552cdd236Ssbehera 
370652cdd236Ssbehera fail:
370752cdd236Ssbehera 	return (status);
370852cdd236Ssbehera }
370952cdd236Ssbehera 
371052cdd236Ssbehera 
371152cdd236Ssbehera static void
nxge_mrvl88x2011_led(p_nxge_t nxgep,uint16_t val)371252cdd236Ssbehera nxge_mrvl88x2011_led(p_nxge_t nxgep,  uint16_t val)
371352cdd236Ssbehera {
371452cdd236Ssbehera 	uint16_t	val2;
371552cdd236Ssbehera 	uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn;
371652cdd236Ssbehera 
371752cdd236Ssbehera 	val2 = MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, val);
371852cdd236Ssbehera 	val2 &= ~MRVL_88X2011_LED(MRVL_88X2011_LED_ACT,
371952cdd236Ssbehera 	    MRVL_88X2011_LED_CTL_MASK);
372052cdd236Ssbehera 	val2 |= MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, val);
372152cdd236Ssbehera 
372252cdd236Ssbehera 	if (nxge_mdio_write(nxgep, phy, MRVL_88X2011_USER_DEV2_ADDR,
372352cdd236Ssbehera 	    MRVL_88X2011_LED_8_TO_11_CTL, val2) != NXGE_OK) {
372452cdd236Ssbehera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
372552cdd236Ssbehera 		    "nxge_mrvl88x2011_led: nxge_mdio_write failed!!"));
372652cdd236Ssbehera 	}
372752cdd236Ssbehera }
372852cdd236Ssbehera 
372952cdd236Ssbehera 
373052cdd236Ssbehera static nxge_status_t
nxge_mrvl88x2011_xcvr_init(p_nxge_t nxgep)373152cdd236Ssbehera nxge_mrvl88x2011_xcvr_init(p_nxge_t nxgep)
373252cdd236Ssbehera {
373352cdd236Ssbehera 	uint8_t		phy;
373452cdd236Ssbehera 	nxge_status_t	status;
373552cdd236Ssbehera 	uint16_t	clk;
373652cdd236Ssbehera 
373752cdd236Ssbehera 	phy = nxgep->statsp->mac_stats.xcvr_portn;
373852cdd236Ssbehera 
373952cdd236Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
374052cdd236Ssbehera 	    "==> nxge_mrvl88x2011_xcvr_init: port<%d> addr<0x%x>",
374152cdd236Ssbehera 	    nxgep->mac.portnum, phy));
374252cdd236Ssbehera 
374352cdd236Ssbehera 	/* Set LED functions	*/
374452cdd236Ssbehera 	nxge_mrvl88x2011_led_blink_rate(nxgep, MRVL_88X2011_LED_BLK134MS);
374552cdd236Ssbehera 	/* PCS activity */
374652cdd236Ssbehera 	nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_ACT);
374752cdd236Ssbehera 
374852cdd236Ssbehera 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
374952cdd236Ssbehera 	    MRVL_88X2011_GEN_CTL, &clk);
375052cdd236Ssbehera 	clk |= MRVL_88X2011_ENA_XFPREFCLK;
375152cdd236Ssbehera 	MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
375252cdd236Ssbehera 	    MRVL_88X2011_GEN_CTL, clk);
375352cdd236Ssbehera 
375452cdd236Ssbehera 	/* Set internal loopback mode if necessary */
375552cdd236Ssbehera 
375652cdd236Ssbehera 	CHK_STAT(nxge_mrvl88x2011_setup_lb(nxgep));
375752cdd236Ssbehera 
375852cdd236Ssbehera 	/* Enable PMD */
375952cdd236Ssbehera 	MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR,
376052cdd236Ssbehera 	    MRVL_88X2011_10G_PMD_TX_DIS, MRVL_88X2011_ENA_PMDTX);
376152cdd236Ssbehera 
376252cdd236Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, " nxge_mrvl88x2011_reset: OK"));
376352cdd236Ssbehera 
376452cdd236Ssbehera fail:
376552cdd236Ssbehera 	return (status);
376652cdd236Ssbehera }
376752cdd236Ssbehera 
376852cdd236Ssbehera 
376952cdd236Ssbehera 
37702d17280bSsbehera /* Initialize the 10G Transceiver */
37712d17280bSsbehera 
37722d17280bSsbehera static nxge_status_t
nxge_10G_xcvr_init(p_nxge_t nxgep)37732d17280bSsbehera nxge_10G_xcvr_init(p_nxge_t nxgep)
37742d17280bSsbehera {
37752d17280bSsbehera 	p_nxge_stats_t		statsp;
37761bd6825cSml 	p_nxge_param_t		param_arr = nxgep->param_arr;
37772d17280bSsbehera 	nxge_status_t		status = NXGE_OK;
37782d17280bSsbehera #ifdef	NXGE_DEBUG
37792d17280bSsbehera 	uint8_t			portn = nxgep->mac.portnum;
37802d17280bSsbehera #endif
37812d17280bSsbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
37822d17280bSsbehera 	    portn));
37832d17280bSsbehera 
37842d17280bSsbehera 	statsp = nxgep->statsp;
37852d17280bSsbehera 
37861c7408c9Stc 	/* Disable Link LEDs, with or without PHY */
37871c7408c9Stc 	if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
37882d17280bSsbehera 		goto done;
37892d17280bSsbehera 
37901c7408c9Stc 	/* Skip MDIO, if PHY absent */
37911c7408c9Stc 	if (nxgep->mac.portmode == PORT_10G_SERDES || nxgep->phy_absent) {
37921c7408c9Stc 		goto done;
37931c7408c9Stc 	}
37942d17280bSsbehera 
37952d17280bSsbehera 	/* Set Clause 45 */
37962d17280bSsbehera 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
37972d17280bSsbehera 
37982d17280bSsbehera 	switch (nxgep->chip_id) {
37992d17280bSsbehera 	case BCM8704_CHIP_ID:
380000161856Syc 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
38012d17280bSsbehera 		    "Chip ID 8704 [0x%x] for 10G xcvr", nxgep->chip_id));
38022d17280bSsbehera 		status = nxge_BCM8704_xcvr_init(nxgep);
38032d17280bSsbehera 		break;
38042d17280bSsbehera 	case BCM8706_CHIP_ID:
380500161856Syc 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
38062d17280bSsbehera 		    "Chip ID 8706 [0x%x] for 10G xcvr", nxgep->chip_id));
38072d17280bSsbehera 		status = nxge_BCM8706_xcvr_init(nxgep);
38082d17280bSsbehera 		break;
380952cdd236Ssbehera 	case MRVL88X201X_CHIP_ID:
381000161856Syc 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
381189282175SSantwona Behera 		    "Chip ID MRVL [0x%x] for 10G xcvr", nxgep->chip_id));
381252cdd236Ssbehera 		status = nxge_mrvl88x2011_xcvr_init(nxgep);
381352cdd236Ssbehera 		break;
381489282175SSantwona Behera 	case NLP2020_CHIP_ID:
381589282175SSantwona Behera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
381689282175SSantwona Behera 		    "Chip ID NL2020 [0x%x] for 10G xcvr", nxgep->chip_id));
381789282175SSantwona Behera 		status = nxge_nlp2020_xcvr_init(nxgep);
381889282175SSantwona Behera 		break;
38192d17280bSsbehera 	default:
38202d17280bSsbehera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_xcvr_init: "
38212d17280bSsbehera 		    "Unknown chip ID 0x%x for 10G xcvr addr[%d]",
38222d17280bSsbehera 		    nxgep->chip_id, nxgep->statsp->mac_stats.xcvr_portn));
38232d17280bSsbehera 		goto fail;
38242d17280bSsbehera 	}
38252d17280bSsbehera 
38262d17280bSsbehera 	if (status != NXGE_OK) {
38272d17280bSsbehera 		goto fail;
38282d17280bSsbehera 	}
38292e59129aSraghus done:
383059ac0c16Sdavemq 	statsp->mac_stats.cap_10gfdx = 1;
383159ac0c16Sdavemq 	statsp->mac_stats.lp_cap_10gfdx = 1;
38321bd6825cSml 	statsp->mac_stats.adv_cap_asmpause =
38331bd6825cSml 	    param_arr[param_anar_asmpause].value;
38341bd6825cSml 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
383544961713Sgirish 
383659ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
383759ac0c16Sdavemq 	    portn));
383859ac0c16Sdavemq 	return (NXGE_OK);
383944961713Sgirish 
384059ac0c16Sdavemq fail:
38412d17280bSsbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
384259ac0c16Sdavemq 	    "nxge_10G_xcvr_init: failed to initialize transceiver for "
38432d17280bSsbehera 	    "port<%d>", nxgep->mac.portnum));
38442d17280bSsbehera 	return (NXGE_ERROR);
384559ac0c16Sdavemq }
384644961713Sgirish 
384759ac0c16Sdavemq /* Initialize the 1G copper (BCM 5464) Transceiver */
384844961713Sgirish 
384959ac0c16Sdavemq static nxge_status_t
nxge_1G_xcvr_init(p_nxge_t nxgep)385059ac0c16Sdavemq nxge_1G_xcvr_init(p_nxge_t nxgep)
385159ac0c16Sdavemq {
385259ac0c16Sdavemq 	p_nxge_param_t		param_arr = nxgep->param_arr;
385359ac0c16Sdavemq 	p_nxge_stats_t		statsp = nxgep->statsp;
385459ac0c16Sdavemq 	nxge_status_t		status = NXGE_OK;
385544961713Sgirish 
38562e59129aSraghus 	if (nxgep->mac.portmode == PORT_1G_SERDES) {
38572e59129aSraghus 		statsp->mac_stats.cap_1000fdx =
38582e59129aSraghus 		    param_arr[param_anar_1000fdx].value;
38592e59129aSraghus 		goto done;
38602e59129aSraghus 	}
38612e59129aSraghus 
386259ac0c16Sdavemq 	/* Set Clause 22 */
386359ac0c16Sdavemq 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE);
386444961713Sgirish 
386559ac0c16Sdavemq 	/* Set capability flags */
386659ac0c16Sdavemq 	statsp->mac_stats.cap_1000fdx = param_arr[param_anar_1000fdx].value;
38672e59129aSraghus 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
38682e59129aSraghus 	    (nxgep->mac.portmode == PORT_1G_FIBER)) {
38692e59129aSraghus 		statsp->mac_stats.cap_100fdx =
38702e59129aSraghus 		    param_arr[param_anar_100fdx].value;
38712e59129aSraghus 		statsp->mac_stats.cap_10fdx =
38722e59129aSraghus 		    param_arr[param_anar_10fdx].value;
38732e59129aSraghus 	}
387444961713Sgirish 
387559ac0c16Sdavemq 	status = nxge_mii_xcvr_init(nxgep);
38762e59129aSraghus done:
387759ac0c16Sdavemq 	return (status);
387859ac0c16Sdavemq }
387959ac0c16Sdavemq 
388000161856Syc /*
388100161856Syc  * Although the Teranetics copper transceiver (TN1010) does not need
388200161856Syc  * to be initialized by the driver for passing packets, this funtion
388300161856Syc  * initializes the members of nxgep->statsp->mac_stats struct for
388400161856Syc  * kstat based on the value of nxgep->statsp->ports_stats.lb_mode.
388500161856Syc  * It also configures the TN1010 for PHY loopback to support SunVTS.
388600161856Syc  *
388700161856Syc  * TN1010 only has the option to disable advertisement for the 10G
388800161856Syc  * mode. So we can set it to either Dual Mode or 1G Only mode but
388900161856Syc  * can't set it to 10G Only mode.
389000161856Syc  *
389100161856Syc  * ndd -set command can set the following 6 speed/duplex related parameters.
389200161856Syc  *
389300161856Syc  * ----------------------------------------------------------------
389400161856Syc  * ndd -set /dev/nxgeX param n		kstat nxge:X | grep param
389500161856Syc  * ----------------------------------------------------------------
389600161856Syc  * adv_autoneg_cap		kstat nxge:1 | grep adv_cap_autoneg
389700161856Syc  * adv_10gfdx_cap
389800161856Syc  * adv_1000fdx_cap		kstat nxge:1 | grep adv_cap_1000fdx
389900161856Syc  * adv_100fdx_cap		kstat nxge:1 | grep adv_cap_100fdx
390000161856Syc  * adv_10fdx_cap		kstat nxge:1 | grep adv_cap_10fdx
390100161856Syc  * adv_pause_cap		kstat nxge:1 | grep adv_cap_pause
390200161856Syc  * ----------------------------------------------------------------
390300161856Syc  */
390400161856Syc static nxge_status_t
nxge_tn1010_xcvr_init(p_nxge_t nxgep)390500161856Syc nxge_tn1010_xcvr_init(p_nxge_t nxgep)
390600161856Syc {
390700161856Syc 	p_nxge_param_t		param_arr;
390800161856Syc 	p_nxge_stats_t		statsp;
390900161856Syc 	tn1010_pcs_ctrl_t	tn1010_pcs_ctrl;
391000161856Syc 	uint16_t		speed;
391100161856Syc 	uint8_t			phy_port_addr;
391200161856Syc 	uint8_t			portn = NXGE_GET_PORT_NUM(nxgep->function_num);
391300161856Syc 	int			status = NXGE_OK;
391400161856Syc 
391500161856Syc 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_1G_tn1010_xcvr_init"));
391600161856Syc 
391700161856Syc 	param_arr	= nxgep->param_arr;
391800161856Syc 	statsp		= nxgep->statsp;
391900161856Syc 
392000161856Syc 	/*
392100161856Syc 	 * Initialize the xcvr statistics which are NOT controlled by ndd
392200161856Syc 	 */
392300161856Syc 	statsp->mac_stats.cap_autoneg  = 1; /* TN1010 autoneg is always on */
392400161856Syc 	statsp->mac_stats.cap_100T4    = 0;
392500161856Syc 
392600161856Syc 	/*
392700161856Syc 	 * Read the TN1010 link speed and initialize capabilities kstat. Note
392800161856Syc 	 * that function nxge_check_tn1010_link repeatedly invoked by the
392900161856Syc 	 * timer will update link_speed real time.
393000161856Syc 	 */
393100161856Syc 	if (nxge_get_tn1010_speed(nxgep,  &speed) != NXGE_OK) {
393200161856Syc 		goto fail;
393300161856Syc 	}
393400161856Syc 	if (speed == TN1010_SPEED_1G) {
393500161856Syc 		statsp->mac_stats.cap_10gfdx = 0;
393600161856Syc 	} else {
393700161856Syc 		statsp->mac_stats.cap_10gfdx = 1;
393800161856Syc 	}
393900161856Syc 
394000161856Syc 	/* Whether we are in 1G or 10G mode, we always have the 1G capability */
394100161856Syc 	statsp->mac_stats.cap_1000fdx  = 1;
394200161856Syc 
394300161856Syc 	/* TN1010 is not able to operate in the following states */
394400161856Syc 	statsp->mac_stats.cap_1000hdx  = 0;
394500161856Syc 	statsp->mac_stats.cap_100fdx   = 0;
394600161856Syc 	statsp->mac_stats.cap_100hdx   = 0;
394700161856Syc 	statsp->mac_stats.cap_10fdx    = 0;
394800161856Syc 	statsp->mac_stats.cap_10hdx    = 0;
394900161856Syc 
395000161856Syc 	/* param_anar_pause can be modified by ndd -set */
395100161856Syc 	statsp->mac_stats.cap_pause    = param_arr[param_anar_pause].value;
395200161856Syc 
395300161856Syc 	/*
395400161856Syc 	 * The following 4 lines actually overwrites what ever the ndd command
395500161856Syc 	 * has set. For example, by command
395691f84442SToomas Soome 	 *	ndd -set /dev/nxge1 adv_autoneg_cap n (n = 0 or 1)
395700161856Syc 	 * we could set param_arr[param_autoneg].value to n.  However, because
395800161856Syc 	 * here we assign constants to these parameters, whatever we set with
395900161856Syc 	 * the "ndd -set" command will be replaced. So command
396000161856Syc 	 *	kstat nxge:X | grep param
396100161856Syc 	 * will always show those constant values.  In other words, the
396200161856Syc 	 * "ndd -set" command can NOT change the values of these 4 parameters
396300161856Syc 	 * even though the command appears to be successful.
396400161856Syc 	 *
396500161856Syc 	 * Note: TN1010 auto negotiation is always enabled.
396600161856Syc 	 */
396700161856Syc 	statsp->mac_stats.adv_cap_autoneg
396800161856Syc 	    = param_arr[param_autoneg].value = 1;
396900161856Syc 	statsp->mac_stats.adv_cap_1000fdx
397000161856Syc 	    = param_arr[param_anar_1000fdx].value = 1;
397100161856Syc 	statsp->mac_stats.adv_cap_100fdx
397200161856Syc 	    = param_arr[param_anar_100fdx].value = 0;
397300161856Syc 	statsp->mac_stats.adv_cap_10fdx
397400161856Syc 	    = param_arr[param_anar_10fdx].value = 0;
397500161856Syc 
397600161856Syc 	/*
397700161856Syc 	 * The following 4 ndd params have type NXGE_PARAM_MAC_DONT_SHOW as
397800161856Syc 	 * defined in nxge_param_arr[], therefore they are not seen by the
397900161856Syc 	 * "ndd -get" command and can not be changed by ndd.  We just set
398000161856Syc 	 * them (both ndd param and kstat values) to constant 0 because TN1010
398100161856Syc 	 * does not support those speeds.
398200161856Syc 	 */
398300161856Syc 	statsp->mac_stats.adv_cap_100T4
398400161856Syc 	    = param_arr[param_anar_100T4].value = 0;
398500161856Syc 	statsp->mac_stats.adv_cap_1000hdx
398600161856Syc 	    = param_arr[param_anar_1000hdx].value = 0;
398700161856Syc 	statsp->mac_stats.adv_cap_100hdx
398800161856Syc 	    = param_arr[param_anar_100hdx].value = 0;
398900161856Syc 	statsp->mac_stats.adv_cap_10hdx
399000161856Syc 	    = param_arr[param_anar_10hdx].value = 0;
399100161856Syc 
399200161856Syc 	/*
399300161856Syc 	 * adv_cap_pause has type NXGE_PARAM_MAC_RW, so it can be modified
399400161856Syc 	 * by ndd
399500161856Syc 	 */
399600161856Syc 	statsp->mac_stats.adv_cap_pause    = param_arr[param_anar_pause].value;
399700161856Syc 
399800161856Syc 	/*
399900161856Syc 	 * nxge_param_arr[] defines the adv_cap_asmpause with type
400000161856Syc 	 * NXGE_PARAM_DONT_SHOW, therefore they are NOT seen by the
400100161856Syc 	 * "ndd -get" command and can not be changed by ndd. Here we do not
400200161856Syc 	 * assign a constant to it so the default value defined in
400300161856Syc 	 * nxge_param_arr[] will be used to set the parameter and
400400161856Syc 	 * will be shown by the kstat.
400500161856Syc 	 */
400600161856Syc 	statsp->mac_stats.adv_cap_asmpause
400700161856Syc 	    = param_arr[param_anar_asmpause].value;
400800161856Syc 
400900161856Syc 	/*
401000161856Syc 	 * Initialize the link statistics.
401100161856Syc 	 */
401200161856Syc 	statsp->mac_stats.link_T4 = 0;
401300161856Syc 	statsp->mac_stats.link_asmpause = 0;
401400161856Syc 	statsp->mac_stats.link_pause = 0;
401500161856Syc 	if (speed == TN1010_SPEED_1G) {
401600161856Syc 		statsp->mac_stats.link_speed = 1000;
401700161856Syc 		statsp->mac_stats.link_duplex = 2;	/* Full duplex */
401800161856Syc 		statsp->mac_stats.link_up = 1;
401900161856Syc 	} else {
402000161856Syc 		statsp->mac_stats.link_speed = 10000;
402100161856Syc 		statsp->mac_stats.link_duplex = 2;
402200161856Syc 		statsp->mac_stats.link_up = 1;
402300161856Syc 	}
402400161856Syc 
402500161856Syc 	/*
402600161856Syc 	 * Because TN1010 does not have a link partner register, to
402700161856Syc 	 * figure out the link partner's capabilities is tricky. Here we
402800161856Syc 	 * just set the kstat based on our knowledge about the partner
402900161856Syc 	 * (The partner must support auto-neg because auto-negotiation
403000161856Syc 	 * has completed, it must support 1G or 10G because that is the
403100161856Syc 	 * negotiated speed we are using.)
403200161856Syc 	 *
403300161856Syc 	 * Note: Current kstat does not show lp_cap_10gfdx and
403400161856Syc 	 *	lp_cap_10ghdx.
403500161856Syc 	 */
403600161856Syc 	if (speed == TN1010_SPEED_1G) {
403700161856Syc 		statsp->mac_stats.lp_cap_1000fdx  = 1;
403800161856Syc 		statsp->mac_stats.lp_cap_10gfdx   = 0;
403900161856Syc 	} else {
404000161856Syc 		statsp->mac_stats.lp_cap_1000fdx  = 0;
404100161856Syc 		statsp->mac_stats.lp_cap_10gfdx   = 1;
404200161856Syc 	}
404300161856Syc 	statsp->mac_stats.lp_cap_10ghdx   = 0;
404400161856Syc 	statsp->mac_stats.lp_cap_1000hdx  = 0;
404500161856Syc 	statsp->mac_stats.lp_cap_100fdx   = 0;
404600161856Syc 	statsp->mac_stats.lp_cap_100hdx   = 0;
404700161856Syc 	statsp->mac_stats.lp_cap_10fdx    = 0;
404800161856Syc 	statsp->mac_stats.lp_cap_10hdx    = 0;
404900161856Syc 	statsp->mac_stats.lp_cap_10gfdx   = 0;
405000161856Syc 	statsp->mac_stats.lp_cap_10ghdx   = 0;
405100161856Syc 	statsp->mac_stats.lp_cap_100T4    = 0;
405200161856Syc 	statsp->mac_stats.lp_cap_autoneg  = 1;
405300161856Syc 	statsp->mac_stats.lp_cap_asmpause = 0;
405400161856Syc 	statsp->mac_stats.lp_cap_pause    = 0;
405500161856Syc 
405600161856Syc 	/* Handle PHY loopback for SunVTS loopback test */
405700161856Syc 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
405800161856Syc 	phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
405900161856Syc 
406000161856Syc 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
406100161856Syc 	    TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG,
406200161856Syc 	    &tn1010_pcs_ctrl.value)) != NXGE_OK) {
406300161856Syc 		goto fail;
406400161856Syc 	}
406500161856Syc 	if ((statsp->port_stats.lb_mode == nxge_lb_phy1000) ||
406600161856Syc 	    (statsp->port_stats.lb_mode == nxge_lb_phy10g)) {
406700161856Syc 		tn1010_pcs_ctrl.bits.loopback = 1;
406800161856Syc 	} else {
406900161856Syc 		tn1010_pcs_ctrl.bits.loopback = 0;
407000161856Syc 	}
407100161856Syc 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
407200161856Syc 	    TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG,
407300161856Syc 	    tn1010_pcs_ctrl.value)) != NXGE_OK) {
407400161856Syc 		goto fail;
407500161856Syc 	}
407600161856Syc 
407700161856Syc 	statsp->mac_stats.xcvr_inits++;
407800161856Syc 
407900161856Syc 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
408000161856Syc 	    "<== nxge_1G_tn1010_xcvr_init status 0x%x", status));
408100161856Syc 	return (status);
408200161856Syc fail:
408300161856Syc 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
408400161856Syc 	    "<== nxge_1G_tn1010_xcvr_init status 0x%x", status));
408500161856Syc 	return (status);
408600161856Syc }
408700161856Syc 
408859ac0c16Sdavemq /* Initialize transceiver */
408959ac0c16Sdavemq 
409059ac0c16Sdavemq nxge_status_t
nxge_xcvr_init(p_nxge_t nxgep)409159ac0c16Sdavemq nxge_xcvr_init(p_nxge_t nxgep)
409259ac0c16Sdavemq {
409359ac0c16Sdavemq 	p_nxge_stats_t		statsp;
409459ac0c16Sdavemq #ifdef	NXGE_DEBUG
409559ac0c16Sdavemq 	uint8_t			portn;
409644961713Sgirish #endif
409744961713Sgirish 
409859ac0c16Sdavemq 	nxge_status_t		status = NXGE_OK;
409959ac0c16Sdavemq #ifdef	NXGE_DEBUG
410059ac0c16Sdavemq 	portn = nxgep->mac.portnum;
410159ac0c16Sdavemq #endif
410259ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn));
410359ac0c16Sdavemq 	statsp = nxgep->statsp;
410444961713Sgirish 
410559ac0c16Sdavemq 	/*
410600161856Syc 	 * Initialize the xcvr statistics. nxgep->xcvr.xcvr_init will
410700161856Syc 	 * modify mac_stats.
410859ac0c16Sdavemq 	 */
410959ac0c16Sdavemq 	statsp->mac_stats.cap_autoneg = 0;
411059ac0c16Sdavemq 	statsp->mac_stats.cap_100T4 = 0;
411159ac0c16Sdavemq 	statsp->mac_stats.cap_100fdx = 0;
411259ac0c16Sdavemq 	statsp->mac_stats.cap_100hdx = 0;
411359ac0c16Sdavemq 	statsp->mac_stats.cap_10fdx = 0;
411459ac0c16Sdavemq 	statsp->mac_stats.cap_10hdx = 0;
411559ac0c16Sdavemq 	statsp->mac_stats.cap_asmpause = 0;
411659ac0c16Sdavemq 	statsp->mac_stats.cap_pause = 0;
411759ac0c16Sdavemq 	statsp->mac_stats.cap_1000fdx = 0;
411859ac0c16Sdavemq 	statsp->mac_stats.cap_1000hdx = 0;
411959ac0c16Sdavemq 	statsp->mac_stats.cap_10gfdx = 0;
412059ac0c16Sdavemq 	statsp->mac_stats.cap_10ghdx = 0;
412159ac0c16Sdavemq 
412259ac0c16Sdavemq 	/*
412359ac0c16Sdavemq 	 * Initialize the link statistics.
412459ac0c16Sdavemq 	 */
412559ac0c16Sdavemq 	statsp->mac_stats.link_T4 = 0;
412659ac0c16Sdavemq 	statsp->mac_stats.link_asmpause = 0;
412759ac0c16Sdavemq 	statsp->mac_stats.link_pause = 0;
412844961713Sgirish 
412959ac0c16Sdavemq 	if (nxgep->xcvr.xcvr_init) {
413059ac0c16Sdavemq 		status = nxgep->xcvr.xcvr_init(nxgep);
413159ac0c16Sdavemq 		if (status != NXGE_OK)
413244961713Sgirish 			goto fail;
413359ac0c16Sdavemq 		statsp->mac_stats.xcvr_inits++;
413444961713Sgirish 	}
413544961713Sgirish 
413659ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>",
413759ac0c16Sdavemq 	    portn));
413844961713Sgirish 	return (NXGE_OK);
413944961713Sgirish 
414044961713Sgirish fail:
414144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
414259ac0c16Sdavemq 	    "nxge_xcvr_init: failed to initialize transceiver for port<%d>",
414359ac0c16Sdavemq 	    portn));
414444961713Sgirish 	return (status);
414544961713Sgirish }
414644961713Sgirish 
41472e59129aSraghus /* Look for transceiver type */
41482e59129aSraghus 
41492e59129aSraghus nxge_status_t
nxge_xcvr_find(p_nxge_t nxgep)41502e59129aSraghus nxge_xcvr_find(p_nxge_t nxgep)
41512e59129aSraghus {
4152d81011f0Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_find: port<%d>",
4153d81011f0Ssbehera 	    nxgep->mac.portnum));
41542e59129aSraghus 
41552e59129aSraghus 	if (nxge_get_xcvr_type(nxgep) != NXGE_OK)
41562e59129aSraghus 		return (NXGE_ERROR);
41572e59129aSraghus 
41582e59129aSraghus 	if (nxge_setup_xcvr_table(nxgep) != NXGE_OK)
41592e59129aSraghus 		return (NXGE_ERROR);
41602e59129aSraghus 
41612e59129aSraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xcvr_find: xcvr_inuse = %d",
41622e59129aSraghus 	    nxgep->statsp->mac_stats.xcvr_inuse));
41632e59129aSraghus 	return (NXGE_OK);
41642e59129aSraghus }
416544961713Sgirish 
416644961713Sgirish /* Initialize the TxMAC sub-block */
416744961713Sgirish 
416844961713Sgirish nxge_status_t
nxge_tx_mac_init(p_nxge_t nxgep)416944961713Sgirish nxge_tx_mac_init(p_nxge_t nxgep)
417044961713Sgirish {
417144961713Sgirish 	npi_attr_t		ap;
417244961713Sgirish 	uint8_t			portn;
417344961713Sgirish 	nxge_port_mode_t	portmode;
417444961713Sgirish 	nxge_port_t		portt;
417544961713Sgirish 	npi_handle_t		handle;
417644961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
417744961713Sgirish 
417844961713Sgirish 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
417944961713Sgirish 	portt    = nxgep->mac.porttype;
418044961713Sgirish 	handle   = nxgep->npi_handle;
418144961713Sgirish 	portmode = nxgep->mac.portmode;
418244961713Sgirish 
418344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>",
418452ccf843Smisaki 	    portn));
418544961713Sgirish 	/* Set Max and Min Frame Size */
41861bd6825cSml 	/*
41871bd6825cSml 	 * Use maxframesize to configure the hardware maxframe size
418800161856Syc 	 * and minframesize to configure the hardware minframe size.
41891bd6825cSml 	 */
41901bd6825cSml 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
41911bd6825cSml 	    "==> nxge_tx_mac_init: port<%d> "
41921bd6825cSml 	    "min framesize %d max framesize %d ",
41931bd6825cSml 	    nxgep->mac.minframesize,
41941bd6825cSml 	    nxgep->mac.maxframesize,
41951bd6825cSml 	    portn));
419644961713Sgirish 
41971bd6825cSml 	SET_MAC_ATTR2(handle, ap, portn,
41981bd6825cSml 	    MAC_PORT_FRAME_SIZE,
41991bd6825cSml 	    nxgep->mac.minframesize,
42001bd6825cSml 	    nxgep->mac.maxframesize,
42011bd6825cSml 	    rs);
420244961713Sgirish 	if (rs != NPI_SUCCESS)
420344961713Sgirish 		goto fail;
420444961713Sgirish 
420544961713Sgirish 	if (portt == PORT_TYPE_XMAC) {
420644961713Sgirish 		if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn,
420752ccf843Smisaki 		    0)) != NPI_SUCCESS)
420844961713Sgirish 			goto fail;
420944961713Sgirish 		nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS;
421044961713Sgirish 		if ((portmode == PORT_10G_FIBER) ||
42112e59129aSraghus 		    (portmode == PORT_10G_COPPER) ||
421200161856Syc 		    (portmode == PORT_10G_TN1010) ||
42131c7408c9Stc 		    (portmode == PORT_HSP_MODE) ||
42142e59129aSraghus 		    (portmode == PORT_10G_SERDES)) {
421544961713Sgirish 			SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG,
421652ccf843Smisaki 			    XGMII_IPG_12_15, rs);
421744961713Sgirish 			if (rs != NPI_SUCCESS)
421844961713Sgirish 				goto fail;
421944961713Sgirish 			nxgep->mac.ipg[0] = XGMII_IPG_12_15;
422044961713Sgirish 		} else {
422144961713Sgirish 			SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG,
422252ccf843Smisaki 			    MII_GMII_IPG_12, rs);
422344961713Sgirish 			if (rs != NPI_SUCCESS)
422444961713Sgirish 				goto fail;
422544961713Sgirish 			nxgep->mac.ipg[0] = MII_GMII_IPG_12;
422644961713Sgirish 		}
422744961713Sgirish 		if ((rs = npi_xmac_tx_config(handle, INIT, portn,
422852ccf843Smisaki 		    CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS)
422944961713Sgirish 			goto fail;
423044961713Sgirish 		nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX;
423144961713Sgirish 		nxgep->mac.maxburstsize = 0;	/* not programmable */
423244961713Sgirish 		nxgep->mac.ctrltype = 0;	/* not programmable */
423344961713Sgirish 		nxgep->mac.pa_size = 0;		/* not programmable */
423444961713Sgirish 
423544961713Sgirish 		if ((rs = npi_xmac_zap_tx_counters(handle, portn))
423652ccf843Smisaki 		    != NPI_SUCCESS)
423744961713Sgirish 			goto fail;
423844961713Sgirish 
423944961713Sgirish 	} else {
424044961713Sgirish 		if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn,
424152ccf843Smisaki 		    0)) != NPI_SUCCESS)
424244961713Sgirish 			goto fail;
424344961713Sgirish 		nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS;
424444961713Sgirish 
424544961713Sgirish 		SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808,
424652ccf843Smisaki 		    rs);
424744961713Sgirish 		if (rs != NPI_SUCCESS)
424844961713Sgirish 			goto fail;
424944961713Sgirish 		nxgep->mac.ctrltype = 0x8808;
425044961713Sgirish 
425144961713Sgirish 		SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs);
425244961713Sgirish 		if (rs != NPI_SUCCESS)
425344961713Sgirish 			goto fail;
425444961713Sgirish 		nxgep->mac.pa_size = 0x7;
425544961713Sgirish 
425644961713Sgirish 		if ((rs = npi_bmac_tx_config(handle, INIT, portn,
425752ccf843Smisaki 		    CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS)
425844961713Sgirish 			goto fail;
425944961713Sgirish 		nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX;
426044961713Sgirish 	}
426144961713Sgirish 
426244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>",
426352ccf843Smisaki 	    portn));
426444961713Sgirish 
426544961713Sgirish 	return (NXGE_OK);
426644961713Sgirish fail:
426744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
426852ccf843Smisaki 	    "nxge_tx_mac_init: failed to initialize port<%d> TXMAC", portn));
426944961713Sgirish 
427044961713Sgirish 	return (NXGE_ERROR | rs);
427144961713Sgirish }
427244961713Sgirish 
42730dc2366fSVenugopal Iyer static npi_status_t
nxge_rx_mac_mcast_hash_table(p_nxge_t nxgep)42740dc2366fSVenugopal Iyer nxge_rx_mac_mcast_hash_table(p_nxge_t nxgep)
42750dc2366fSVenugopal Iyer {
42760dc2366fSVenugopal Iyer 	uint32_t		i;
42770dc2366fSVenugopal Iyer 	uint16_t		hashtab_e;
42780dc2366fSVenugopal Iyer 	p_hash_filter_t		hash_filter;
42790dc2366fSVenugopal Iyer 	uint8_t			portn;
42800dc2366fSVenugopal Iyer 	npi_handle_t		handle;
42810dc2366fSVenugopal Iyer 	npi_status_t		rs = NPI_SUCCESS;
42820dc2366fSVenugopal Iyer 
42830dc2366fSVenugopal Iyer 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
42840dc2366fSVenugopal Iyer 	handle = nxgep->npi_handle;
42850dc2366fSVenugopal Iyer 
42860dc2366fSVenugopal Iyer 	/*
42870dc2366fSVenugopal Iyer 	 * Load the multicast hash filter bits.
42880dc2366fSVenugopal Iyer 	 */
42890dc2366fSVenugopal Iyer 	hash_filter = nxgep->hash_filter;
42900dc2366fSVenugopal Iyer 	for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) {
42910dc2366fSVenugopal Iyer 		if (hash_filter != NULL) {
42920dc2366fSVenugopal Iyer 			hashtab_e = (uint16_t)hash_filter->hash_filter_regs[
42930dc2366fSVenugopal Iyer 			    (NMCFILTER_REGS - 1) - i];
42940dc2366fSVenugopal Iyer 		} else {
42950dc2366fSVenugopal Iyer 			hashtab_e = 0;
42960dc2366fSVenugopal Iyer 		}
42970dc2366fSVenugopal Iyer 
42980dc2366fSVenugopal Iyer 		if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i,
42990dc2366fSVenugopal Iyer 		    (uint16_t *)&hashtab_e)) != NPI_SUCCESS)
43000dc2366fSVenugopal Iyer 			return (rs);
43010dc2366fSVenugopal Iyer 	}
4302678453a8Sspeer 
43030dc2366fSVenugopal Iyer 	return (NPI_SUCCESS);
43040dc2366fSVenugopal Iyer }
430544961713Sgirish 
43060dc2366fSVenugopal Iyer /*
43070dc2366fSVenugopal Iyer  * Initialize the RxMAC sub-block
43080dc2366fSVenugopal Iyer  */
430944961713Sgirish nxge_status_t
nxge_rx_mac_init(p_nxge_t nxgep)431044961713Sgirish nxge_rx_mac_init(p_nxge_t nxgep)
431144961713Sgirish {
431244961713Sgirish 	npi_attr_t		ap;
431344961713Sgirish 	nxge_port_t		portt;
431444961713Sgirish 	uint8_t			portn;
431544961713Sgirish 	npi_handle_t		handle;
431644961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
431791f84442SToomas Soome 	uint16_t		*addr16p;
431891f84442SToomas Soome 	uint16_t		addr0, addr1, addr2;
431944961713Sgirish 	xmac_rx_config_t	xconfig;
432044961713Sgirish 	bmac_rx_config_t	bconfig;
432144961713Sgirish 
432244961713Sgirish 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
432344961713Sgirish 
432444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n",
432552ccf843Smisaki 	    portn));
432644961713Sgirish 	handle = nxgep->npi_handle;
432744961713Sgirish 	portt = nxgep->mac.porttype;
432844961713Sgirish 
432944961713Sgirish 	addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet;
433044961713Sgirish 	addr0 = ntohs(addr16p[2]);
433144961713Sgirish 	addr1 = ntohs(addr16p[1]);
433244961713Sgirish 	addr2 = ntohs(addr16p[0]);
43330dc2366fSVenugopal Iyer 	SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR,
43340dc2366fSVenugopal Iyer 	    addr0, addr1, addr2, rs);
433544961713Sgirish 	if (rs != NPI_SUCCESS)
433644961713Sgirish 		goto fail;
433744961713Sgirish 	SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs);
433844961713Sgirish 	if (rs != NPI_SUCCESS)
433944961713Sgirish 		goto fail;
434044961713Sgirish 	SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs);
434144961713Sgirish 	if (rs != NPI_SUCCESS)
434244961713Sgirish 		goto fail;
434344961713Sgirish 
43440dc2366fSVenugopal Iyer 	rs = nxge_rx_mac_mcast_hash_table(nxgep);
43450dc2366fSVenugopal Iyer 	if (rs != NPI_SUCCESS)
43460dc2366fSVenugopal Iyer 		goto fail;
434744961713Sgirish 
434844961713Sgirish 	if (portt == PORT_TYPE_XMAC) {
434944961713Sgirish 		if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn,
435052ccf843Smisaki 		    0)) != NPI_SUCCESS)
435144961713Sgirish 			goto fail;
435244961713Sgirish 		nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS;
435344961713Sgirish 
435444961713Sgirish 		(void) nxge_fflp_init_hostinfo(nxgep);
435544961713Sgirish 
435644961713Sgirish 		xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK |
435752ccf843Smisaki 		    CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK &
435852ccf843Smisaki 		    ~CFG_XMAC_RX_STRIP_CRC;
435944961713Sgirish 
436044961713Sgirish 		if (nxgep->filter.all_phys_cnt != 0)
436144961713Sgirish 			xconfig |= CFG_XMAC_RX_PROMISCUOUS;
436244961713Sgirish 		if (nxgep->filter.all_multicast_cnt != 0)
436344961713Sgirish 			xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP;
436444961713Sgirish 
436544961713Sgirish 		xconfig |= CFG_XMAC_RX_HASH_FILTER;
436644961713Sgirish 
43670dc2366fSVenugopal Iyer 		if ((rs = npi_xmac_rx_config(handle, INIT,
43680dc2366fSVenugopal Iyer 		    portn, xconfig)) != NPI_SUCCESS)
436944961713Sgirish 			goto fail;
437044961713Sgirish 		nxgep->mac.rx_config = xconfig;
437144961713Sgirish 
43720dc2366fSVenugopal Iyer 		/*
43730dc2366fSVenugopal Iyer 		 * Comparison of mac unique address is always
43740dc2366fSVenugopal Iyer 		 * enabled on XMAC
43750dc2366fSVenugopal Iyer 		 */
437644961713Sgirish 		if ((rs = npi_xmac_zap_rx_counters(handle, portn))
437752ccf843Smisaki 		    != NPI_SUCCESS)
437844961713Sgirish 			goto fail;
437944961713Sgirish 	} else {
438044961713Sgirish 		if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn,
438152ccf843Smisaki 		    0) != NPI_SUCCESS)
438244961713Sgirish 			goto fail;
43830dc2366fSVenugopal Iyer 
438444961713Sgirish 		nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS;
438544961713Sgirish 
43860dc2366fSVenugopal Iyer 		(void) nxge_fflp_init_hostinfo(nxgep);
43870dc2366fSVenugopal Iyer 
4388a3c5bd6dSspeer 		bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX &
438952ccf843Smisaki 		    ~CFG_BMAC_RX_STRIP_CRC;
439044961713Sgirish 
439144961713Sgirish 		if (nxgep->filter.all_phys_cnt != 0)
439244961713Sgirish 			bconfig |= CFG_BMAC_RX_PROMISCUOUS;
439344961713Sgirish 		if (nxgep->filter.all_multicast_cnt != 0)
439444961713Sgirish 			bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP;
439544961713Sgirish 
439644961713Sgirish 		bconfig |= CFG_BMAC_RX_HASH_FILTER;
43970dc2366fSVenugopal Iyer 		if ((rs = npi_bmac_rx_config(handle, INIT,
43980dc2366fSVenugopal Iyer 		    portn, bconfig)) != NPI_SUCCESS)
439944961713Sgirish 			goto fail;
440044961713Sgirish 		nxgep->mac.rx_config = bconfig;
440144961713Sgirish 
44020dc2366fSVenugopal Iyer 		/*
44030dc2366fSVenugopal Iyer 		 * Always enable comparison of mac unique address
44040dc2366fSVenugopal Iyer 		 */
44050dc2366fSVenugopal Iyer 		if ((rs = npi_mac_altaddr_enable(handle,
44060dc2366fSVenugopal Iyer 		    portn, 0)) != NPI_SUCCESS)
440744961713Sgirish 			goto fail;
440844961713Sgirish 	}
440944961713Sgirish 
441044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n",
441152ccf843Smisaki 	    portn));
441244961713Sgirish 
441344961713Sgirish 	return (NXGE_OK);
441444961713Sgirish 
441544961713Sgirish fail:
441644961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
441752ccf843Smisaki 	    "nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC", portn));
441844961713Sgirish 
441944961713Sgirish 	return (NXGE_ERROR | rs);
442044961713Sgirish }
442144961713Sgirish 
442244961713Sgirish /* Enable TXMAC */
442344961713Sgirish 
442444961713Sgirish nxge_status_t
nxge_tx_mac_enable(p_nxge_t nxgep)442544961713Sgirish nxge_tx_mac_enable(p_nxge_t nxgep)
442644961713Sgirish {
442744961713Sgirish 	npi_handle_t	handle;
442844961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
442944961713Sgirish 	nxge_status_t	status = NXGE_OK;
443044961713Sgirish 
443144961713Sgirish 	handle = nxgep->npi_handle;
443244961713Sgirish 
443344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>",
443452ccf843Smisaki 	    nxgep->mac.portnum));
443544961713Sgirish 
443644961713Sgirish 	if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
443744961713Sgirish 		goto fail;
443844961713Sgirish 
443944961713Sgirish 	/* based on speed */
444044961713Sgirish 	nxgep->msg_min = ETHERMIN;
444144961713Sgirish 
444244961713Sgirish 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
444344961713Sgirish 		if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
444452ccf843Smisaki 		    CFG_XMAC_TX)) != NPI_SUCCESS)
444544961713Sgirish 			goto fail;
444644961713Sgirish 	} else {
444744961713Sgirish 		if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
444852ccf843Smisaki 		    CFG_BMAC_TX)) != NPI_SUCCESS)
444944961713Sgirish 			goto fail;
445044961713Sgirish 	}
445144961713Sgirish 
445244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>",
445352ccf843Smisaki 	    nxgep->mac.portnum));
445444961713Sgirish 
445544961713Sgirish 	return (NXGE_OK);
445644961713Sgirish fail:
445744961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
445852ccf843Smisaki 	    "nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC",
445952ccf843Smisaki 	    nxgep->mac.portnum));
446044961713Sgirish 	if (rs != NPI_SUCCESS)
446144961713Sgirish 		return (NXGE_ERROR | rs);
446244961713Sgirish 	else
446344961713Sgirish 		return (status);
446444961713Sgirish }
446544961713Sgirish 
446644961713Sgirish /* Disable TXMAC */
446744961713Sgirish 
446844961713Sgirish nxge_status_t
nxge_tx_mac_disable(p_nxge_t nxgep)446944961713Sgirish nxge_tx_mac_disable(p_nxge_t nxgep)
447044961713Sgirish {
447144961713Sgirish 	npi_handle_t	handle;
447244961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
447344961713Sgirish 
4474678453a8Sspeer 	if (isLDOMguest(nxgep))
4475678453a8Sspeer 		return (NXGE_OK);
4476678453a8Sspeer 
447744961713Sgirish 	handle = nxgep->npi_handle;
447844961713Sgirish 
447944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>",
448052ccf843Smisaki 	    nxgep->mac.portnum));
448144961713Sgirish 
448244961713Sgirish 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
448344961713Sgirish 		if ((rs = npi_xmac_tx_config(handle, DISABLE,
448452ccf843Smisaki 		    nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS)
448544961713Sgirish 			goto fail;
448644961713Sgirish 	} else {
448744961713Sgirish 		if ((rs = npi_bmac_tx_config(handle, DISABLE,
448852ccf843Smisaki 		    nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS)
448944961713Sgirish 			goto fail;
449044961713Sgirish 	}
449144961713Sgirish 
449244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>",
449352ccf843Smisaki 	    nxgep->mac.portnum));
449444961713Sgirish 	return (NXGE_OK);
449544961713Sgirish fail:
449644961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
449752ccf843Smisaki 	    "nxge_tx_mac_disable: Failed to disable port<%d> TxMAC",
449852ccf843Smisaki 	    nxgep->mac.portnum));
449944961713Sgirish 	return (NXGE_ERROR | rs);
450044961713Sgirish }
450144961713Sgirish 
450244961713Sgirish /* Enable RXMAC */
450344961713Sgirish 
450444961713Sgirish nxge_status_t
nxge_rx_mac_enable(p_nxge_t nxgep)450544961713Sgirish nxge_rx_mac_enable(p_nxge_t nxgep)
450644961713Sgirish {
450744961713Sgirish 	npi_handle_t	handle;
450891f84442SToomas Soome 	uint8_t		portn;
450944961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
451044961713Sgirish 	nxge_status_t	status = NXGE_OK;
451144961713Sgirish 
4512678453a8Sspeer 	/* This is a service-domain-only activity. */
4513678453a8Sspeer 	if (isLDOMguest(nxgep))
4514678453a8Sspeer 		return (status);
4515678453a8Sspeer 
451644961713Sgirish 	handle = nxgep->npi_handle;
451744961713Sgirish 	portn = nxgep->mac.portnum;
451844961713Sgirish 
451944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>",
452052ccf843Smisaki 	    portn));
452144961713Sgirish 
452244961713Sgirish 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
452344961713Sgirish 		goto fail;
452444961713Sgirish 
452544961713Sgirish 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
452644961713Sgirish 		if ((rs = npi_xmac_rx_config(handle, ENABLE, portn,
4527678453a8Sspeer 		    CFG_XMAC_RX)) != NPI_SUCCESS)
452844961713Sgirish 			goto fail;
452944961713Sgirish 	} else {
453044961713Sgirish 		if ((rs = npi_bmac_rx_config(handle, ENABLE, portn,
4531678453a8Sspeer 		    CFG_BMAC_RX)) != NPI_SUCCESS)
453244961713Sgirish 			goto fail;
453344961713Sgirish 	}
453444961713Sgirish 
4535678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4536678453a8Sspeer 	    "<== nxge_rx_mac_enable: port<%d>", portn));
453744961713Sgirish 
453844961713Sgirish 	return (NXGE_OK);
453944961713Sgirish fail:
454044961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4541678453a8Sspeer 	    "nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC", portn));
454244961713Sgirish 
454344961713Sgirish 	if (rs != NPI_SUCCESS)
454444961713Sgirish 		return (NXGE_ERROR | rs);
454544961713Sgirish 	else
454644961713Sgirish 		return (status);
454744961713Sgirish }
454844961713Sgirish 
454944961713Sgirish /* Disable RXMAC */
455044961713Sgirish 
455144961713Sgirish nxge_status_t
nxge_rx_mac_disable(p_nxge_t nxgep)455244961713Sgirish nxge_rx_mac_disable(p_nxge_t nxgep)
455344961713Sgirish {
455444961713Sgirish 	npi_handle_t	handle;
455544961713Sgirish 	uint8_t		portn;
455644961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
455744961713Sgirish 
4558678453a8Sspeer 	/* If we are a guest domain driver, don't bother. */
4559678453a8Sspeer 	if (isLDOMguest(nxgep))
4560678453a8Sspeer 		return (NXGE_OK);
4561678453a8Sspeer 
456244961713Sgirish 	handle = nxgep->npi_handle;
456344961713Sgirish 	portn = nxgep->mac.portnum;
456444961713Sgirish 
456544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>",
456652ccf843Smisaki 	    portn));
456744961713Sgirish 
456844961713Sgirish 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
456944961713Sgirish 		if ((rs = npi_xmac_rx_config(handle, DISABLE, portn,
457052ccf843Smisaki 		    CFG_XMAC_RX)) != NPI_SUCCESS)
457144961713Sgirish 			goto fail;
457244961713Sgirish 	} else {
457344961713Sgirish 		if ((rs = npi_bmac_rx_config(handle, DISABLE, portn,
457452ccf843Smisaki 		    CFG_BMAC_RX)) != NPI_SUCCESS)
457544961713Sgirish 			goto fail;
457644961713Sgirish 	}
457744961713Sgirish 
457844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>",
457952ccf843Smisaki 	    portn));
458044961713Sgirish 	return (NXGE_OK);
458144961713Sgirish fail:
458244961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
458352ccf843Smisaki 	    "nxgep_rx_mac_disable: Failed to disable port<%d> RxMAC", portn));
458444961713Sgirish 
458544961713Sgirish 	return (NXGE_ERROR | rs);
458644961713Sgirish }
458744961713Sgirish 
458844961713Sgirish /* Reset TXMAC */
458944961713Sgirish 
459044961713Sgirish nxge_status_t
nxge_tx_mac_reset(p_nxge_t nxgep)459144961713Sgirish nxge_tx_mac_reset(p_nxge_t nxgep)
459244961713Sgirish {
459344961713Sgirish 	npi_handle_t	handle;
459444961713Sgirish 	uint8_t		portn;
459544961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
459644961713Sgirish 
459744961713Sgirish 	handle = nxgep->npi_handle;
459844961713Sgirish 	portn = nxgep->mac.portnum;
459944961713Sgirish 
460044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>",
460152ccf843Smisaki 	    portn));
460244961713Sgirish 
460344961713Sgirish 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
460444961713Sgirish 		if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL))
460544961713Sgirish 		    != NPI_SUCCESS)
460644961713Sgirish 			goto fail;
460744961713Sgirish 	} else {
460844961713Sgirish 		if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET))
460952ccf843Smisaki 		    != NPI_SUCCESS)
461044961713Sgirish 			goto fail;
461144961713Sgirish 	}
461244961713Sgirish 
461344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>",
461452ccf843Smisaki 	    portn));
461544961713Sgirish 
461644961713Sgirish 	return (NXGE_OK);
461744961713Sgirish fail:
461844961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
461952ccf843Smisaki 	    "nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>", portn));
462044961713Sgirish 
462144961713Sgirish 	return (NXGE_ERROR | rs);
462244961713Sgirish }
462344961713Sgirish 
462444961713Sgirish /* Reset RXMAC */
462544961713Sgirish 
462644961713Sgirish nxge_status_t
nxge_rx_mac_reset(p_nxge_t nxgep)462744961713Sgirish nxge_rx_mac_reset(p_nxge_t nxgep)
462844961713Sgirish {
462944961713Sgirish 	npi_handle_t	handle;
463044961713Sgirish 	uint8_t		portn;
463144961713Sgirish 	npi_status_t	rs = NPI_SUCCESS;
463244961713Sgirish 
463344961713Sgirish 	handle = nxgep->npi_handle;
463444961713Sgirish 	portn = nxgep->mac.portnum;
463544961713Sgirish 
463644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>",
463752ccf843Smisaki 	    portn));
463844961713Sgirish 
463944961713Sgirish 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
464044961713Sgirish 		if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL))
464144961713Sgirish 		    != NPI_SUCCESS)
46424df3b64dSToomas Soome 			goto fail;
464344961713Sgirish 	} else {
464444961713Sgirish 		if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET))
464552ccf843Smisaki 		    != NPI_SUCCESS)
46464df3b64dSToomas Soome 			goto fail;
464744961713Sgirish 	}
464844961713Sgirish 
464944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>",
465052ccf843Smisaki 	    portn));
465144961713Sgirish 
465259ac0c16Sdavemq 	return (NXGE_OK);
465359ac0c16Sdavemq fail:
465459ac0c16Sdavemq 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
465552ccf843Smisaki 	    "nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>", portn));
465659ac0c16Sdavemq 	return (NXGE_ERROR | rs);
465759ac0c16Sdavemq }
465859ac0c16Sdavemq 
465959ac0c16Sdavemq /* 10G fiber link interrupt start routine */
466059ac0c16Sdavemq 
466159ac0c16Sdavemq static nxge_status_t
nxge_10G_link_intr_start(p_nxge_t nxgep)466259ac0c16Sdavemq nxge_10G_link_intr_start(p_nxge_t nxgep)
466359ac0c16Sdavemq {
466459ac0c16Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
466559ac0c16Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
466659ac0c16Sdavemq 
466759ac0c16Sdavemq 	rs = npi_xmac_xpcs_link_intr_enable(nxgep->npi_handle, portn);
466859ac0c16Sdavemq 
466959ac0c16Sdavemq 	if (rs != NPI_SUCCESS)
467059ac0c16Sdavemq 		return (NXGE_ERROR | rs);
467159ac0c16Sdavemq 	else
467259ac0c16Sdavemq 		return (NXGE_OK);
467359ac0c16Sdavemq }
467459ac0c16Sdavemq 
467559ac0c16Sdavemq /* 10G fiber link interrupt stop routine */
467659ac0c16Sdavemq 
467759ac0c16Sdavemq static nxge_status_t
nxge_10G_link_intr_stop(p_nxge_t nxgep)467859ac0c16Sdavemq nxge_10G_link_intr_stop(p_nxge_t nxgep)
467959ac0c16Sdavemq {
468059ac0c16Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
468159ac0c16Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
468259ac0c16Sdavemq 
468359ac0c16Sdavemq 	rs = npi_xmac_xpcs_link_intr_disable(nxgep->npi_handle, portn);
468459ac0c16Sdavemq 
468559ac0c16Sdavemq 	if (rs != NPI_SUCCESS)
468659ac0c16Sdavemq 		return (NXGE_ERROR | rs);
468759ac0c16Sdavemq 	else
468859ac0c16Sdavemq 		return (NXGE_OK);
468959ac0c16Sdavemq }
469059ac0c16Sdavemq 
469159ac0c16Sdavemq /* 1G fiber link interrupt start routine */
469259ac0c16Sdavemq 
469359ac0c16Sdavemq static nxge_status_t
nxge_1G_fiber_link_intr_start(p_nxge_t nxgep)469459ac0c16Sdavemq nxge_1G_fiber_link_intr_start(p_nxge_t nxgep)
469559ac0c16Sdavemq {
469659ac0c16Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
469759ac0c16Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
469859ac0c16Sdavemq 
469959ac0c16Sdavemq 	rs = npi_mac_pcs_link_intr_enable(nxgep->npi_handle, portn);
470059ac0c16Sdavemq 	if (rs != NPI_SUCCESS)
470159ac0c16Sdavemq 		return (NXGE_ERROR | rs);
470259ac0c16Sdavemq 	else
470359ac0c16Sdavemq 		return (NXGE_OK);
470459ac0c16Sdavemq }
470559ac0c16Sdavemq 
470659ac0c16Sdavemq /* 1G fiber link interrupt stop routine */
470759ac0c16Sdavemq 
470859ac0c16Sdavemq static nxge_status_t
nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep)470959ac0c16Sdavemq nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep)
471059ac0c16Sdavemq {
471159ac0c16Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
471259ac0c16Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
471359ac0c16Sdavemq 
471459ac0c16Sdavemq 	rs = npi_mac_pcs_link_intr_disable(nxgep->npi_handle, portn);
471559ac0c16Sdavemq 
471659ac0c16Sdavemq 	if (rs != NPI_SUCCESS)
471759ac0c16Sdavemq 		return (NXGE_ERROR | rs);
471859ac0c16Sdavemq 	else
471959ac0c16Sdavemq 		return (NXGE_OK);
472059ac0c16Sdavemq }
472159ac0c16Sdavemq 
472259ac0c16Sdavemq /* 1G copper link interrupt start routine */
472359ac0c16Sdavemq 
472459ac0c16Sdavemq static nxge_status_t
nxge_1G_copper_link_intr_start(p_nxge_t nxgep)472559ac0c16Sdavemq nxge_1G_copper_link_intr_start(p_nxge_t nxgep)
472659ac0c16Sdavemq {
472759ac0c16Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
472859ac0c16Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
472959ac0c16Sdavemq 
473059ac0c16Sdavemq 	rs = npi_mac_mif_link_intr_enable(nxgep->npi_handle, portn,
47316b438925Ssbehera 	    MII_STATUS, MII_STATUS_LINKUP);
473259ac0c16Sdavemq 
473359ac0c16Sdavemq 	if (rs != NPI_SUCCESS)
473459ac0c16Sdavemq 		return (NXGE_ERROR | rs);
473559ac0c16Sdavemq 	else
473659ac0c16Sdavemq 		return (NXGE_OK);
473744961713Sgirish }
473844961713Sgirish 
473959ac0c16Sdavemq /* 1G copper link interrupt stop routine */
474059ac0c16Sdavemq 
474159ac0c16Sdavemq static nxge_status_t
nxge_1G_copper_link_intr_stop(p_nxge_t nxgep)474259ac0c16Sdavemq nxge_1G_copper_link_intr_stop(p_nxge_t nxgep)
474359ac0c16Sdavemq {
474459ac0c16Sdavemq 	npi_status_t	rs = NPI_SUCCESS;
474559ac0c16Sdavemq 	uint8_t		portn = nxgep->mac.portnum;
474659ac0c16Sdavemq 
474759ac0c16Sdavemq 	rs = npi_mac_mif_link_intr_disable(nxgep->npi_handle, portn);
474859ac0c16Sdavemq 
474959ac0c16Sdavemq 	if (rs != NPI_SUCCESS)
475059ac0c16Sdavemq 		return (NXGE_ERROR | rs);
475159ac0c16Sdavemq 	else
475259ac0c16Sdavemq 		return (NXGE_OK);
475359ac0c16Sdavemq }
475444961713Sgirish 
475559ac0c16Sdavemq /* Enable/Disable Link Status change interrupt */
475644961713Sgirish 
475744961713Sgirish nxge_status_t
nxge_link_intr(p_nxge_t nxgep,link_intr_enable_t enable)475844961713Sgirish nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable)
475944961713Sgirish {
476059ac0c16Sdavemq 	uint8_t		portn;
476159ac0c16Sdavemq 	nxge_status_t	status = NXGE_OK;
476244961713Sgirish 
476344961713Sgirish 	portn = nxgep->mac.portnum;
476444961713Sgirish 
476544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn));
476659ac0c16Sdavemq 	if (!nxgep->xcvr.link_intr_stop || !nxgep->xcvr.link_intr_start)
476759ac0c16Sdavemq 		return (NXGE_OK);
476844961713Sgirish 
476959ac0c16Sdavemq 	if (enable == LINK_INTR_START)
477059ac0c16Sdavemq 		status = nxgep->xcvr.link_intr_start(nxgep);
477159ac0c16Sdavemq 	else if (enable == LINK_INTR_STOP)
477259ac0c16Sdavemq 		status = nxgep->xcvr.link_intr_stop(nxgep);
477359ac0c16Sdavemq 	if (status != NXGE_OK)
477459ac0c16Sdavemq 		goto fail;
477544961713Sgirish 
477644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn));
477744961713Sgirish 
477844961713Sgirish 	return (NXGE_OK);
477944961713Sgirish fail:
478044961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
478152ccf843Smisaki 	    "nxge_link_intr: Failed to set port<%d> mif intr mode", portn));
478244961713Sgirish 
478359ac0c16Sdavemq 	return (status);
478444961713Sgirish }
478544961713Sgirish 
478644961713Sgirish /* Initialize 1G Fiber / Copper transceiver using Clause 22 */
478744961713Sgirish 
478844961713Sgirish nxge_status_t
nxge_mii_xcvr_init(p_nxge_t nxgep)478944961713Sgirish nxge_mii_xcvr_init(p_nxge_t nxgep)
479044961713Sgirish {
479144961713Sgirish 	p_nxge_param_t	param_arr;
479244961713Sgirish 	p_nxge_stats_t	statsp;
479344961713Sgirish 	uint8_t		xcvr_portn;
479444961713Sgirish 	p_mii_regs_t	mii_regs;
479544961713Sgirish 	mii_bmcr_t	bmcr;
479644961713Sgirish 	mii_bmsr_t	bmsr;
479744961713Sgirish 	mii_anar_t	anar;
479844961713Sgirish 	mii_gcr_t	gcr;
479944961713Sgirish 	mii_esr_t	esr;
480044961713Sgirish 	mii_aux_ctl_t	bcm5464r_aux;
480144961713Sgirish 	int		status = NXGE_OK;
480244961713Sgirish 
480344961713Sgirish 	uint_t delay;
480444961713Sgirish 
480544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init"));
480644961713Sgirish 
480744961713Sgirish 	param_arr = nxgep->param_arr;
480844961713Sgirish 	statsp = nxgep->statsp;
480944961713Sgirish 	xcvr_portn = statsp->mac_stats.xcvr_portn;
481044961713Sgirish 
481144961713Sgirish 	mii_regs = NULL;
481244961713Sgirish 
481344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
481452ccf843Smisaki 	    "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value));
481544961713Sgirish 
4816d81011f0Ssbehera 	/*
4817d81011f0Ssbehera 	 * The mif phy mode may be connected to either a copper link
4818d81011f0Ssbehera 	 * or fiber link. Read the mode control register to get the fiber
4819d81011f0Ssbehera 	 * configuration if it is hard-wired to fiber link.
4820d81011f0Ssbehera 	 */
4821d81011f0Ssbehera 	(void) nxge_mii_get_link_mode(nxgep);
4822d81011f0Ssbehera 	if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) {
4823d81011f0Ssbehera 		return (nxge_mii_xcvr_fiber_init(nxgep));
4824d81011f0Ssbehera 	}
4825d81011f0Ssbehera 
482644961713Sgirish 	/*
482744961713Sgirish 	 * Reset the transceiver.
482844961713Sgirish 	 */
482944961713Sgirish 	delay = 0;
483044961713Sgirish 	bmcr.value = 0;
483144961713Sgirish 	bmcr.bits.reset = 1;
483244961713Sgirish 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
483352ccf843Smisaki 	    (uint8_t)(uint64_t)&mii_regs->bmcr,
483452ccf843Smisaki 	    bmcr.value)) != NXGE_OK)
483544961713Sgirish 		goto fail;
483644961713Sgirish 	do {
483744961713Sgirish 		drv_usecwait(500);
483844961713Sgirish 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
483952ccf843Smisaki 		    (uint8_t)(uint64_t)&mii_regs->bmcr,
484052ccf843Smisaki 		    &bmcr.value)) != NXGE_OK)
484144961713Sgirish 			goto fail;
484244961713Sgirish 		delay++;
484344961713Sgirish 	} while ((bmcr.bits.reset) && (delay < 1000));
484444961713Sgirish 	if (delay == 1000) {
484544961713Sgirish 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed."));
484644961713Sgirish 		goto fail;
484744961713Sgirish 	}
484844961713Sgirish 
484944961713Sgirish 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
485052ccf843Smisaki 	    (uint8_t)(uint64_t)(&mii_regs->bmsr),
485152ccf843Smisaki 	    &bmsr.value)) != NXGE_OK)
485244961713Sgirish 		goto fail;
485344961713Sgirish 
485444961713Sgirish 	param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able;
485544961713Sgirish 	param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4;
485644961713Sgirish 	param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx;
485744961713Sgirish 	param_arr[param_anar_100hdx].value = 0;
485844961713Sgirish 	param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx;
485944961713Sgirish 	param_arr[param_anar_10hdx].value = 0;
486044961713Sgirish 
486144961713Sgirish 	/*
486258324dfcSspeer 	 * Initialize the xcvr statistics.
486344961713Sgirish 	 */
486444961713Sgirish 	statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able;
486544961713Sgirish 	statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4;
486644961713Sgirish 	statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx;
486744961713Sgirish 	statsp->mac_stats.cap_100hdx = 0;
486844961713Sgirish 	statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx;
486944961713Sgirish 	statsp->mac_stats.cap_10hdx = 0;
487044961713Sgirish 	statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value;
487144961713Sgirish 	statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
487244961713Sgirish 
487344961713Sgirish 	/*
487400161856Syc 	 * Initialize the xcvr advertised capability statistics.
487544961713Sgirish 	 */
487644961713Sgirish 	statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value;
487744961713Sgirish 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
487844961713Sgirish 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
487944961713Sgirish 	statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value;
488044961713Sgirish 	statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value;
488144961713Sgirish 	statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value;
488244961713Sgirish 	statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value;
488344961713Sgirish 	statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value;
488444961713Sgirish 	statsp->mac_stats.adv_cap_asmpause =
488552ccf843Smisaki 	    param_arr[param_anar_asmpause].value;
488644961713Sgirish 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
488744961713Sgirish 
488844961713Sgirish 
488944961713Sgirish 	/*
489044961713Sgirish 	 * Check for extended status just in case we're
489144961713Sgirish 	 * running a Gigibit phy.
489244961713Sgirish 	 */
489344961713Sgirish 	if (bmsr.bits.extend_status) {
489444961713Sgirish 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
489552ccf843Smisaki 		    (uint8_t)(uint64_t)(&mii_regs->esr),
489652ccf843Smisaki 		    &esr.value)) != NXGE_OK)
489744961713Sgirish 			goto fail;
489852ccf843Smisaki 		param_arr[param_anar_1000fdx].value &= esr.bits.link_1000fdx;
489944961713Sgirish 		param_arr[param_anar_1000hdx].value = 0;
490044961713Sgirish 
490144961713Sgirish 		statsp->mac_stats.cap_1000fdx =
490252ccf843Smisaki 		    (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx);
490344961713Sgirish 		statsp->mac_stats.cap_1000hdx = 0;
490444961713Sgirish 	} else {
490544961713Sgirish 		param_arr[param_anar_1000fdx].value = 0;
490644961713Sgirish 		param_arr[param_anar_1000hdx].value = 0;
490744961713Sgirish 	}
490844961713Sgirish 
490944961713Sgirish 	/*
491044961713Sgirish 	 * Initialize 1G Statistics once the capability is established.
491144961713Sgirish 	 */
491244961713Sgirish 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
491344961713Sgirish 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
491444961713Sgirish 
491544961713Sgirish 	/*
491600161856Syc 	 * Initialize the link statistics.
491744961713Sgirish 	 */
491844961713Sgirish 	statsp->mac_stats.link_T4 = 0;
491944961713Sgirish 	statsp->mac_stats.link_asmpause = 0;
492044961713Sgirish 	statsp->mac_stats.link_pause = 0;
492144961713Sgirish 	statsp->mac_stats.link_speed = 0;
492244961713Sgirish 	statsp->mac_stats.link_duplex = 0;
492344961713Sgirish 	statsp->mac_stats.link_up = 0;
492444961713Sgirish 
492544961713Sgirish 	/*
492644961713Sgirish 	 * Switch off Auto-negotiation, 100M and full duplex.
492744961713Sgirish 	 */
492844961713Sgirish 	bmcr.value = 0;
492944961713Sgirish 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
493052ccf843Smisaki 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
493152ccf843Smisaki 	    bmcr.value)) != NXGE_OK)
493244961713Sgirish 		goto fail;
493344961713Sgirish 
493444961713Sgirish 	if ((statsp->port_stats.lb_mode == nxge_lb_phy) ||
493552ccf843Smisaki 	    (statsp->port_stats.lb_mode == nxge_lb_phy1000)) {
493644961713Sgirish 		bmcr.bits.loopback = 1;
493744961713Sgirish 		bmcr.bits.enable_autoneg = 0;
493844961713Sgirish 		if (statsp->port_stats.lb_mode == nxge_lb_phy1000)
493944961713Sgirish 			bmcr.bits.speed_1000_sel = 1;
494044961713Sgirish 		bmcr.bits.duplex_mode = 1;
494144961713Sgirish 		param_arr[param_autoneg].value = 0;
494244961713Sgirish 	} else {
494344961713Sgirish 		bmcr.bits.loopback = 0;
494444961713Sgirish 	}
494544961713Sgirish 
494644961713Sgirish 	if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
494752ccf843Smisaki 	    (statsp->port_stats.lb_mode == nxge_lb_ext100) ||
494852ccf843Smisaki 	    (statsp->port_stats.lb_mode == nxge_lb_ext10)) {
494944961713Sgirish 		param_arr[param_autoneg].value = 0;
495044961713Sgirish 		bcm5464r_aux.value = 0;
495144961713Sgirish 		bcm5464r_aux.bits.ext_lb = 1;
495244961713Sgirish 		bcm5464r_aux.bits.write_1 = 1;
495344961713Sgirish 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
495452ccf843Smisaki 		    BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK)
495544961713Sgirish 			goto fail;
495644961713Sgirish 	}
495744961713Sgirish 
495800161856Syc 	/* If auto-negotiation is desired */
495944961713Sgirish 	if (param_arr[param_autoneg].value) {
496044961713Sgirish 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
496152ccf843Smisaki 		    "Restarting Auto-negotiation."));
496244961713Sgirish 		/*
496344961713Sgirish 		 * Setup our Auto-negotiation advertisement register.
496444961713Sgirish 		 */
496544961713Sgirish 		anar.value = 0;
496644961713Sgirish 		anar.bits.selector = 1;
496744961713Sgirish 		anar.bits.cap_100T4 = param_arr[param_anar_100T4].value;
496844961713Sgirish 		anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value;
496944961713Sgirish 		anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value;
497044961713Sgirish 		anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value;
497144961713Sgirish 		anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value;
497244961713Sgirish 		anar.bits.cap_asmpause = 0;
497344961713Sgirish 		anar.bits.cap_pause = 0;
497444961713Sgirish 		if (param_arr[param_anar_1000fdx].value ||
497552ccf843Smisaki 		    param_arr[param_anar_100fdx].value ||
497652ccf843Smisaki 		    param_arr[param_anar_10fdx].value) {
497744961713Sgirish 			anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause;
497844961713Sgirish 			anar.bits.cap_pause = statsp->mac_stats.cap_pause;
497944961713Sgirish 		}
498044961713Sgirish 
498100161856Syc 		/* Write to the auto-negotiation advertisement register */
498244961713Sgirish 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
498352ccf843Smisaki 		    (uint8_t)(uint64_t)(&mii_regs->anar),
498452ccf843Smisaki 		    anar.value)) != NXGE_OK)
498544961713Sgirish 			goto fail;
498644961713Sgirish 		if (bmsr.bits.extend_status) {
498744961713Sgirish 			gcr.value = 0;
498844961713Sgirish 			gcr.bits.ms_mode_en =
498952ccf843Smisaki 			    param_arr[param_master_cfg_enable].value;
499044961713Sgirish 			gcr.bits.master =
499152ccf843Smisaki 			    param_arr[param_master_cfg_value].value;
499244961713Sgirish 			gcr.bits.link_1000fdx =
499352ccf843Smisaki 			    param_arr[param_anar_1000fdx].value;
499444961713Sgirish 			gcr.bits.link_1000hdx =
499552ccf843Smisaki 			    param_arr[param_anar_1000hdx].value;
499644961713Sgirish 			if ((status = nxge_mii_write(nxgep, xcvr_portn,
499752ccf843Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->gcr),
499852ccf843Smisaki 			    gcr.value)) != NXGE_OK)
499944961713Sgirish 				goto fail;
500044961713Sgirish 		}
500144961713Sgirish 
500244961713Sgirish 		bmcr.bits.enable_autoneg = 1;
500344961713Sgirish 		bmcr.bits.restart_autoneg = 1;
500444961713Sgirish 
500544961713Sgirish 	} else {
500644961713Sgirish 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode."));
500744961713Sgirish 		bmcr.bits.speed_1000_sel =
500852ccf843Smisaki 		    param_arr[param_anar_1000fdx].value |
500952ccf843Smisaki 		    param_arr[param_anar_1000hdx].value;
501044961713Sgirish 		bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) &
501152ccf843Smisaki 		    (param_arr[param_anar_100fdx].value |
501252ccf843Smisaki 		    param_arr[param_anar_100hdx].value);
501300161856Syc 
501400161856Syc 		/* Force to 1G */
501544961713Sgirish 		if (bmcr.bits.speed_1000_sel) {
501644961713Sgirish 			statsp->mac_stats.link_speed = 1000;
501744961713Sgirish 			gcr.value = 0;
501844961713Sgirish 			gcr.bits.ms_mode_en =
501952ccf843Smisaki 			    param_arr[param_master_cfg_enable].value;
502044961713Sgirish 			gcr.bits.master =
502152ccf843Smisaki 			    param_arr[param_master_cfg_value].value;
502244961713Sgirish 			if ((status = nxge_mii_write(nxgep, xcvr_portn,
502352ccf843Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->gcr),
502452ccf843Smisaki 			    gcr.value)) != NXGE_OK)
502544961713Sgirish 				goto fail;
502644961713Sgirish 			if (param_arr[param_anar_1000fdx].value) {
502744961713Sgirish 				bmcr.bits.duplex_mode = 1;
502844961713Sgirish 				statsp->mac_stats.link_duplex = 2;
502944961713Sgirish 			} else
503044961713Sgirish 				statsp->mac_stats.link_duplex = 1;
503100161856Syc 
503200161856Syc 		/* Force to 100M */
503344961713Sgirish 		} else if (bmcr.bits.speed_sel) {
503444961713Sgirish 			statsp->mac_stats.link_speed = 100;
503544961713Sgirish 			if (param_arr[param_anar_100fdx].value) {
503644961713Sgirish 				bmcr.bits.duplex_mode = 1;
503744961713Sgirish 				statsp->mac_stats.link_duplex = 2;
503844961713Sgirish 			} else
503944961713Sgirish 				statsp->mac_stats.link_duplex = 1;
504000161856Syc 
504100161856Syc 		/* Force to 10M */
504244961713Sgirish 		} else {
504344961713Sgirish 			statsp->mac_stats.link_speed = 10;
504444961713Sgirish 			if (param_arr[param_anar_10fdx].value) {
504544961713Sgirish 				bmcr.bits.duplex_mode = 1;
504644961713Sgirish 				statsp->mac_stats.link_duplex = 2;
504744961713Sgirish 			} else
504844961713Sgirish 				statsp->mac_stats.link_duplex = 1;
504944961713Sgirish 		}
505044961713Sgirish 		if (statsp->mac_stats.link_duplex != 1) {
505144961713Sgirish 			statsp->mac_stats.link_asmpause =
505252ccf843Smisaki 			    statsp->mac_stats.cap_asmpause;
505344961713Sgirish 			statsp->mac_stats.link_pause =
505452ccf843Smisaki 			    statsp->mac_stats.cap_pause;
505544961713Sgirish 		}
505644961713Sgirish 
505744961713Sgirish 		if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
505852ccf843Smisaki 		    (statsp->port_stats.lb_mode == nxge_lb_ext100) ||
505952ccf843Smisaki 		    (statsp->port_stats.lb_mode == nxge_lb_ext10)) {
506044961713Sgirish 			if (statsp->port_stats.lb_mode == nxge_lb_ext1000) {
506144961713Sgirish 				/* BCM5464R 1000mbps external loopback mode */
506244961713Sgirish 				gcr.value = 0;
506344961713Sgirish 				gcr.bits.ms_mode_en = 1;
506444961713Sgirish 				gcr.bits.master = 1;
506544961713Sgirish 				if ((status = nxge_mii_write(nxgep, xcvr_portn,
506652ccf843Smisaki 				    (uint8_t)(uint64_t)(&mii_regs->gcr),
506752ccf843Smisaki 				    gcr.value)) != NXGE_OK)
506844961713Sgirish 					goto fail;
506944961713Sgirish 				bmcr.value = 0;
507044961713Sgirish 				bmcr.bits.speed_1000_sel = 1;
507144961713Sgirish 				statsp->mac_stats.link_speed = 1000;
507244961713Sgirish 			} else if (statsp->port_stats.lb_mode
507344961713Sgirish 			    == nxge_lb_ext100) {
507444961713Sgirish 				/* BCM5464R 100mbps external loopback mode */
507544961713Sgirish 				bmcr.value = 0;
507644961713Sgirish 				bmcr.bits.speed_sel = 1;
507744961713Sgirish 				bmcr.bits.duplex_mode = 1;
507844961713Sgirish 				statsp->mac_stats.link_speed = 100;
507944961713Sgirish 			} else if (statsp->port_stats.lb_mode
508044961713Sgirish 			    == nxge_lb_ext10) {
508144961713Sgirish 				/* BCM5464R 10mbps external loopback mode */
508244961713Sgirish 				bmcr.value = 0;
508344961713Sgirish 				bmcr.bits.duplex_mode = 1;
508444961713Sgirish 				statsp->mac_stats.link_speed = 10;
508544961713Sgirish 			}
508644961713Sgirish 		}
508744961713Sgirish 	}
508844961713Sgirish 
508944961713Sgirish 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
509052ccf843Smisaki 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
509152ccf843Smisaki 	    bmcr.value)) != NXGE_OK)
509244961713Sgirish 		goto fail;
509344961713Sgirish 
509444961713Sgirish 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
509552ccf843Smisaki 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
509652ccf843Smisaki 	    &bmcr.value)) != NXGE_OK)
509744961713Sgirish 		goto fail;
509844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value));
509944961713Sgirish 
510044961713Sgirish 	/*
510144961713Sgirish 	 * Initialize the xcvr status kept in the context structure.
510244961713Sgirish 	 */
510344961713Sgirish 	nxgep->soft_bmsr.value = 0;
510444961713Sgirish 
510544961713Sgirish 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
510652ccf843Smisaki 	    (uint8_t)(uint64_t)(&mii_regs->bmsr),
510752ccf843Smisaki 	    &nxgep->bmsr.value)) != NXGE_OK)
510844961713Sgirish 		goto fail;
510944961713Sgirish 
511044961713Sgirish 	statsp->mac_stats.xcvr_inits++;
511144961713Sgirish 	nxgep->bmsr.value = 0;
511244961713Sgirish 
511344961713Sgirish fail:
511444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
511552ccf843Smisaki 	    "<== nxge_mii_xcvr_init status 0x%x", status));
511644961713Sgirish 	return (status);
511744961713Sgirish }
511844961713Sgirish 
5119d81011f0Ssbehera nxge_status_t
nxge_mii_xcvr_fiber_init(p_nxge_t nxgep)5120d81011f0Ssbehera nxge_mii_xcvr_fiber_init(p_nxge_t nxgep)
5121d81011f0Ssbehera {
5122d81011f0Ssbehera 	p_nxge_param_t	param_arr;
5123d81011f0Ssbehera 	p_nxge_stats_t	statsp;
5124d81011f0Ssbehera 	uint8_t		xcvr_portn;
5125d81011f0Ssbehera 	p_mii_regs_t	mii_regs;
5126d81011f0Ssbehera 	mii_bmcr_t	bmcr;
5127d81011f0Ssbehera 	mii_bmsr_t	bmsr;
5128d81011f0Ssbehera 	mii_gcr_t	gcr;
5129d81011f0Ssbehera 	mii_esr_t	esr;
5130d81011f0Ssbehera 	mii_aux_ctl_t	bcm5464r_aux;
5131d81011f0Ssbehera 	int		status = NXGE_OK;
5132d81011f0Ssbehera 
5133d81011f0Ssbehera 	uint_t delay;
5134d81011f0Ssbehera 
5135d81011f0Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_fiber_init"));
5136d81011f0Ssbehera 
5137d81011f0Ssbehera 	param_arr = nxgep->param_arr;
5138d81011f0Ssbehera 	statsp = nxgep->statsp;
5139d81011f0Ssbehera 	xcvr_portn = statsp->mac_stats.xcvr_portn;
5140d81011f0Ssbehera 
5141d81011f0Ssbehera 	mii_regs = NULL;
5142d81011f0Ssbehera 
5143d81011f0Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5144d81011f0Ssbehera 	    "nxge_mii_xcvr_fiber_init: "
5145d81011f0Ssbehera 	    "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value));
5146d81011f0Ssbehera 
5147d81011f0Ssbehera 	/*
5148d81011f0Ssbehera 	 * Reset the transceiver.
5149d81011f0Ssbehera 	 */
5150d81011f0Ssbehera 	delay = 0;
5151d81011f0Ssbehera 	bmcr.value = 0;
5152d81011f0Ssbehera 	bmcr.bits.reset = 1;
5153d81011f0Ssbehera 
5154d81011f0Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
5155d81011f0Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
5156d81011f0Ssbehera 		goto fail;
5157d81011f0Ssbehera 	do {
5158d81011f0Ssbehera 		drv_usecwait(500);
5159d81011f0Ssbehera 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
5160d81011f0Ssbehera 		    (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value))
5161d81011f0Ssbehera 		    != NXGE_OK)
5162d81011f0Ssbehera 			goto fail;
5163d81011f0Ssbehera 		delay++;
5164d81011f0Ssbehera 	} while ((bmcr.bits.reset) && (delay < 1000));
5165d81011f0Ssbehera 	if (delay == 1000) {
5166d81011f0Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed."));
5167d81011f0Ssbehera 		goto fail;
5168d81011f0Ssbehera 	}
5169d81011f0Ssbehera 
5170d81011f0Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
5171d81011f0Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK)
5172d81011f0Ssbehera 		goto fail;
5173d81011f0Ssbehera 
5174d81011f0Ssbehera 	param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able;
5175d81011f0Ssbehera 	param_arr[param_anar_100T4].value = 0;
5176d81011f0Ssbehera 	param_arr[param_anar_100fdx].value = 0;
5177d81011f0Ssbehera 	param_arr[param_anar_100hdx].value = 0;
5178d81011f0Ssbehera 	param_arr[param_anar_10fdx].value = 0;
5179d81011f0Ssbehera 	param_arr[param_anar_10hdx].value = 0;
5180d81011f0Ssbehera 
5181d81011f0Ssbehera 	/*
5182d81011f0Ssbehera 	 * Initialize the xcvr statistics.
5183d81011f0Ssbehera 	 */
5184d81011f0Ssbehera 	statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able;
5185d81011f0Ssbehera 	statsp->mac_stats.cap_100T4 = 0;
5186d81011f0Ssbehera 	statsp->mac_stats.cap_100fdx = 0;
5187d81011f0Ssbehera 	statsp->mac_stats.cap_100hdx = 0;
5188d81011f0Ssbehera 	statsp->mac_stats.cap_10fdx = 0;
5189d81011f0Ssbehera 	statsp->mac_stats.cap_10hdx = 0;
5190d81011f0Ssbehera 	statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value;
5191d81011f0Ssbehera 	statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
5192d81011f0Ssbehera 
5193d81011f0Ssbehera 	/*
5194d81011f0Ssbehera 	 * Initialize the xcvr advertised capability statistics.
5195d81011f0Ssbehera 	 */
5196d81011f0Ssbehera 	statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value;
5197d81011f0Ssbehera 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
5198d81011f0Ssbehera 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
5199d81011f0Ssbehera 	statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value;
5200d81011f0Ssbehera 	statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value;
5201d81011f0Ssbehera 	statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value;
5202d81011f0Ssbehera 	statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value;
5203d81011f0Ssbehera 	statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value;
5204d81011f0Ssbehera 	statsp->mac_stats.adv_cap_asmpause =
5205d81011f0Ssbehera 	    param_arr[param_anar_asmpause].value;
5206d81011f0Ssbehera 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
5207d81011f0Ssbehera 
5208d81011f0Ssbehera 	/*
5209d81011f0Ssbehera 	 * Check for extended status just in case we're
5210d81011f0Ssbehera 	 * running a Gigibit phy.
5211d81011f0Ssbehera 	 */
5212d81011f0Ssbehera 	if (bmsr.bits.extend_status) {
5213d81011f0Ssbehera 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
5214d81011f0Ssbehera 		    (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) !=
5215d81011f0Ssbehera 		    NXGE_OK)
5216d81011f0Ssbehera 			goto fail;
5217d81011f0Ssbehera 		param_arr[param_anar_1000fdx].value &=
5218d81011f0Ssbehera 		    esr.bits.link_1000fdx;
5219d81011f0Ssbehera 		param_arr[param_anar_1000hdx].value = 0;
5220d81011f0Ssbehera 
5221d81011f0Ssbehera 		statsp->mac_stats.cap_1000fdx =
5222d81011f0Ssbehera 		    (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx);
5223d81011f0Ssbehera 		statsp->mac_stats.cap_1000hdx = 0;
5224d81011f0Ssbehera 	} else {
5225d81011f0Ssbehera 		param_arr[param_anar_1000fdx].value = 0;
5226d81011f0Ssbehera 		param_arr[param_anar_1000hdx].value = 0;
5227d81011f0Ssbehera 	}
5228d81011f0Ssbehera 
5229d81011f0Ssbehera 	/*
5230d81011f0Ssbehera 	 * Initialize 1G Statistics once the capability is established.
5231d81011f0Ssbehera 	 */
5232d81011f0Ssbehera 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
5233d81011f0Ssbehera 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
5234d81011f0Ssbehera 
5235d81011f0Ssbehera 	/*
5236d81011f0Ssbehera 	 * Initialize the link statistics.
5237d81011f0Ssbehera 	 */
5238d81011f0Ssbehera 	statsp->mac_stats.link_T4 = 0;
5239d81011f0Ssbehera 	statsp->mac_stats.link_asmpause = 0;
5240d81011f0Ssbehera 	statsp->mac_stats.link_pause = 0;
5241d81011f0Ssbehera 	statsp->mac_stats.link_speed = 0;
5242d81011f0Ssbehera 	statsp->mac_stats.link_duplex = 0;
5243d81011f0Ssbehera 	statsp->mac_stats.link_up = 0;
5244d81011f0Ssbehera 
5245d81011f0Ssbehera 	/*
5246d81011f0Ssbehera 	 * Switch off Auto-negotiation, 100M and full duplex.
5247d81011f0Ssbehera 	 */
5248d81011f0Ssbehera 	bmcr.value = 0;
5249d81011f0Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
5250d81011f0Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
5251d81011f0Ssbehera 		goto fail;
5252d81011f0Ssbehera 
5253d81011f0Ssbehera 	if ((statsp->port_stats.lb_mode == nxge_lb_phy) ||
5254d81011f0Ssbehera 	    (statsp->port_stats.lb_mode == nxge_lb_phy1000)) {
5255d81011f0Ssbehera 		bmcr.bits.loopback = 1;
5256d81011f0Ssbehera 		bmcr.bits.enable_autoneg = 0;
5257d81011f0Ssbehera 		if (statsp->port_stats.lb_mode == nxge_lb_phy1000)
5258d81011f0Ssbehera 			bmcr.bits.speed_1000_sel = 1;
5259d81011f0Ssbehera 		bmcr.bits.duplex_mode = 1;
5260d81011f0Ssbehera 		param_arr[param_autoneg].value = 0;
5261d81011f0Ssbehera 	} else {
5262d81011f0Ssbehera 		bmcr.bits.loopback = 0;
5263d81011f0Ssbehera 	}
5264d81011f0Ssbehera 
5265d81011f0Ssbehera 	if (statsp->port_stats.lb_mode == nxge_lb_ext1000) {
5266d81011f0Ssbehera 		param_arr[param_autoneg].value = 0;
5267d81011f0Ssbehera 		bcm5464r_aux.value = 0;
5268d81011f0Ssbehera 		bcm5464r_aux.bits.ext_lb = 1;
5269d81011f0Ssbehera 		bcm5464r_aux.bits.write_1 = 1;
5270d81011f0Ssbehera 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
5271d81011f0Ssbehera 		    BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK)
5272d81011f0Ssbehera 			goto fail;
5273d81011f0Ssbehera 	}
5274d81011f0Ssbehera 
5275d81011f0Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode."));
5276d81011f0Ssbehera 	bmcr.bits.speed_1000_sel = 1;
5277d81011f0Ssbehera 	bmcr.bits.speed_sel = 0;
5278d81011f0Ssbehera 	bmcr.bits.duplex_mode = 1;
5279d81011f0Ssbehera 	statsp->mac_stats.link_speed = 1000;
5280d81011f0Ssbehera 	statsp->mac_stats.link_duplex = 2;
5281d81011f0Ssbehera 
5282d81011f0Ssbehera 	if ((statsp->port_stats.lb_mode == nxge_lb_ext1000)) {
5283d81011f0Ssbehera 		/* BCM5464R 1000mbps external loopback mode */
5284d81011f0Ssbehera 		gcr.value = 0;
5285d81011f0Ssbehera 		gcr.bits.ms_mode_en = 1;
5286d81011f0Ssbehera 		gcr.bits.master = 1;
5287d81011f0Ssbehera 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
5288d81011f0Ssbehera 		    (uint8_t)(uint64_t)(&mii_regs->gcr),
5289d81011f0Ssbehera 		    gcr.value)) != NXGE_OK)
5290d81011f0Ssbehera 			goto fail;
5291d81011f0Ssbehera 		bmcr.value = 0;
5292d81011f0Ssbehera 		bmcr.bits.speed_1000_sel = 1;
5293d81011f0Ssbehera 		statsp->mac_stats.link_speed = 1000;
5294d81011f0Ssbehera 	}
5295d81011f0Ssbehera 
5296d81011f0Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
5297d81011f0Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
5298d81011f0Ssbehera 	    bmcr.value)) != NXGE_OK)
5299d81011f0Ssbehera 		goto fail;
5300d81011f0Ssbehera 
5301d81011f0Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5302d81011f0Ssbehera 	    "nxge_mii_xcvr_fiber_init: value wrote bmcr = 0x%x",
5303d81011f0Ssbehera 	    bmcr.value));
5304d81011f0Ssbehera 
5305d81011f0Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
5306d81011f0Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
5307d81011f0Ssbehera 		goto fail;
5308d81011f0Ssbehera 
5309d81011f0Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5310d81011f0Ssbehera 	    "nxge_mii_xcvr_fiber_init: read bmcr = 0x%04X", bmcr.value));
5311d81011f0Ssbehera 
5312d81011f0Ssbehera 	/*
5313d81011f0Ssbehera 	 * Initialize the xcvr status kept in the context structure.
5314d81011f0Ssbehera 	 */
5315d81011f0Ssbehera 	nxgep->soft_bmsr.value = 0;
5316d81011f0Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
5317d81011f0Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmsr),
5318d81011f0Ssbehera 	    &nxgep->bmsr.value)) != NXGE_OK)
5319d81011f0Ssbehera 		goto fail;
5320d81011f0Ssbehera 
5321d81011f0Ssbehera 	statsp->mac_stats.xcvr_inits++;
5322d81011f0Ssbehera 	nxgep->bmsr.value = 0;
5323d81011f0Ssbehera 
5324d81011f0Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5325d81011f0Ssbehera 	    "<== nxge_mii_xcvr_fiber_init status 0x%x", status));
5326d81011f0Ssbehera 	return (status);
5327d81011f0Ssbehera 
5328d81011f0Ssbehera fail:
5329d81011f0Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5330d81011f0Ssbehera 	    "<== nxge_mii_xcvr_fiber_init status 0x%x", status));
5331d81011f0Ssbehera 	return (status);
5332d81011f0Ssbehera }
5333d81011f0Ssbehera 
533444961713Sgirish /* Read from a MII compliant register */
533544961713Sgirish 
533644961713Sgirish nxge_status_t
nxge_mii_read(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t xcvr_reg,uint16_t * value)533744961713Sgirish nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
533891f84442SToomas Soome     uint16_t *value)
533944961713Sgirish {
534044961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
534144961713Sgirish 
534244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>"
534352ccf843Smisaki 	    "xcvr_reg<%d>", xcvr_portn, xcvr_reg));
534444961713Sgirish 
5345321febdeSsbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
534644961713Sgirish 
5347d81011f0Ssbehera 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
5348d81011f0Ssbehera 	    (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) {
534944961713Sgirish 		if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle,
535052ccf843Smisaki 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
535144961713Sgirish 			goto fail;
53522e59129aSraghus 	} else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
53532e59129aSraghus 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
535444961713Sgirish 		if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle,
535552ccf843Smisaki 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
535644961713Sgirish 			goto fail;
535744961713Sgirish 	} else
535844961713Sgirish 		goto fail;
535944961713Sgirish 
5360321febdeSsbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
536144961713Sgirish 
536244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>"
536352ccf843Smisaki 	    "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, *value));
536444961713Sgirish 	return (NXGE_OK);
536544961713Sgirish fail:
5366321febdeSsbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
536744961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
536852ccf843Smisaki 	    "nxge_mii_read: Failed to read mii on xcvr %d", xcvr_portn));
536944961713Sgirish 
537044961713Sgirish 	return (NXGE_ERROR | rs);
537144961713Sgirish }
537244961713Sgirish 
537344961713Sgirish /* Write to a MII compliant Register */
537444961713Sgirish 
537544961713Sgirish nxge_status_t
nxge_mii_write(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t xcvr_reg,uint16_t value)537644961713Sgirish nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
537791f84442SToomas Soome     uint16_t value)
537844961713Sgirish {
537944961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
538044961713Sgirish 
538144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>"
538252ccf843Smisaki 	    "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, value));
538344961713Sgirish 
5384321febdeSsbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
538544961713Sgirish 
5386d81011f0Ssbehera 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
5387d81011f0Ssbehera 	    (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) {
538844961713Sgirish 		if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle,
538952ccf843Smisaki 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
539044961713Sgirish 			goto fail;
53912e59129aSraghus 	} else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
53922e59129aSraghus 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
539344961713Sgirish 		if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle,
539452ccf843Smisaki 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
539544961713Sgirish 			goto fail;
539644961713Sgirish 	} else
539744961713Sgirish 		goto fail;
539844961713Sgirish 
5399321febdeSsbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
540044961713Sgirish 
540144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>"
540252ccf843Smisaki 	    "xcvr_reg<%d>", xcvr_portn, xcvr_reg));
540344961713Sgirish 	return (NXGE_OK);
540444961713Sgirish fail:
5405321febdeSsbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
540644961713Sgirish 
540744961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
540852ccf843Smisaki 	    "nxge_mii_write: Failed to write mii on xcvr %d", xcvr_portn));
540944961713Sgirish 
541044961713Sgirish 	return (NXGE_ERROR | rs);
541144961713Sgirish }
541244961713Sgirish 
541300161856Syc /*
541400161856Syc  * Perform write to Clause45 serdes / transceiver device
541500161856Syc  * Arguments:
541691f84442SToomas Soome  *	xcvr_portn:	The IEEE 802.3 Clause45 PHYAD, it is the same as port
541700161856Syc  *			number if nxge_mdio_write is used for accessing the
541800161856Syc  *			internal LSIL serdes. Otherwise PHYAD is different
541991f84442SToomas Soome  *			for different platforms.
542000161856Syc  *	device:		With each PHYAD, the driver can use MDIO to control
542100161856Syc  *			multiple devices inside the PHY, here "device" is an
542200161856Syc  *			MMD (MDIO managable device).
542300161856Syc  *	xcvr_reg:	Each device has multiple registers. xcvr_reg specifies
542400161856Syc  *			the register which the driver will write value to.
542500161856Syc  *	value:		The register value will be filled in.
542600161856Syc  */
542744961713Sgirish nxge_status_t
nxge_mdio_read(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t device,uint16_t xcvr_reg,uint16_t * value)542844961713Sgirish nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
542991f84442SToomas Soome     uint16_t xcvr_reg, uint16_t *value)
543044961713Sgirish {
543144961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
543244961713Sgirish 
543344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>",
543452ccf843Smisaki 	    xcvr_portn));
543544961713Sgirish 
543653560810Ssbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
543744961713Sgirish 
543844961713Sgirish 	if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle,
543952ccf843Smisaki 	    xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
544044961713Sgirish 		goto fail;
544144961713Sgirish 
544253560810Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
544344961713Sgirish 
544444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>",
544552ccf843Smisaki 	    xcvr_portn));
544644961713Sgirish 	return (NXGE_OK);
544744961713Sgirish fail:
544853560810Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
544944961713Sgirish 
545044961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
545152ccf843Smisaki 	    "nxge_mdio_read: Failed to read mdio on xcvr %d", xcvr_portn));
545244961713Sgirish 
545344961713Sgirish 	return (NXGE_ERROR | rs);
545444961713Sgirish }
545544961713Sgirish 
545644961713Sgirish /* Perform write to Clause45 serdes / transceiver device */
545744961713Sgirish 
545844961713Sgirish nxge_status_t
nxge_mdio_write(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t device,uint16_t xcvr_reg,uint16_t value)545944961713Sgirish nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
546091f84442SToomas Soome     uint16_t xcvr_reg, uint16_t value)
546144961713Sgirish {
546244961713Sgirish 	npi_status_t rs = NPI_SUCCESS;
546344961713Sgirish 
546444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>",
546552ccf843Smisaki 	    xcvr_portn));
546644961713Sgirish 
546753560810Ssbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
546844961713Sgirish 
546944961713Sgirish 	if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle,
547052ccf843Smisaki 	    xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
547144961713Sgirish 		goto fail;
547244961713Sgirish 
547353560810Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
547444961713Sgirish 
547544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>",
547652ccf843Smisaki 	    xcvr_portn));
547744961713Sgirish 	return (NXGE_OK);
547844961713Sgirish fail:
547953560810Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
548044961713Sgirish 
548144961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
548252ccf843Smisaki 	    "nxge_mdio_write: Failed to write mdio on xcvr %d", xcvr_portn));
548344961713Sgirish 
548444961713Sgirish 	return (NXGE_ERROR | rs);
548544961713Sgirish }
548644961713Sgirish 
548744961713Sgirish 
548844961713Sgirish /* Check MII to see if there is any link status change */
548944961713Sgirish 
549044961713Sgirish 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)5491a3c5bd6dSspeer nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints,
549291f84442SToomas Soome     nxge_link_state_t *link_up)
549344961713Sgirish {
549444961713Sgirish 	p_nxge_param_t	param_arr;
549544961713Sgirish 	p_nxge_stats_t	statsp;
549644961713Sgirish 	p_mii_regs_t	mii_regs;
549744961713Sgirish 	p_mii_bmsr_t	soft_bmsr;
549844961713Sgirish 	mii_anar_t	anar;
549944961713Sgirish 	mii_anlpar_t	anlpar;
550044961713Sgirish 	mii_anar_t	an_common;
550144961713Sgirish 	mii_aner_t	aner;
550244961713Sgirish 	mii_gsr_t	gsr;
550344961713Sgirish 	nxge_status_t	status = NXGE_OK;
550444961713Sgirish 
550544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check"));
550644961713Sgirish 
550744961713Sgirish 	mii_regs = NULL;
550844961713Sgirish 	param_arr = nxgep->param_arr;
550944961713Sgirish 	statsp = nxgep->statsp;
551044961713Sgirish 	soft_bmsr = &nxgep->soft_bmsr;
5511a3c5bd6dSspeer 	*link_up = LINK_NO_CHANGE;
551244961713Sgirish 
5513d81011f0Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5514d81011f0Ssbehera 	    "==> nxge_mii_check bmsr 0x%x bmsr_int 0x%x",
5515d81011f0Ssbehera 	    bmsr.value, bmsr_ints.value));
5516d81011f0Ssbehera 
551744961713Sgirish 	if (bmsr_ints.bits.link_status) {
5518d81011f0Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5519d81011f0Ssbehera 		    "==> nxge_mii_check (link up) bmsr 0x%x bmsr_int 0x%x",
5520d81011f0Ssbehera 		    bmsr.value, bmsr_ints.value));
552144961713Sgirish 		if (bmsr.bits.link_status) {
552244961713Sgirish 			soft_bmsr->bits.link_status = 1;
5523d81011f0Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5524d81011f0Ssbehera 		    "==> nxge_mii_check (link up) soft bmsr 0x%x bmsr_int "
5525d81011f0Ssbehera 		    "0x%x", bmsr.value, bmsr_ints.value));
552644961713Sgirish 		} else {
5527774da109Stc 			/* Only status change will update *link_up */
5528774da109Stc 			if (statsp->mac_stats.link_up == 1) {
5529774da109Stc 				*link_up = LINK_IS_DOWN;
5530774da109Stc 				/* Will notify, turn off further msg */
5531774da109Stc 				nxgep->link_notify = B_FALSE;
5532774da109Stc 			}
553344961713Sgirish 			statsp->mac_stats.link_up = 0;
553444961713Sgirish 			soft_bmsr->bits.link_status = 0;
553544961713Sgirish 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
553652ccf843Smisaki 			    "Link down cable problem"));
553744961713Sgirish 		}
553844961713Sgirish 	}
553944961713Sgirish 
5540d81011f0Ssbehera 	if (nxgep->mac.portmode == PORT_1G_COPPER &&
5541d81011f0Ssbehera 	    param_arr[param_autoneg].value) {
554244961713Sgirish 		if (bmsr_ints.bits.auto_neg_complete) {
554344961713Sgirish 			if (bmsr.bits.auto_neg_complete)
554444961713Sgirish 				soft_bmsr->bits.auto_neg_complete = 1;
554544961713Sgirish 			else
554644961713Sgirish 				soft_bmsr->bits.auto_neg_complete = 0;
554744961713Sgirish 		}
554844961713Sgirish 		if (soft_bmsr->bits.link_status == 0) {
554944961713Sgirish 			statsp->mac_stats.link_T4 = 0;
555044961713Sgirish 			statsp->mac_stats.link_speed = 0;
555144961713Sgirish 			statsp->mac_stats.link_duplex = 0;
555244961713Sgirish 			statsp->mac_stats.link_asmpause = 0;
555344961713Sgirish 			statsp->mac_stats.link_pause = 0;
555444961713Sgirish 			statsp->mac_stats.lp_cap_autoneg = 0;
555544961713Sgirish 			statsp->mac_stats.lp_cap_100T4 = 0;
555644961713Sgirish 			statsp->mac_stats.lp_cap_1000fdx = 0;
555744961713Sgirish 			statsp->mac_stats.lp_cap_1000hdx = 0;
555844961713Sgirish 			statsp->mac_stats.lp_cap_100fdx = 0;
555944961713Sgirish 			statsp->mac_stats.lp_cap_100hdx = 0;
556044961713Sgirish 			statsp->mac_stats.lp_cap_10fdx = 0;
556144961713Sgirish 			statsp->mac_stats.lp_cap_10hdx = 0;
556244961713Sgirish 			statsp->mac_stats.lp_cap_10gfdx = 0;
556344961713Sgirish 			statsp->mac_stats.lp_cap_10ghdx = 0;
556444961713Sgirish 			statsp->mac_stats.lp_cap_asmpause = 0;
556544961713Sgirish 			statsp->mac_stats.lp_cap_pause = 0;
556644961713Sgirish 		}
556744961713Sgirish 	} else
556844961713Sgirish 		soft_bmsr->bits.auto_neg_complete = 1;
556944961713Sgirish 
557044961713Sgirish 	if ((bmsr_ints.bits.link_status ||
557152ccf843Smisaki 	    bmsr_ints.bits.auto_neg_complete) &&
557252ccf843Smisaki 	    soft_bmsr->bits.link_status &&
557352ccf843Smisaki 	    soft_bmsr->bits.auto_neg_complete) {
5574774da109Stc 		if (statsp->mac_stats.link_up == 0) {
5575774da109Stc 			*link_up = LINK_IS_UP;
5576774da109Stc 			nxgep->link_notify = B_FALSE;
5577774da109Stc 		}
557844961713Sgirish 		statsp->mac_stats.link_up = 1;
5579d81011f0Ssbehera 
5580d81011f0Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5581d81011f0Ssbehera 		    "==> nxge_mii_check "
5582d81011f0Ssbehera 		    "(auto negotiation complete or link up) "
5583d81011f0Ssbehera 		    "soft bmsr 0x%x bmsr_int 0x%x",
5584d81011f0Ssbehera 		    bmsr.value, bmsr_ints.value));
5585d81011f0Ssbehera 
5586d81011f0Ssbehera 		if (nxgep->mac.portmode == PORT_1G_COPPER &&
5587d81011f0Ssbehera 		    param_arr[param_autoneg].value) {
558844961713Sgirish 			if ((status = nxge_mii_read(nxgep,
558952ccf843Smisaki 			    statsp->mac_stats.xcvr_portn,
559052ccf843Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->anar),
559152ccf843Smisaki 			    &anar.value)) != NXGE_OK)
559244961713Sgirish 				goto fail;
559344961713Sgirish 			if ((status = nxge_mii_read(nxgep,
559452ccf843Smisaki 			    statsp->mac_stats.xcvr_portn,
559552ccf843Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->anlpar),
559652ccf843Smisaki 			    &anlpar.value)) != NXGE_OK)
559744961713Sgirish 				goto fail;
559844961713Sgirish 			if ((status = nxge_mii_read(nxgep,
559952ccf843Smisaki 			    statsp->mac_stats.xcvr_portn,
560052ccf843Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->aner),
560152ccf843Smisaki 			    &aner.value)) != NXGE_OK)
560244961713Sgirish 				goto fail;
560344961713Sgirish 			statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able;
560444961713Sgirish 			statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4;
560544961713Sgirish 			statsp->mac_stats.lp_cap_100fdx =
560652ccf843Smisaki 			    anlpar.bits.cap_100fdx;
560744961713Sgirish 			statsp->mac_stats.lp_cap_100hdx =
560852ccf843Smisaki 			    anlpar.bits.cap_100hdx;
560944961713Sgirish 			statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx;
561044961713Sgirish 			statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx;
561144961713Sgirish 			statsp->mac_stats.lp_cap_asmpause =
561252ccf843Smisaki 			    anlpar.bits.cap_asmpause;
561344961713Sgirish 			statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause;
561444961713Sgirish 			an_common.value = anar.value & anlpar.value;
561544961713Sgirish 			if (param_arr[param_anar_1000fdx].value ||
561652ccf843Smisaki 			    param_arr[param_anar_1000hdx].value) {
561744961713Sgirish 				if ((status = nxge_mii_read(nxgep,
561852ccf843Smisaki 				    statsp->mac_stats.xcvr_portn,
561952ccf843Smisaki 				    (uint8_t)(uint64_t)(&mii_regs->gsr),
562052ccf843Smisaki 				    &gsr.value)) != NXGE_OK)
562144961713Sgirish 					goto fail;
562244961713Sgirish 				statsp->mac_stats.lp_cap_1000fdx =
562352ccf843Smisaki 				    gsr.bits.link_1000fdx;
562444961713Sgirish 				statsp->mac_stats.lp_cap_1000hdx =
562552ccf843Smisaki 				    gsr.bits.link_1000hdx;
562644961713Sgirish 				if (param_arr[param_anar_1000fdx].value &&
562752ccf843Smisaki 				    gsr.bits.link_1000fdx) {
562844961713Sgirish 					statsp->mac_stats.link_speed = 1000;
562944961713Sgirish 					statsp->mac_stats.link_duplex = 2;
563044961713Sgirish 				} else if (
563152ccf843Smisaki 				    param_arr[param_anar_1000hdx].value &&
563252ccf843Smisaki 				    gsr.bits.link_1000hdx) {
563344961713Sgirish 					statsp->mac_stats.link_speed = 1000;
563444961713Sgirish 					statsp->mac_stats.link_duplex = 1;
563544961713Sgirish 				}
563644961713Sgirish 			}
563744961713Sgirish 			if ((an_common.value != 0) &&
563852ccf843Smisaki 			    !(statsp->mac_stats.link_speed)) {
563944961713Sgirish 				if (an_common.bits.cap_100T4) {
564044961713Sgirish 					statsp->mac_stats.link_T4 = 1;
564144961713Sgirish 					statsp->mac_stats.link_speed = 100;
564244961713Sgirish 					statsp->mac_stats.link_duplex = 1;
564344961713Sgirish 				} else if (an_common.bits.cap_100fdx) {
564444961713Sgirish 					statsp->mac_stats.link_speed = 100;
564544961713Sgirish 					statsp->mac_stats.link_duplex = 2;
564644961713Sgirish 				} else if (an_common.bits.cap_100hdx) {
564744961713Sgirish 					statsp->mac_stats.link_speed = 100;
564844961713Sgirish 					statsp->mac_stats.link_duplex = 1;
564944961713Sgirish 				} else if (an_common.bits.cap_10fdx) {
565044961713Sgirish 					statsp->mac_stats.link_speed = 10;
565144961713Sgirish 					statsp->mac_stats.link_duplex = 2;
565244961713Sgirish 				} else if (an_common.bits.cap_10hdx) {
565344961713Sgirish 					statsp->mac_stats.link_speed = 10;
565444961713Sgirish 					statsp->mac_stats.link_duplex = 1;
565544961713Sgirish 				} else {
565644961713Sgirish 					goto fail;
565744961713Sgirish 				}
565844961713Sgirish 			}
565944961713Sgirish 			if (statsp->mac_stats.link_duplex != 1) {
566052ccf843Smisaki 				int	link_pause;
566152ccf843Smisaki 				int	cp, lcp;
566252ccf843Smisaki 
566344961713Sgirish 				statsp->mac_stats.link_asmpause =
566452ccf843Smisaki 				    an_common.bits.cap_asmpause;
566552ccf843Smisaki 				cp = statsp->mac_stats.cap_pause;
566652ccf843Smisaki 				lcp = statsp->mac_stats.lp_cap_pause;
566752ccf843Smisaki 				if (statsp->mac_stats.link_asmpause) {
566852ccf843Smisaki 					if ((cp == 0) && (lcp == 1)) {
566952ccf843Smisaki 						link_pause = 0;
567052ccf843Smisaki 					} else {
567152ccf843Smisaki 						link_pause = 1;
567252ccf843Smisaki 					}
567352ccf843Smisaki 				} else {
567452ccf843Smisaki 					link_pause = an_common.bits.cap_pause;
567552ccf843Smisaki 				}
567652ccf843Smisaki 				statsp->mac_stats.link_pause = link_pause;
567744961713Sgirish 			}
5678d81011f0Ssbehera 		} else if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) {
5679d81011f0Ssbehera 			statsp->mac_stats.link_speed = 1000;
5680d81011f0Ssbehera 			statsp->mac_stats.link_duplex = 2;
568144961713Sgirish 		}
5682a3c5bd6dSspeer 	}
5683774da109Stc 	/* Initial link_notify, delay link down msg */
5684774da109Stc 	if (nxgep->link_notify && nxgep->nxge_mac_state == NXGE_MAC_STARTED &&
5685774da109Stc 	    (statsp->mac_stats.link_up == 1 || nxgep->link_check_count > 3)) {
5686a3c5bd6dSspeer 		*link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP :
568752ccf843Smisaki 		    LINK_IS_DOWN);
5688a3c5bd6dSspeer 		nxgep->link_notify = B_FALSE;
568944961713Sgirish 	}
569044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check"));
569144961713Sgirish 	return (NXGE_OK);
569244961713Sgirish fail:
569344961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
569452ccf843Smisaki 	    "nxge_mii_check: Unable to check MII"));
569544961713Sgirish 	return (status);
569644961713Sgirish }
569744961713Sgirish 
569800161856Syc /*
569900161856Syc  * Check PCS to see if there is any link status change.
570000161856Syc  * This function is called by PORT_1G_SERDES only.
570100161856Syc  */
570200161856Syc void
nxge_pcs_check(p_nxge_t nxgep,uint8_t portn,nxge_link_state_t * link_up)57032e59129aSraghus nxge_pcs_check(p_nxge_t nxgep, uint8_t portn, nxge_link_state_t *link_up)
57042e59129aSraghus {
57052e59129aSraghus 	p_nxge_stats_t	statsp;
57062e59129aSraghus 	boolean_t	linkup;
57072e59129aSraghus 
57082e59129aSraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_check"));
57092e59129aSraghus 
57102e59129aSraghus 	statsp = nxgep->statsp;
57112e59129aSraghus 	*link_up = LINK_NO_CHANGE;
57122e59129aSraghus 
57132e59129aSraghus 	(void) npi_mac_get_link_status(nxgep->npi_handle, portn, &linkup);
57142e59129aSraghus 	if (linkup) {
5715774da109Stc 		if ((nxgep->link_notify &&
5716774da109Stc 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
57172e59129aSraghus 		    nxgep->statsp->mac_stats.link_up == 0) {
57182e59129aSraghus 			statsp->mac_stats.link_up = 1;
57192e59129aSraghus 			statsp->mac_stats.link_speed = 1000;
57202e59129aSraghus 			statsp->mac_stats.link_duplex = 2;
57212e59129aSraghus 			*link_up = LINK_IS_UP;
57222e59129aSraghus 			nxgep->link_notify = B_FALSE;
57232e59129aSraghus 		}
57242e59129aSraghus 	} else {
5725774da109Stc 		if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
5726774da109Stc 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
57272e59129aSraghus 		    nxgep->statsp->mac_stats.link_up == 1) {
57282e59129aSraghus 			statsp->mac_stats.link_up = 0;
57292e59129aSraghus 			statsp->mac_stats.link_speed = 0;
57302e59129aSraghus 			statsp->mac_stats.link_duplex = 0;
57312e59129aSraghus 			*link_up = LINK_IS_DOWN;
57322e59129aSraghus 			nxgep->link_notify = B_FALSE;
57332e59129aSraghus 		}
57342e59129aSraghus 	}
57352e59129aSraghus 
57362e59129aSraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_check"));
57372e59129aSraghus }
57382e59129aSraghus 
573944961713Sgirish /* Add a multicast address entry into the HW hash table */
574044961713Sgirish 
574144961713Sgirish nxge_status_t
nxge_add_mcast_addr(p_nxge_t nxgep,struct ether_addr * addrp)574244961713Sgirish nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
574344961713Sgirish {
574444961713Sgirish 	uint32_t mchash;
574544961713Sgirish 	p_hash_filter_t hash_filter;
574644961713Sgirish 	uint16_t hash_bit;
574744961713Sgirish 	uint_t j;
574844961713Sgirish 	nxge_status_t status = NXGE_OK;
57490dc2366fSVenugopal Iyer 	npi_status_t rs;
575044961713Sgirish 
575144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr"));
575244961713Sgirish 
575344961713Sgirish 	RW_ENTER_WRITER(&nxgep->filter_lock);
575444961713Sgirish 	mchash = crc32_mchash(addrp);
575544961713Sgirish 	if (nxgep->hash_filter == NULL) {
575644961713Sgirish 		NXGE_DEBUG_MSG((NULL, STR_CTL,
575752ccf843Smisaki 		    "Allocating hash filter storage."));
575844961713Sgirish 		nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t),
575952ccf843Smisaki 		    KM_SLEEP);
576044961713Sgirish 	}
57610dc2366fSVenugopal Iyer 
576244961713Sgirish 	hash_filter = nxgep->hash_filter;
576344961713Sgirish 	j = mchash / HASH_REG_WIDTH;
576444961713Sgirish 	hash_bit = (1 << (mchash % HASH_REG_WIDTH));
576544961713Sgirish 	hash_filter->hash_filter_regs[j] |= hash_bit;
576644961713Sgirish 	hash_filter->hash_bit_ref_cnt[mchash]++;
576744961713Sgirish 	if (hash_filter->hash_bit_ref_cnt[mchash] == 1) {
576844961713Sgirish 		hash_filter->hash_ref_cnt++;
576944961713Sgirish 	}
577044961713Sgirish 
57710dc2366fSVenugopal Iyer 	rs = nxge_rx_mac_mcast_hash_table(nxgep);
57720dc2366fSVenugopal Iyer 	if (rs != NPI_SUCCESS)
57730dc2366fSVenugopal Iyer 		goto fail;
577444961713Sgirish 
57750dc2366fSVenugopal Iyer 	RW_EXIT(&nxgep->filter_lock);
577644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr"));
577744961713Sgirish 	return (NXGE_OK);
577844961713Sgirish fail:
577944961713Sgirish 	RW_EXIT(&nxgep->filter_lock);
578044961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: "
578152ccf843Smisaki 	    "Unable to add multicast address"));
578244961713Sgirish 	return (status);
578344961713Sgirish }
578444961713Sgirish 
578544961713Sgirish /* Remove a multicast address entry from the HW hash table */
578644961713Sgirish 
578744961713Sgirish nxge_status_t
nxge_del_mcast_addr(p_nxge_t nxgep,struct ether_addr * addrp)578844961713Sgirish nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
578944961713Sgirish {
579044961713Sgirish 	uint32_t mchash;
579144961713Sgirish 	p_hash_filter_t hash_filter;
579244961713Sgirish 	uint16_t hash_bit;
579344961713Sgirish 	uint_t j;
579444961713Sgirish 	nxge_status_t status = NXGE_OK;
57950dc2366fSVenugopal Iyer 	npi_status_t rs;
579644961713Sgirish 
579744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr"));
579844961713Sgirish 	RW_ENTER_WRITER(&nxgep->filter_lock);
579944961713Sgirish 	mchash = crc32_mchash(addrp);
580044961713Sgirish 	if (nxgep->hash_filter == NULL) {
580144961713Sgirish 		NXGE_DEBUG_MSG((NULL, STR_CTL,
580252ccf843Smisaki 		    "Hash filter already de_allocated."));
580344961713Sgirish 		RW_EXIT(&nxgep->filter_lock);
580444961713Sgirish 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
580544961713Sgirish 		return (NXGE_OK);
580644961713Sgirish 	}
580744961713Sgirish 	hash_filter = nxgep->hash_filter;
580844961713Sgirish 	hash_filter->hash_bit_ref_cnt[mchash]--;
580944961713Sgirish 	if (hash_filter->hash_bit_ref_cnt[mchash] == 0) {
581044961713Sgirish 		j = mchash / HASH_REG_WIDTH;
581144961713Sgirish 		hash_bit = (1 << (mchash % HASH_REG_WIDTH));
581244961713Sgirish 		hash_filter->hash_filter_regs[j] &= ~hash_bit;
581344961713Sgirish 		hash_filter->hash_ref_cnt--;
581444961713Sgirish 	}
58150dc2366fSVenugopal Iyer 
581644961713Sgirish 	if (hash_filter->hash_ref_cnt == 0) {
581744961713Sgirish 		NXGE_DEBUG_MSG((NULL, STR_CTL,
581852ccf843Smisaki 		    "De-allocating hash filter storage."));
581944961713Sgirish 		KMEM_FREE(hash_filter, sizeof (hash_filter_t));
582044961713Sgirish 		nxgep->hash_filter = NULL;
582144961713Sgirish 	}
582244961713Sgirish 
58230dc2366fSVenugopal Iyer 	rs = nxge_rx_mac_mcast_hash_table(nxgep);
58240dc2366fSVenugopal Iyer 	if (rs != NPI_SUCCESS)
58250dc2366fSVenugopal Iyer 		goto fail;
58260dc2366fSVenugopal Iyer 
582744961713Sgirish 	RW_EXIT(&nxgep->filter_lock);
582844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
582944961713Sgirish 
583044961713Sgirish 	return (NXGE_OK);
583144961713Sgirish fail:
583244961713Sgirish 	RW_EXIT(&nxgep->filter_lock);
583344961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: "
583452ccf843Smisaki 	    "Unable to remove multicast address"));
583544961713Sgirish 
583644961713Sgirish 	return (status);
583744961713Sgirish }
583844961713Sgirish 
583944961713Sgirish /* Set MAC address into MAC address HW registers */
584044961713Sgirish 
584144961713Sgirish nxge_status_t
nxge_set_mac_addr(p_nxge_t nxgep,struct ether_addr * addrp)584244961713Sgirish nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp)
584344961713Sgirish {
584444961713Sgirish 	nxge_status_t status = NXGE_OK;
584544961713Sgirish 
584644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr"));
584744961713Sgirish 
584844961713Sgirish 	MUTEX_ENTER(&nxgep->ouraddr_lock);
584944961713Sgirish 	/*
585044961713Sgirish 	 * Exit if the address is same as ouraddr or multicast or broadcast
585144961713Sgirish 	 */
585244961713Sgirish 	if (((addrp->ether_addr_octet[0] & 01) == 1) ||
585352ccf843Smisaki 	    (ether_cmp(addrp, &etherbroadcastaddr) == 0) ||
585452ccf843Smisaki 	    (ether_cmp(addrp, &nxgep->ouraddr) == 0)) {
585544961713Sgirish 		goto nxge_set_mac_addr_exit;
585644961713Sgirish 	}
585744961713Sgirish 	nxgep->ouraddr = *addrp;
585844961713Sgirish 	/*
585944961713Sgirish 	 * Set new interface local address and re-init device.
586044961713Sgirish 	 * This is destructive to any other streams attached
586144961713Sgirish 	 * to this device.
586244961713Sgirish 	 */
586344961713Sgirish 	RW_ENTER_WRITER(&nxgep->filter_lock);
586444961713Sgirish 	if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
586544961713Sgirish 		goto fail;
586644961713Sgirish 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
586744961713Sgirish 		goto fail;
586844961713Sgirish 
586944961713Sgirish 	RW_EXIT(&nxgep->filter_lock);
587044961713Sgirish 	MUTEX_EXIT(&nxgep->ouraddr_lock);
587144961713Sgirish 	goto nxge_set_mac_addr_end;
587244961713Sgirish nxge_set_mac_addr_exit:
587344961713Sgirish 	MUTEX_EXIT(&nxgep->ouraddr_lock);
587444961713Sgirish nxge_set_mac_addr_end:
587544961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr"));
587644961713Sgirish 
587744961713Sgirish 	return (NXGE_OK);
587844961713Sgirish fail:
587944961713Sgirish 	MUTEX_EXIT(&nxgep->ouraddr_lock);
588044961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: "
588152ccf843Smisaki 	    "Unable to set mac address"));
588244961713Sgirish 	return (status);
588344961713Sgirish }
588444961713Sgirish 
588598ecde52Stm static
588698ecde52Stm check_link_state_t
nxge_check_link_stop(nxge_t * nxge)588700161856Syc nxge_check_link_stop(nxge_t *nxge)
588898ecde52Stm {
588998ecde52Stm 	/* If the poll has been cancelled, return STOP. */
589098ecde52Stm 	MUTEX_ENTER(&nxge->poll_lock);
589198ecde52Stm 	if (nxge->suspended || nxge->poll_state == LINK_MONITOR_STOPPING) {
589298ecde52Stm 		nxge->poll_state = LINK_MONITOR_STOP;
589398ecde52Stm 		nxge->nxge_link_poll_timerid = 0;
589498ecde52Stm 		cv_broadcast(&nxge->poll_cv);
589598ecde52Stm 		MUTEX_EXIT(&nxge->poll_lock);
589698ecde52Stm 
589798ecde52Stm 		NXGE_DEBUG_MSG((nxge, MAC_CTL,
589898ecde52Stm 		    "nxge_check_%s_link(port<%d>) stopped.",
589998ecde52Stm 		    nxge->mac.portmode == PORT_10G_FIBER ? "10g" : "mii",
590098ecde52Stm 		    nxge->mac.portnum));
590198ecde52Stm 		return (CHECK_LINK_STOP);
590298ecde52Stm 	}
590398ecde52Stm 	MUTEX_EXIT(&nxge->poll_lock);
590498ecde52Stm 
590598ecde52Stm 	return (CHECK_LINK_RESCHEDULE);
590698ecde52Stm }
590798ecde52Stm 
590800161856Syc /*
590900161856Syc  * Check status of MII (MIF or PCS) link.
591000161856Syc  * This function is called once per second, that is because this function
591100161856Syc  * calls nxge_link_monitor with LINK_MONITOR_START, which starts a timer to
591200161856Syc  * call this function recursively.
591300161856Syc  */
591459ac0c16Sdavemq static nxge_status_t
nxge_check_mii_link(p_nxge_t nxgep)591544961713Sgirish nxge_check_mii_link(p_nxge_t nxgep)
591644961713Sgirish {
591744961713Sgirish 	mii_bmsr_t bmsr_ints, bmsr_data;
591844961713Sgirish 	mii_anlpar_t anlpar;
591944961713Sgirish 	mii_gsr_t gsr;
592044961713Sgirish 	p_mii_regs_t mii_regs;
592144961713Sgirish 	nxge_status_t status = NXGE_OK;
592244961713Sgirish 	uint8_t portn;
5923a3c5bd6dSspeer 	nxge_link_state_t link_up;
592444961713Sgirish 
592598ecde52Stm 	if (nxgep->nxge_magic != NXGE_MAGIC)
592698ecde52Stm 		return (NXGE_ERROR);
592798ecde52Stm 
592898ecde52Stm 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
592998ecde52Stm 		return (NXGE_OK);
593098ecde52Stm 
593144961713Sgirish 	portn = nxgep->mac.portnum;
593244961713Sgirish 
593344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>",
593498ecde52Stm 	    portn));
593544961713Sgirish 
593644961713Sgirish 	mii_regs = NULL;
593744961713Sgirish 
593844961713Sgirish 	RW_ENTER_WRITER(&nxgep->filter_lock);
593944961713Sgirish 
594044961713Sgirish 	if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10)
594144961713Sgirish 		goto nxge_check_mii_link_exit;
594244961713Sgirish 
59432e59129aSraghus 	switch (nxgep->mac.portmode) {
59442e59129aSraghus 	default:
5945d81011f0Ssbehera 		bmsr_data.value = 0;
594644961713Sgirish 		if ((status = nxge_mii_read(nxgep,
59472e59129aSraghus 		    nxgep->statsp->mac_stats.xcvr_portn,
59482e59129aSraghus 		    (uint8_t)(uint64_t)(&mii_regs->bmsr),
59492e59129aSraghus 		    &bmsr_data.value)) != NXGE_OK) {
595044961713Sgirish 			goto fail;
595144961713Sgirish 		}
595244961713Sgirish 
5953d81011f0Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5954d81011f0Ssbehera 		    "==> nxge_check_mii_link port<0x%x> "
5955d81011f0Ssbehera 		    "RIGHT AFTER READ bmsr_data 0x%x (nxgep->bmsr 0x%x ",
59562d17280bSsbehera 		    portn, bmsr_data.value, nxgep->bmsr.value));
5957d81011f0Ssbehera 
59582e59129aSraghus 		if (nxgep->param_arr[param_autoneg].value) {
59592e59129aSraghus 			if ((status = nxge_mii_read(nxgep,
596052ccf843Smisaki 			    nxgep->statsp->mac_stats.xcvr_portn,
596152ccf843Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->gsr),
596252ccf843Smisaki 			    &gsr.value)) != NXGE_OK)
59632e59129aSraghus 				goto fail;
59642e59129aSraghus 			if ((status = nxge_mii_read(nxgep,
596552ccf843Smisaki 			    nxgep->statsp->mac_stats.xcvr_portn,
596652ccf843Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->anlpar),
596752ccf843Smisaki 			    &anlpar.value)) != NXGE_OK)
59682e59129aSraghus 				goto fail;
5969d81011f0Ssbehera 			if (nxgep->mac.portmode != PORT_1G_RGMII_FIBER) {
5970d81011f0Ssbehera 
5971d81011f0Ssbehera 				if (nxgep->statsp->mac_stats.link_up &&
5972d81011f0Ssbehera 				    ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^
5973d81011f0Ssbehera 				    gsr.bits.link_1000fdx) ||
5974d81011f0Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_1000hdx ^
5975d81011f0Ssbehera 				    gsr.bits.link_1000hdx) ||
5976d81011f0Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_100T4 ^
5977d81011f0Ssbehera 				    anlpar.bits.cap_100T4) ||
5978d81011f0Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_100fdx ^
5979d81011f0Ssbehera 				    anlpar.bits.cap_100fdx) ||
5980d81011f0Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_100hdx ^
5981d81011f0Ssbehera 				    anlpar.bits.cap_100hdx) ||
5982d81011f0Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_10fdx ^
5983d81011f0Ssbehera 				    anlpar.bits.cap_10fdx) ||
5984d81011f0Ssbehera 				    (nxgep->statsp->mac_stats.lp_cap_10hdx ^
5985d81011f0Ssbehera 				    anlpar.bits.cap_10hdx))) {
5986d81011f0Ssbehera 					bmsr_data.bits.link_status = 0;
5987d81011f0Ssbehera 				}
59882e59129aSraghus 			}
59892e59129aSraghus 		}
599044961713Sgirish 
59912e59129aSraghus 		/* Workaround for link down issue */
59922e59129aSraghus 		if (bmsr_data.value == 0) {
59932e59129aSraghus 			cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n");
59942e59129aSraghus 			goto nxge_check_mii_link_exit;
59952e59129aSraghus 		}
59962e59129aSraghus 
5997d81011f0Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5998d81011f0Ssbehera 		    "==> nxge_check_mii_link port<0x%x> :"
5999d81011f0Ssbehera 		    "BEFORE BMSR ^ nxgep->bmsr 0x%x bmsr_data 0x%x",
60002d17280bSsbehera 		    portn, nxgep->bmsr.value, bmsr_data.value));
6001d81011f0Ssbehera 
60022e59129aSraghus 		bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value;
60032e59129aSraghus 		nxgep->bmsr.value = bmsr_data.value;
6004d81011f0Ssbehera 
6005d81011f0Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
6006d81011f0Ssbehera 		    "==> nxge_check_mii_link port<0x%x> CALLING "
6007d81011f0Ssbehera 		    "bmsr_data 0x%x bmsr_ints.value 0x%x",
60082d17280bSsbehera 		    portn, bmsr_data.value, bmsr_ints.value));
6009d81011f0Ssbehera 
60102e59129aSraghus 		if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints,
60112e59129aSraghus 		    &link_up)) != NXGE_OK) {
60122e59129aSraghus 			goto fail;
60132e59129aSraghus 		}
60142e59129aSraghus 		break;
60152e59129aSraghus 
60162e59129aSraghus 	case PORT_1G_SERDES:
601700161856Syc 		/*
601800161856Syc 		 * Above default is for all cases except PORT_1G_SERDES.
601900161856Syc 		 * The default case gets information from the PHY, but a
602000161856Syc 		 * nxge whose portmode equals PORT_1G_SERDES does not
602100161856Syc 		 * have a PHY.
602200161856Syc 		 */
60232e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
60242e59129aSraghus 		    "==> nxge_check_mii_link port<%d> (SERDES)", portn));
602500161856Syc 		nxge_pcs_check(nxgep, portn, &link_up);
60262e59129aSraghus 		break;
60272e59129aSraghus 	}
602844961713Sgirish 
602944961713Sgirish nxge_check_mii_link_exit:
603044961713Sgirish 	RW_EXIT(&nxgep->filter_lock);
6031a3c5bd6dSspeer 	if (link_up == LINK_IS_UP) {
6032a3c5bd6dSspeer 		nxge_link_is_up(nxgep);
6033a3c5bd6dSspeer 	} else if (link_up == LINK_IS_DOWN) {
6034a3c5bd6dSspeer 		nxge_link_is_down(nxgep);
6035a3c5bd6dSspeer 	}
603644961713Sgirish 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
603744961713Sgirish 
603844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>",
603952ccf843Smisaki 	    portn));
604044961713Sgirish 	return (NXGE_OK);
604144961713Sgirish 
604244961713Sgirish fail:
604344961713Sgirish 	RW_EXIT(&nxgep->filter_lock);
604444961713Sgirish 
604544961713Sgirish 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
604644961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
604752ccf843Smisaki 	    "nxge_check_mii_link: Failed to check link port<%d>", portn));
604844961713Sgirish 	return (status);
604944961713Sgirish }
605044961713Sgirish 
605144961713Sgirish /*ARGSUSED*/
605259ac0c16Sdavemq static nxge_status_t
nxge_check_10g_link(p_nxge_t nxgep)605344961713Sgirish nxge_check_10g_link(p_nxge_t nxgep)
605444961713Sgirish {
605544961713Sgirish 	uint8_t		portn;
605644961713Sgirish 	nxge_status_t	status = NXGE_OK;
6057763fcc44Ssbehera 	boolean_t	link_up;
60582e59129aSraghus 	uint32_t	val;
60592e59129aSraghus 	npi_status_t	rs;
606044961713Sgirish 
606198ecde52Stm 	if (nxgep->nxge_magic != NXGE_MAGIC)
606298ecde52Stm 		return (NXGE_ERROR);
606398ecde52Stm 
606498ecde52Stm 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
606598ecde52Stm 		return (NXGE_OK);
606698ecde52Stm 
606744961713Sgirish 	portn = nxgep->mac.portnum;
6068d81011f0Ssbehera 	val = 0;
6069d81011f0Ssbehera 	rs = NPI_SUCCESS;
607044961713Sgirish 
607144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>",
607298ecde52Stm 	    portn));
607344961713Sgirish 
60742e59129aSraghus 	switch (nxgep->mac.portmode) {
60752e59129aSraghus 	default:
60762d17280bSsbehera 		/*
60772d17280bSsbehera 		 * Check if the phy is present in case of hot swappable phy
60782d17280bSsbehera 		 */
60792d17280bSsbehera 		if (nxgep->hot_swappable_phy) {
60802d17280bSsbehera 			boolean_t phy_present_now = B_FALSE;
60812d17280bSsbehera 
608289282175SSantwona Behera 			if (nxge_hswap_phy_present(nxgep, portn))
60832d17280bSsbehera 				phy_present_now = B_TRUE;
60842d17280bSsbehera 
60851c7408c9Stc 			/* Check back-to-back XAUI connect to detect Opus NEM */
60861c7408c9Stc 			rs = npi_xmac_xpcs_read(nxgep->npi_handle,
60871c7408c9Stc 			    nxgep->mac.portnum, XPCS_REG_STATUS, &val);
60881c7408c9Stc 			if (rs != 0)
60891c7408c9Stc 				goto fail;
60901c7408c9Stc 
60911c7408c9Stc 			link_up = B_FALSE;
60921c7408c9Stc 			if (val & XPCS_STATUS_LANE_ALIGN) {
60931c7408c9Stc 				link_up = B_TRUE;
60941c7408c9Stc 			}
60951c7408c9Stc 
60962d17280bSsbehera 			if (nxgep->phy_absent) {
60972d17280bSsbehera 				if (phy_present_now) {
60982d17280bSsbehera 				/*
60992d17280bSsbehera 				 * Detect, Initialize phy and do link up
61002d17280bSsbehera 				 * set xcvr vals, link_init, nxge_init
61012d17280bSsbehera 				 */
61022d17280bSsbehera 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61032d17280bSsbehera 					    "Hot swappable phy DETECTED!!"));
61042d17280bSsbehera 					nxgep->phy_absent = B_FALSE;
61052d17280bSsbehera 					(void) nxge_xcvr_find(nxgep);
61062d17280bSsbehera 					(void) nxge_link_init(nxgep);
61072d17280bSsbehera 					if (!(nxgep->drv_state &
61082d17280bSsbehera 					    STATE_HW_INITIALIZED)) {
61092d17280bSsbehera 						status = nxge_init(nxgep);
61102d17280bSsbehera 						if (status != NXGE_OK) {
61112d17280bSsbehera 							NXGE_ERROR_MSG((nxgep,
61122d17280bSsbehera 							    NXGE_ERR_CTL,
61132d17280bSsbehera 							    "Hot swappable "
61142d17280bSsbehera 							    "phy present, but"
61152d17280bSsbehera 							    " driver init"
61162d17280bSsbehera 							    "  failed..."));
61172d17280bSsbehera 							goto fail;
61182d17280bSsbehera 						}
61192d17280bSsbehera 					}
61201c7408c9Stc 				} else if (link_up) { /* XAUI linkup, no PHY */
612148056c53SMichael Speer 					/*
61221c7408c9Stc 					 * This is the back-to-back XAUI
61231c7408c9Stc 					 * connect case for Opus NEM.
61241c7408c9Stc 					 */
61251c7408c9Stc 					nxgep->statsp->mac_stats.xcvr_inuse =
61261c7408c9Stc 					    XPCS_XCVR;
61271c7408c9Stc 					nxgep->mac.portmode = PORT_10G_SERDES;
61281c7408c9Stc 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61291c7408c9Stc 					    "HSP 10G Serdes DETECTED!!"));
61301c7408c9Stc 					break;
61312d17280bSsbehera 				}
61322d17280bSsbehera 
6133774da109Stc 				if (nxgep->link_notify &&
6134774da109Stc 				    nxgep->link_check_count > 3 &&
6135774da109Stc 				    nxgep->nxge_mac_state == NXGE_MAC_STARTED ||
6136774da109Stc 				    nxgep->statsp->mac_stats.link_up == 1) {
6137774da109Stc 					nxgep->statsp->mac_stats.link_up = 0;
6138774da109Stc 					nxgep->statsp->mac_stats.link_speed = 0;
6139774da109Stc 					nxgep->statsp->mac_stats.link_duplex =
6140774da109Stc 					    0;
6141774da109Stc 
6142774da109Stc 					nxge_link_is_down(nxgep);
6143774da109Stc 					nxgep->link_notify = B_FALSE;
6144774da109Stc 				}
6145774da109Stc 
61462d17280bSsbehera 				goto start_link_check;
61472d17280bSsbehera 
61482d17280bSsbehera 			} else if (!phy_present_now) {
61492d17280bSsbehera 				/*
61502d17280bSsbehera 				 * Phy gone, bring link down reset xcvr vals
61512d17280bSsbehera 				 */
61522d17280bSsbehera 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61532d17280bSsbehera 				    "Hot swappable phy REMOVED!!"));
61542d17280bSsbehera 				nxgep->phy_absent = B_TRUE;
61552d17280bSsbehera 				nxgep->statsp->mac_stats.link_up = 0;
61562d17280bSsbehera 				nxgep->statsp->mac_stats.link_speed = 0;
61572d17280bSsbehera 				nxgep->statsp->mac_stats.link_duplex = 0;
61582d17280bSsbehera 				nxge_link_is_down(nxgep);
61592d17280bSsbehera 				nxgep->link_notify = B_FALSE;
61602d17280bSsbehera 
61612d17280bSsbehera 				(void) nxge_xcvr_find(nxgep);
61622d17280bSsbehera 
61632d17280bSsbehera 				goto start_link_check;
61642d17280bSsbehera 
61652d17280bSsbehera 			}
61662d17280bSsbehera 		}
616789282175SSantwona Behera 
616889282175SSantwona Behera 		switch (nxgep->chip_id) {
616989282175SSantwona Behera 		case MRVL88X201X_CHIP_ID:
617000161856Syc 			status = nxge_check_mrvl88x2011_link(nxgep, &link_up);
617189282175SSantwona Behera 			break;
617289282175SSantwona Behera 		case NLP2020_CHIP_ID:
617389282175SSantwona Behera 			status = nxge_check_nlp2020_link(nxgep, &link_up);
617489282175SSantwona Behera 			break;
617589282175SSantwona Behera 		default:
617652cdd236Ssbehera 			status = nxge_check_bcm8704_link(nxgep, &link_up);
617789282175SSantwona Behera 			break;
617852cdd236Ssbehera 		}
617989282175SSantwona Behera 
61802e59129aSraghus 		if (status != NXGE_OK)
61812e59129aSraghus 			goto fail;
61822e59129aSraghus 		break;
61832e59129aSraghus 	case PORT_10G_SERDES:
61842e59129aSraghus 		rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
6185763fcc44Ssbehera 		    XPCS_REG_STATUS, &val);
61862e59129aSraghus 		if (rs != 0)
61872e59129aSraghus 			goto fail;
61882e59129aSraghus 
61892e59129aSraghus 		link_up = B_FALSE;
6190763fcc44Ssbehera 		if (val & XPCS_STATUS_LANE_ALIGN) {
6191763fcc44Ssbehera 			link_up = B_TRUE;
61922e59129aSraghus 		}
61932e59129aSraghus 
61942e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61952e59129aSraghus 		    "==> nxge_check_10g_link port<%d> "
6196763fcc44Ssbehera 		    "XPCS_REG_STATUS2 0x%x link_up %d",
6197763fcc44Ssbehera 		    portn, val, link_up));
61982e59129aSraghus 
61992e59129aSraghus 		break;
62002e59129aSraghus 	}
620144961713Sgirish 
620244961713Sgirish 	if (link_up) {
6203774da109Stc 		if ((nxgep->link_notify &&
6204774da109Stc 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
620552ccf843Smisaki 		    nxgep->statsp->mac_stats.link_up == 0) {
620644961713Sgirish 			if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
620744961713Sgirish 				goto fail;
620844961713Sgirish 			nxgep->statsp->mac_stats.link_up = 1;
620944961713Sgirish 			nxgep->statsp->mac_stats.link_speed = 10000;
621044961713Sgirish 			nxgep->statsp->mac_stats.link_duplex = 2;
621144961713Sgirish 
621244961713Sgirish 			nxge_link_is_up(nxgep);
6213a3c5bd6dSspeer 			nxgep->link_notify = B_FALSE;
621444961713Sgirish 		}
621544961713Sgirish 	} else {
6216774da109Stc 		if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
6217774da109Stc 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
621852ccf843Smisaki 		    nxgep->statsp->mac_stats.link_up == 1) {
621944961713Sgirish 			if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
622044961713Sgirish 				goto fail;
622144961713Sgirish 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
622252ccf843Smisaki 			    "Link down cable problem"));
622344961713Sgirish 			nxgep->statsp->mac_stats.link_up = 0;
622444961713Sgirish 			nxgep->statsp->mac_stats.link_speed = 0;
622544961713Sgirish 			nxgep->statsp->mac_stats.link_duplex = 0;
622644961713Sgirish 
622744961713Sgirish 			nxge_link_is_down(nxgep);
6228a3c5bd6dSspeer 			nxgep->link_notify = B_FALSE;
62291c7408c9Stc 
62301c7408c9Stc 			if (nxgep->mac.portmode == PORT_10G_SERDES) {
62311c7408c9Stc 				/*
62321c7408c9Stc 				 * NEM was unplugged, set up xcvr table
62331c7408c9Stc 				 * to find another xcvr in the future.
62341c7408c9Stc 				 */
62351c7408c9Stc 				(void) nxge_xcvr_find(nxgep);
62361c7408c9Stc 			}
623744961713Sgirish 		}
623844961713Sgirish 	}
623944961713Sgirish 
62402d17280bSsbehera start_link_check:
624144961713Sgirish 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
624244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>",
624398ecde52Stm 	    portn));
624444961713Sgirish 	return (NXGE_OK);
624544961713Sgirish 
624644961713Sgirish fail:
624798ecde52Stm 	(void) nxge_check_link_stop(nxgep);
624898ecde52Stm 
624944961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
625098ecde52Stm 	    "nxge_check_10g_link: Failed to check link port<%d>",
625198ecde52Stm 	    portn));
625244961713Sgirish 	return (status);
625344961713Sgirish }
625444961713Sgirish 
625544961713Sgirish 
625644961713Sgirish /* Declare link down */
625744961713Sgirish 
625844961713Sgirish void
nxge_link_is_down(p_nxge_t nxgep)625944961713Sgirish nxge_link_is_down(p_nxge_t nxgep)
626044961713Sgirish {
626159ac0c16Sdavemq 	p_nxge_stats_t statsp;
626259ac0c16Sdavemq 	char link_stat_msg[64];
626359ac0c16Sdavemq 
626444961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down"));
626544961713Sgirish 
626659ac0c16Sdavemq 	statsp = nxgep->statsp;
626759ac0c16Sdavemq 	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is down",
626859ac0c16Sdavemq 	    statsp->mac_stats.xcvr_portn);
626959ac0c16Sdavemq 
627059ac0c16Sdavemq 	if (nxge_no_msg == B_FALSE) {
627159ac0c16Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
627259ac0c16Sdavemq 	}
627359ac0c16Sdavemq 
627444961713Sgirish 	mac_link_update(nxgep->mach, LINK_STATE_DOWN);
627544961713Sgirish 
627644961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down"));
627744961713Sgirish }
627844961713Sgirish 
627944961713Sgirish /* Declare link up */
628044961713Sgirish 
628144961713Sgirish void
nxge_link_is_up(p_nxge_t nxgep)628244961713Sgirish nxge_link_is_up(p_nxge_t nxgep)
628344961713Sgirish {
628459ac0c16Sdavemq 	p_nxge_stats_t statsp;
628559ac0c16Sdavemq 	char link_stat_msg[64];
628644961713Sgirish 	uint32_t val;
628744961713Sgirish 
628844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up"));
628944961713Sgirish 
629059ac0c16Sdavemq 	statsp = nxgep->statsp;
629159ac0c16Sdavemq 	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is up %d Mbps ",
629259ac0c16Sdavemq 	    statsp->mac_stats.xcvr_portn,
629359ac0c16Sdavemq 	    statsp->mac_stats.link_speed);
629459ac0c16Sdavemq 
629559ac0c16Sdavemq 	if (statsp->mac_stats.link_T4)
629659ac0c16Sdavemq 		(void) strcat(link_stat_msg, "T4");
629759ac0c16Sdavemq 	else if (statsp->mac_stats.link_duplex == 2)
629859ac0c16Sdavemq 		(void) strcat(link_stat_msg, "full duplex");
629959ac0c16Sdavemq 	else
630059ac0c16Sdavemq 		(void) strcat(link_stat_msg, "half duplex");
630159ac0c16Sdavemq 
630244961713Sgirish 
630344961713Sgirish 	/* Clean up symbol errors incurred during link transition */
63042e59129aSraghus 	if ((nxgep->mac.portmode == PORT_10G_FIBER) ||
630589282175SSantwona Behera 	    (nxgep->mac.portmode == PORT_10G_COPPER) ||
63062e59129aSraghus 	    (nxgep->mac.portmode == PORT_10G_SERDES)) {
630744961713Sgirish 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
630852ccf843Smisaki 		    XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
630944961713Sgirish 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
631052ccf843Smisaki 		    XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
631144961713Sgirish 	}
631244961713Sgirish 
631300161856Syc 	/*
631400161856Syc 	 * If the driver was plumbed without a link (therefore auto-negotiation
631500161856Syc 	 * could not complete), the driver will detect a link up when a cable
631600161856Syc 	 * conneting to a link partner is plugged into the port. By the time
631700161856Syc 	 * link-up is detected, auto-negotiation should have completed (The
631800161856Syc 	 * TN1010 tries to contact a link partner every 8~24ms). Here we re-
631900161856Syc 	 * configure the Neptune/NIU according to the newly negotiated speed.
632000161856Syc 	 * This is necessary only for the TN1010 basad device because only the
632100161856Syc 	 * TN1010 supports dual speeds.
632200161856Syc 	 */
632300161856Syc 	if (nxgep->mac.portmode == PORT_1G_TN1010 ||
632400161856Syc 	    nxgep->mac.portmode == PORT_10G_TN1010) {
632500161856Syc 
632600161856Syc 		(void) nxge_set_tn1010_param(nxgep);
632700161856Syc 
632800161856Syc 		/*
632900161856Syc 		 * nxge_xcvr_find calls nxge_get_xcvr_type (which sets
633000161856Syc 		 * nxgep->portmode) and nxge_setup_xcvr_table (which sets
633100161856Syc 		 * the nxgep->xcvr to the proper nxge_xcvr_table_t struct).
633200161856Syc 		 */
633300161856Syc 		if (nxge_xcvr_find(nxgep) != NXGE_OK) {
633400161856Syc 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
633500161856Syc 			    "nxge_link_is_up: nxge_xcvr_find failed"));
633600161856Syc 		}
633700161856Syc 
633800161856Syc 		/* nxge_link_init calls nxge_xcvr_init and nxge_serdes_init */
633900161856Syc 		if (nxge_link_init(nxgep) != NXGE_OK) {
634000161856Syc 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
634100161856Syc 			    "nxge_link_is_up: nxge_link_init failed"));
634200161856Syc 		}
634300161856Syc 
634400161856Syc 		/*
634500161856Syc 		 * nxge_mac_init calls many subroutines including
634600161856Syc 		 * nxge_xif_init which sets XGMII or GMII mode
634700161856Syc 		 */
634800161856Syc 		if (nxge_mac_init(nxgep) != NXGE_OK) {
634900161856Syc 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
635000161856Syc 			    "nxge_link_is_up: nxge_mac_init failed"));
635100161856Syc 		}
635200161856Syc 	} else {
635300161856Syc 		(void) nxge_xif_init(nxgep);
635400161856Syc 	}
635500161856Syc 
635659ac0c16Sdavemq 	if (nxge_no_msg == B_FALSE) {
635759ac0c16Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
635859ac0c16Sdavemq 	}
635959ac0c16Sdavemq 
636044961713Sgirish 	mac_link_update(nxgep->mach, LINK_STATE_UP);
636144961713Sgirish 
636244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up"));
636344961713Sgirish }
636444961713Sgirish 
636500161856Syc #ifdef NXGE_DEBUG
636600161856Syc /* Dump all TN1010 Status registers */
636700161856Syc static void
nxge_dump_tn1010_status_regs(p_nxge_t nxgep)636800161856Syc nxge_dump_tn1010_status_regs(p_nxge_t nxgep)
636900161856Syc {
637000161856Syc 	uint16_t val;
637100161856Syc 
637200161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
637300161856Syc 	    TN1010_PMA_PMD_DEV_ADDR, 1, &val);
637400161856Syc 	cmn_err(CE_NOTE, "PMA status1 = 0x%x", val);
637500161856Syc 
637600161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
637700161856Syc 	    TN1010_PMA_PMD_DEV_ADDR, 8, &val);
637800161856Syc 	cmn_err(CE_NOTE, "PMA status2 = 0x%x", val);
637900161856Syc 
638000161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
638100161856Syc 	    TN1010_PMA_PMD_DEV_ADDR, 129, &val);
638200161856Syc 	cmn_err(CE_NOTE, "10BASET-T status = 0x%x", val);
638300161856Syc 
638400161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
638500161856Syc 	    TN1010_PCS_DEV_ADDR, 1, &val);
638600161856Syc 	cmn_err(CE_NOTE, "PCS status1 = 0x%x", val);
638700161856Syc 
638800161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
638900161856Syc 	    TN1010_PCS_DEV_ADDR, 8, &val);
639000161856Syc 	cmn_err(CE_NOTE, "PCS status2 = 0x%x", val);
639100161856Syc 
639200161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
639300161856Syc 	    TN1010_PCS_DEV_ADDR, 32, &val);
639400161856Syc 	cmn_err(CE_NOTE, "10GBASE-R status1 = 0x%x", val);
639500161856Syc 
639600161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
639700161856Syc 	    TN1010_PCS_DEV_ADDR, 33, &val);
639800161856Syc 	cmn_err(CE_NOTE, "10GBASE-R Status2 = 0x%x", val);
639900161856Syc 
640000161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
640100161856Syc 	    TN1010_PHYXS_DEV_ADDR, 1, &val);
640200161856Syc 	cmn_err(CE_NOTE, "PHYXS status1 = 0x%x", val);
640300161856Syc 
640400161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
640500161856Syc 	    TN1010_PHYXS_DEV_ADDR, 8, &val);
640600161856Syc 	cmn_err(CE_NOTE, "PHYXS status2 = 0x%x", val);
640700161856Syc 
640800161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
640900161856Syc 	    TN1010_PHYXS_DEV_ADDR, 24, &val);
641000161856Syc 	cmn_err(CE_NOTE, "XGXS Lane status = 0x%x", val);
641100161856Syc 
641200161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
641300161856Syc 	    TN1010_AUTONEG_DEV_ADDR, 1, &val);
641400161856Syc 	cmn_err(CE_NOTE, "Autoneg status = 0x%x", val);
641500161856Syc 
641600161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
641700161856Syc 	    TN1010_AUTONEG_DEV_ADDR, 33, &val);
641800161856Syc 	cmn_err(CE_NOTE, "10Gbase-T An status = 0x%x", val);
641900161856Syc 
642000161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
642100161856Syc 	    TN1010_VENDOR_MMD1_DEV_ADDR, 1, &val);
642200161856Syc 	cmn_err(CE_NOTE, "TN1010 status = 0x%x", val);
642300161856Syc 
642400161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
642500161856Syc 	    TN1010_VENDOR_MMD1_DEV_ADDR, 8, &val);
642600161856Syc 	cmn_err(CE_NOTE, "Device status = 0x%x", val);
642700161856Syc 
642800161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
642900161856Syc 	    TN1010_VENDOR_MMD1_DEV_ADDR, 16, &val);
643000161856Syc 	cmn_err(CE_NOTE, "DDR status = 0x%x", val);
643100161856Syc 
643200161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
643300161856Syc 	    TN1010_VENDOR_MMD1_DEV_ADDR, 17, &val);
643400161856Syc 	cmn_err(CE_NOTE, "DDR fault status = 0x%x", val);
643500161856Syc 
643600161856Syc 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
643700161856Syc 	    TN1010_VENDOR_MMD1_DEV_ADDR, 11, &val);
643800161856Syc 	cmn_err(CE_NOTE, "Firmware Revision = 0x%x  Major = 0x%x Minor = 0x%x",
643900161856Syc 	    val,  (val & 0xFF00) >> 8, val & 0x00FF);
644000161856Syc }
644100161856Syc #endif
644200161856Syc 
644344961713Sgirish /*
644444961713Sgirish  * Calculate the bit in the multicast address filter
644544961713Sgirish  * that selects the given * address.
644644961713Sgirish  * Note: For GEM, the last 8-bits are used.
644744961713Sgirish  */
644844961713Sgirish uint32_t
crc32_mchash(p_ether_addr_t addr)644944961713Sgirish crc32_mchash(p_ether_addr_t addr)
645044961713Sgirish {
645144961713Sgirish 	uint8_t *cp;
645244961713Sgirish 	uint32_t crc;
645344961713Sgirish 	uint32_t c;
645444961713Sgirish 	int byte;
645544961713Sgirish 	int bit;
645644961713Sgirish 
645744961713Sgirish 	cp = (uint8_t *)addr;
645844961713Sgirish 	crc = (uint32_t)0xffffffff;
645944961713Sgirish 	for (byte = 0; byte < 6; byte++) {
646044961713Sgirish 		c = (uint32_t)cp[byte];
646144961713Sgirish 		for (bit = 0; bit < 8; bit++) {
646244961713Sgirish 			if ((c & 0x1) ^ (crc & 0x1))
646344961713Sgirish 				crc = (crc >> 1)^0xedb88320;
646444961713Sgirish 			else
646544961713Sgirish 				crc = (crc >> 1);
646644961713Sgirish 			c >>= 1;
646744961713Sgirish 		}
646844961713Sgirish 	}
646944961713Sgirish 	return ((~crc) >> (32 - HASH_BITS));
647044961713Sgirish }
647144961713Sgirish 
647244961713Sgirish /* Reset serdes */
647344961713Sgirish 
647444961713Sgirish nxge_status_t
nxge_serdes_reset(p_nxge_t nxgep)647544961713Sgirish nxge_serdes_reset(p_nxge_t nxgep)
647644961713Sgirish {
647744961713Sgirish 	npi_handle_t		handle;
647844961713Sgirish 
647944961713Sgirish 	handle = nxgep->npi_handle;
648044961713Sgirish 
648144961713Sgirish 	ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1);
648244961713Sgirish 	drv_usecwait(500);
648344961713Sgirish 	ESR_REG_WR(handle, ESR_CONFIG_REG, 0);
648444961713Sgirish 
648544961713Sgirish 	return (NXGE_OK);
648644961713Sgirish }
648744961713Sgirish 
648800161856Syc /*
648900161856Syc  * This function monitors link status using interrupt or polling.
649000161856Syc  * It calls nxgep->xcvr.check_link, a member function of
649100161856Syc  * nxge_xcvr_table_t. But nxgep->xcvr.check_link calls this
649200161856Syc  * function back, that is why the check_link routine is
649300161856Syc  * executed periodically.
649400161856Syc  */
649544961713Sgirish nxge_status_t
nxge_link_monitor(p_nxge_t nxgep,link_mon_enable_t enable)649644961713Sgirish nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable)
649744961713Sgirish {
649844961713Sgirish 	nxge_status_t status = NXGE_OK;
649944961713Sgirish 
6500678453a8Sspeer 	/* If we are a guest domain driver, don't bother. */
6501678453a8Sspeer 	if (isLDOMguest(nxgep))
6502678453a8Sspeer 		return (status);
6503678453a8Sspeer 
650444961713Sgirish 	/*
650598ecde52Stm 	 * Return immediately if this is an imaginary XMAC port.
650698ecde52Stm 	 * (At least, we don't have 4-port XMAC cards yet.)
650744961713Sgirish 	 */
65082e59129aSraghus 	if ((nxgep->mac.portmode == PORT_10G_FIBER ||
650989282175SSantwona Behera 	    nxgep->mac.portmode == PORT_10G_COPPER ||
65102e59129aSraghus 	    nxgep->mac.portmode == PORT_10G_SERDES) &&
65112e59129aSraghus 	    (nxgep->mac.portnum > 1))
651244961713Sgirish 		return (NXGE_OK);
651344961713Sgirish 
651444961713Sgirish 	if (nxgep->statsp == NULL) {
651544961713Sgirish 		/* stats has not been allocated. */
651644961713Sgirish 		return (NXGE_OK);
651744961713Sgirish 	}
6518321febdeSsbehera 	/* Don't check link if we're in internal loopback mode */
6519321febdeSsbehera 	if (nxgep->statsp->port_stats.lb_mode >= nxge_lb_serdes10g)
652044961713Sgirish 		return (NXGE_OK);
652144961713Sgirish 
652244961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
652398ecde52Stm 	    "==> nxge_link_monitor port<%d> enable=%d",
652498ecde52Stm 	    nxgep->mac.portnum, enable));
652544961713Sgirish 	if (enable == LINK_MONITOR_START) {
652644961713Sgirish 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
652744961713Sgirish 			if ((status = nxge_link_intr(nxgep, LINK_INTR_START))
652898ecde52Stm 			    != NXGE_OK)
652944961713Sgirish 				goto fail;
653044961713Sgirish 		} else {
653198ecde52Stm 			timeout_id_t timerid;
653200161856Syc 			/*
653300161856Syc 			 * check_link_stop means "Stop the link check", so
653400161856Syc 			 * we return without starting the timer.
653500161856Syc 			 */
653698ecde52Stm 			if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
653798ecde52Stm 				return (NXGE_OK);
653898ecde52Stm 
653900161856Syc 			/*
654000161856Syc 			 * Otherwise fire the timer for the nxge to check
654100161856Syc 			 * the link using the check_link function
654200161856Syc 			 * of the nxge_xcvr_table and pass "nxgep" as the
654300161856Syc 			 * argument to the check_link function.
654400161856Syc 			 */
654559ac0c16Sdavemq 			if (nxgep->xcvr.check_link) {
654691f84442SToomas Soome 				timerid = timeout((fptrv_t)(uintptr_t)
654791f84442SToomas Soome 				    (nxgep->xcvr.check_link),
654898ecde52Stm 				    nxgep,
654998ecde52Stm 				    drv_usectohz(LINK_MONITOR_PERIOD));
655059ac0c16Sdavemq 				MUTEX_ENTER(&nxgep->poll_lock);
655159ac0c16Sdavemq 				nxgep->nxge_link_poll_timerid = timerid;
655259ac0c16Sdavemq 				MUTEX_EXIT(&nxgep->poll_lock);
6553774da109Stc 				nxgep->link_check_count ++;
655459ac0c16Sdavemq 			} else {
655598ecde52Stm 				return (NXGE_ERROR);
655644961713Sgirish 			}
655744961713Sgirish 		}
655844961713Sgirish 	} else {
655944961713Sgirish 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
656044961713Sgirish 			if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP))
656198ecde52Stm 			    != NXGE_OK)
656244961713Sgirish 				goto fail;
656344961713Sgirish 		} else {
656498ecde52Stm 			clock_t rv;
656598ecde52Stm 
656698ecde52Stm 			MUTEX_ENTER(&nxgep->poll_lock);
656798ecde52Stm 
656898ecde52Stm 			/* If <timerid> == 0, the link monitor has */
656998ecde52Stm 			/* never been started, or just now stopped. */
657098ecde52Stm 			if (nxgep->nxge_link_poll_timerid == 0) {
657198ecde52Stm 				MUTEX_EXIT(&nxgep->poll_lock);
657298ecde52Stm 				return (NXGE_OK);
657398ecde52Stm 			}
657498ecde52Stm 
657598ecde52Stm 			nxgep->poll_state = LINK_MONITOR_STOPPING;
6576d3d50737SRafael Vanoni 			rv = cv_reltimedwait(&nxgep->poll_cv, &nxgep->poll_lock,
657798ecde52Stm 			    drv_usectohz(LM_WAIT_MULTIPLIER *
6578d3d50737SRafael Vanoni 			    LINK_MONITOR_PERIOD), TR_CLOCK_TICK);
657998ecde52Stm 			if (rv == -1) {
658098ecde52Stm 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
658198ecde52Stm 				    "==> stopping port %d: "
658298ecde52Stm 				    "cv_timedwait(%d) timed out",
658398ecde52Stm 				    nxgep->mac.portnum, nxgep->poll_state));
658498ecde52Stm 				nxgep->poll_state = LINK_MONITOR_STOP;
658544961713Sgirish 				nxgep->nxge_link_poll_timerid = 0;
658644961713Sgirish 			}
658798ecde52Stm 
658898ecde52Stm 			MUTEX_EXIT(&nxgep->poll_lock);
658944961713Sgirish 		}
659044961713Sgirish 	}
659144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
659298ecde52Stm 	    "<== nxge_link_monitor port<%d> enable=%d",
659398ecde52Stm 	    nxgep->mac.portnum, enable));
6594678453a8Sspeer 
659544961713Sgirish 	return (NXGE_OK);
659644961713Sgirish fail:
659744961713Sgirish 	return (status);
659800161856Syc 
659900161856Syc }
660000161856Syc 
660100161856Syc nxge_status_t
nxge_check_tn1010_link(p_nxge_t nxgep)660200161856Syc nxge_check_tn1010_link(p_nxge_t nxgep)
660300161856Syc {
660400161856Syc 	nxge_status_t	status = NXGE_OK;
660500161856Syc 	nxge_link_state_t link_up;
660600161856Syc 
660700161856Syc 	if (nxgep->nxge_magic != NXGE_MAGIC) {
660800161856Syc 		/* magic is 0 if driver is not attached */
660900161856Syc 		return (NXGE_ERROR);
661000161856Syc 	}
661100161856Syc 
661200161856Syc 	/* Link has been stopped, no need to continue */
661300161856Syc 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) {
661400161856Syc 		return (NXGE_OK);
661500161856Syc 	}
661600161856Syc 
661700161856Syc 	if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10)
661800161856Syc 		goto nxge_check_tn1010_link_exit;
661900161856Syc 
662000161856Syc 	if ((status = nxge_tn1010_check(nxgep, &link_up)) != NXGE_OK)
662100161856Syc 		goto fail;
662200161856Syc 
662300161856Syc nxge_check_tn1010_link_exit:
662400161856Syc 	if (link_up == LINK_IS_UP)
662500161856Syc 		nxge_link_is_up(nxgep);
662600161856Syc 	else if (link_up == LINK_IS_DOWN)
662700161856Syc 		nxge_link_is_down(nxgep);
662800161856Syc 
662900161856Syc 	/*
663000161856Syc 	 * nxge_link_monitor will call (nxgep->xcvr.check_link)
663100161856Syc 	 * which could be THIS function.
663200161856Syc 	 */
663300161856Syc 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
663400161856Syc 
663500161856Syc 	return (NXGE_OK);
663600161856Syc 
663700161856Syc fail:
663800161856Syc 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
663900161856Syc 
664000161856Syc 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
664100161856Syc 	    "nxge_check_tn1010_link: Failed to check link"));
664200161856Syc 	return (status);
664300161856Syc }
664400161856Syc 
664500161856Syc 
664600161856Syc /*
664700161856Syc  * Fill variable "link_up" with either LINK_IS_UP or LINK_IS_DOWN.
664800161856Syc  */
664900161856Syc static nxge_status_t
nxge_tn1010_check(p_nxge_t nxgep,nxge_link_state_t * link_up)665000161856Syc nxge_tn1010_check(p_nxge_t nxgep, nxge_link_state_t *link_up)
665100161856Syc {
665200161856Syc 	nxge_status_t	status = NXGE_OK;
665300161856Syc 	p_nxge_stats_t	statsp;
665400161856Syc 	uint8_t		phy_port_addr, portn;
665500161856Syc 	uint16_t	val;
665600161856Syc 
665700161856Syc 	*link_up = LINK_NO_CHANGE;
665800161856Syc 
665900161856Syc 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
666000161856Syc 	phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
666100161856Syc 	statsp = nxgep->statsp;
666200161856Syc 
666300161856Syc 	/* Check if link is up */
666400161856Syc 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
666500161856Syc 	    TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val))
666600161856Syc 	    != NXGE_OK) {
666700161856Syc 		goto fail;
666800161856Syc 	}
666900161856Syc 	/*
667000161856Syc 	 * nxge_link_is_up has called nxge_set_tn1010_param and set
667100161856Syc 	 * portmode and link_speed
667200161856Syc 	 */
667300161856Syc 	if (val & TN1010_AN_LINK_STAT_BIT) {
6674774da109Stc 		if ((nxgep->link_notify &&
6675774da109Stc 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
667600161856Syc 		    nxgep->statsp->mac_stats.link_up == 0) {
667700161856Syc 			statsp->mac_stats.link_up = 1;
667800161856Syc 			statsp->mac_stats.link_duplex = 2;
667900161856Syc 			*link_up = LINK_IS_UP;
668000161856Syc 			nxgep->link_notify = B_FALSE;
668100161856Syc 		}
668200161856Syc 	} else {
6683774da109Stc 		if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
6684774da109Stc 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
668500161856Syc 		    nxgep->statsp->mac_stats.link_up == 1) {
668600161856Syc 			statsp->mac_stats.link_up = 0;
668700161856Syc 			statsp->mac_stats.link_speed = 0;
668800161856Syc 			statsp->mac_stats.link_duplex = 0;
668900161856Syc 			*link_up = LINK_IS_DOWN;
669000161856Syc 			nxgep->link_notify = B_FALSE;
669100161856Syc 		}
669200161856Syc 	}
669300161856Syc 	return (NXGE_OK);
669400161856Syc 
669500161856Syc fail:
669600161856Syc 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
669700161856Syc 	    "nxge_tn1010_check: Unable to check TN1010"));
669800161856Syc 	return (status);
669944961713Sgirish }
670044961713Sgirish 
670100161856Syc 
670244961713Sgirish /* Set promiscous mode */
670344961713Sgirish 
670444961713Sgirish nxge_status_t
nxge_set_promisc(p_nxge_t nxgep,boolean_t on)670544961713Sgirish nxge_set_promisc(p_nxge_t nxgep, boolean_t on)
670644961713Sgirish {
670744961713Sgirish 	nxge_status_t status = NXGE_OK;
670844961713Sgirish 
670959ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on));
671044961713Sgirish 
671144961713Sgirish 	nxgep->filter.all_phys_cnt = ((on) ? 1 : 0);
671244961713Sgirish 
671344961713Sgirish 	RW_ENTER_WRITER(&nxgep->filter_lock);
671444961713Sgirish 
671544961713Sgirish 	if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) {
671644961713Sgirish 		goto fail;
671744961713Sgirish 	}
671844961713Sgirish 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) {
671944961713Sgirish 		goto fail;
672044961713Sgirish 	}
672144961713Sgirish 
672244961713Sgirish 	RW_EXIT(&nxgep->filter_lock);
672344961713Sgirish 
672444961713Sgirish 	if (on)
672544961713Sgirish 		nxgep->statsp->mac_stats.promisc = B_TRUE;
672644961713Sgirish 	else
672744961713Sgirish 		nxgep->statsp->mac_stats.promisc = B_FALSE;
672844961713Sgirish 
672944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc"));
673044961713Sgirish 
673144961713Sgirish 	return (NXGE_OK);
673244961713Sgirish fail:
673344961713Sgirish 	RW_EXIT(&nxgep->filter_lock);
673444961713Sgirish 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: "
673559ac0c16Sdavemq 	    "Unable to set promisc (%d)", on));
673644961713Sgirish 
673744961713Sgirish 	return (status);
673844961713Sgirish }
673944961713Sgirish 
674044961713Sgirish /*ARGSUSED*/
674144961713Sgirish uint_t
nxge_mif_intr(void * arg1,void * arg2)674244961713Sgirish nxge_mif_intr(void *arg1, void *arg2)
674344961713Sgirish {
674444961713Sgirish #ifdef	NXGE_DEBUG
674544961713Sgirish 	p_nxge_t		nxgep = (p_nxge_t)arg2;
674644961713Sgirish #endif
674744961713Sgirish #if NXGE_MIF
674844961713Sgirish 	p_nxge_ldv_t		ldvp = (p_nxge_ldv_t)arg1;
674944961713Sgirish 	uint32_t		status;
675044961713Sgirish 	npi_handle_t		handle;
675144961713Sgirish 	uint8_t			portn;
675244961713Sgirish 	p_nxge_stats_t		statsp;
675344961713Sgirish #endif
675444961713Sgirish 
675544961713Sgirish #ifdef	NXGE_MIF
675644961713Sgirish 	if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
675744961713Sgirish 		nxgep = ldvp->nxgep;
675844961713Sgirish 	}
675944961713Sgirish 	nxgep = ldvp->nxgep;
676044961713Sgirish #endif
676144961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr"));
676244961713Sgirish 
676344961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
676444961713Sgirish 	return (DDI_INTR_CLAIMED);
676544961713Sgirish 
676644961713Sgirish mif_intr_fail:
676744961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
676844961713Sgirish 	return (DDI_INTR_UNCLAIMED);
676944961713Sgirish }
677044961713Sgirish 
677144961713Sgirish /*ARGSUSED*/
677244961713Sgirish uint_t
nxge_mac_intr(void * arg1,void * arg2)677344961713Sgirish nxge_mac_intr(void *arg1, void *arg2)
677444961713Sgirish {
677544961713Sgirish 	p_nxge_t		nxgep = (p_nxge_t)arg2;
677644961713Sgirish 	p_nxge_ldv_t		ldvp = (p_nxge_ldv_t)arg1;
677744961713Sgirish 	p_nxge_ldg_t		ldgp;
677844961713Sgirish 	uint32_t		status;
677944961713Sgirish 	npi_handle_t		handle;
678044961713Sgirish 	uint8_t			portn;
678144961713Sgirish 	p_nxge_stats_t		statsp;
678244961713Sgirish 	npi_status_t		rs = NPI_SUCCESS;
678344961713Sgirish 
678444961713Sgirish 	if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
678544961713Sgirish 		nxgep = ldvp->nxgep;
678644961713Sgirish 	}
678744961713Sgirish 
678844961713Sgirish 	ldgp = ldvp->ldgp;
678944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: "
679059ac0c16Sdavemq 	    "group %d", ldgp->ldg));
679144961713Sgirish 
679244961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
679344961713Sgirish 	/*
679444961713Sgirish 	 * This interrupt handler is for a specific
679544961713Sgirish 	 * mac port.
679644961713Sgirish 	 */
679744961713Sgirish 	statsp = (p_nxge_stats_t)nxgep->statsp;
679844961713Sgirish 	portn = nxgep->mac.portnum;
679944961713Sgirish 
680044961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
680159ac0c16Sdavemq 	    "==> nxge_mac_intr: reading mac stats: port<%d>", portn));
680244961713Sgirish 
680344961713Sgirish 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
680444961713Sgirish 		rs = npi_xmac_tx_get_istatus(handle, portn,
680552ccf843Smisaki 		    (xmac_tx_iconfig_t *)&status);
680644961713Sgirish 		if (rs != NPI_SUCCESS)
680744961713Sgirish 			goto npi_fail;
680844961713Sgirish 		if (status & ICFG_XMAC_TX_ALL) {
680944961713Sgirish 			if (status & ICFG_XMAC_TX_UNDERRUN) {
681044961713Sgirish 				statsp->xmac_stats.tx_underflow_err++;
6811b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
681252ccf843Smisaki 				    NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
681344961713Sgirish 			}
681444961713Sgirish 			if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) {
681544961713Sgirish 				statsp->xmac_stats.tx_maxpktsize_err++;
6816f6485eecSyc 				/*
6817f6485eecSyc 				 * Do not send FMA ereport because this
6818f6485eecSyc 				 * error does not indicate HW failure.
6819f6485eecSyc 				 */
682044961713Sgirish 			}
682144961713Sgirish 			if (status & ICFG_XMAC_TX_OVERFLOW) {
682244961713Sgirish 				statsp->xmac_stats.tx_overflow_err++;
6823b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
682452ccf843Smisaki 				    NXGE_FM_EREPORT_TXMAC_OVERFLOW);
682544961713Sgirish 			}
682644961713Sgirish 			if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) {
682744961713Sgirish 				statsp->xmac_stats.tx_fifo_xfr_err++;
6828b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
682952ccf843Smisaki 				    NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR);
683044961713Sgirish 			}
683144961713Sgirish 			if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) {
683244961713Sgirish 				statsp->xmac_stats.tx_byte_cnt +=
683352ccf843Smisaki 				    XTXMAC_BYTE_CNT_MASK;
683444961713Sgirish 			}
683544961713Sgirish 			if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) {
683644961713Sgirish 				statsp->xmac_stats.tx_frame_cnt +=
683752ccf843Smisaki 				    XTXMAC_FRM_CNT_MASK;
683844961713Sgirish 			}
683944961713Sgirish 		}
684044961713Sgirish 
684144961713Sgirish 		rs = npi_xmac_rx_get_istatus(handle, portn,
684252ccf843Smisaki 		    (xmac_rx_iconfig_t *)&status);
684344961713Sgirish 		if (rs != NPI_SUCCESS)
684444961713Sgirish 			goto npi_fail;
684544961713Sgirish 		if (status & ICFG_XMAC_RX_ALL) {
684644961713Sgirish 			if (status & ICFG_XMAC_RX_OVERFLOW)
684744961713Sgirish 				statsp->xmac_stats.rx_overflow_err++;
684844961713Sgirish 			if (status & ICFG_XMAC_RX_UNDERFLOW) {
684944961713Sgirish 				statsp->xmac_stats.rx_underflow_err++;
6850b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
685152ccf843Smisaki 				    NXGE_FM_EREPORT_RXMAC_UNDERFLOW);
685244961713Sgirish 			}
6853f6485eecSyc 			/*
6854f6485eecSyc 			 * Do not send FMA ereport for the following 3 errors
6855f6485eecSyc 			 * because they do not indicate HW failures.
6856f6485eecSyc 			 */
685744961713Sgirish 			if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) {
685844961713Sgirish 				statsp->xmac_stats.rx_crc_err_cnt +=
685952ccf843Smisaki 				    XRXMAC_CRC_ER_CNT_MASK;
686044961713Sgirish 			}
686144961713Sgirish 			if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) {
686244961713Sgirish 				statsp->xmac_stats.rx_len_err_cnt +=
686352ccf843Smisaki 				    MAC_LEN_ER_CNT_MASK;
686444961713Sgirish 			}
686544961713Sgirish 			if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) {
686644961713Sgirish 				statsp->xmac_stats.rx_viol_err_cnt +=
686752ccf843Smisaki 				    XRXMAC_CD_VIO_CNT_MASK;
686844961713Sgirish 			}
686944961713Sgirish 			if (status & ICFG_XMAC_RX_OCT_CNT_EXP) {
687044961713Sgirish 				statsp->xmac_stats.rx_byte_cnt +=
687152ccf843Smisaki 				    XRXMAC_BT_CNT_MASK;
687244961713Sgirish 			}
687344961713Sgirish 			if (status & ICFG_XMAC_RX_HST_CNT1_EXP) {
687444961713Sgirish 				statsp->xmac_stats.rx_hist1_cnt +=
687552ccf843Smisaki 				    XRXMAC_HIST_CNT1_MASK;
687644961713Sgirish 			}
687744961713Sgirish 			if (status & ICFG_XMAC_RX_HST_CNT2_EXP) {
687844961713Sgirish 				statsp->xmac_stats.rx_hist2_cnt +=
687952ccf843Smisaki 				    XRXMAC_HIST_CNT2_MASK;
688044961713Sgirish 			}
688144961713Sgirish 			if (status & ICFG_XMAC_RX_HST_CNT3_EXP) {
688244961713Sgirish 				statsp->xmac_stats.rx_hist3_cnt +=
688352ccf843Smisaki 				    XRXMAC_HIST_CNT3_MASK;
688444961713Sgirish 			}
688544961713Sgirish 			if (status & ICFG_XMAC_RX_HST_CNT4_EXP) {
688644961713Sgirish 				statsp->xmac_stats.rx_hist4_cnt +=
688752ccf843Smisaki 				    XRXMAC_HIST_CNT4_MASK;
688844961713Sgirish 			}
688944961713Sgirish 			if (status & ICFG_XMAC_RX_HST_CNT5_EXP) {
689044961713Sgirish 				statsp->xmac_stats.rx_hist5_cnt +=
689152ccf843Smisaki 				    XRXMAC_HIST_CNT5_MASK;
689244961713Sgirish 			}
689344961713Sgirish 			if (status & ICFG_XMAC_RX_HST_CNT6_EXP) {
689444961713Sgirish 				statsp->xmac_stats.rx_hist6_cnt +=
689552ccf843Smisaki 				    XRXMAC_HIST_CNT6_MASK;
689644961713Sgirish 			}
689744961713Sgirish 			if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) {
689844961713Sgirish 				statsp->xmac_stats.rx_broadcast_cnt +=
689952ccf843Smisaki 				    XRXMAC_BC_FRM_CNT_MASK;
690044961713Sgirish 			}
690144961713Sgirish 			if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) {
690244961713Sgirish 				statsp->xmac_stats.rx_mult_cnt +=
690352ccf843Smisaki 				    XRXMAC_MC_FRM_CNT_MASK;
690444961713Sgirish 			}
6905f6485eecSyc 			/*
6906f6485eecSyc 			 * Do not send FMA ereport for the following 3 errors
6907f6485eecSyc 			 * because they do not indicate HW failures.
6908f6485eecSyc 			 */
690944961713Sgirish 			if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) {
691044961713Sgirish 				statsp->xmac_stats.rx_frag_cnt +=
691152ccf843Smisaki 				    XRXMAC_FRAG_CNT_MASK;
691244961713Sgirish 			}
691344961713Sgirish 			if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) {
691444961713Sgirish 				statsp->xmac_stats.rx_frame_align_err_cnt +=
691552ccf843Smisaki 				    XRXMAC_AL_ER_CNT_MASK;
691644961713Sgirish 			}
691744961713Sgirish 			if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) {
691844961713Sgirish 				statsp->xmac_stats.rx_linkfault_err_cnt +=
691952ccf843Smisaki 				    XMAC_LINK_FLT_CNT_MASK;
692044961713Sgirish 			}
692144961713Sgirish 			if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) {
692244961713Sgirish 				statsp->xmac_stats.rx_remotefault_err++;
692344961713Sgirish 			}
692444961713Sgirish 			if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) {
692544961713Sgirish 				statsp->xmac_stats.rx_localfault_err++;
692644961713Sgirish 			}
692744961713Sgirish 		}
692844961713Sgirish 
692944961713Sgirish 		rs = npi_xmac_ctl_get_istatus(handle, portn,
693052ccf843Smisaki 		    (xmac_ctl_iconfig_t *)&status);
693144961713Sgirish 		if (rs != NPI_SUCCESS)
693244961713Sgirish 			goto npi_fail;
693344961713Sgirish 		if (status & ICFG_XMAC_CTRL_ALL) {
693444961713Sgirish 			if (status & ICFG_XMAC_CTRL_PAUSE_RCVD)
693544961713Sgirish 				statsp->xmac_stats.rx_pause_cnt++;
693644961713Sgirish 			if (status & ICFG_XMAC_CTRL_PAUSE_STATE)
693744961713Sgirish 				statsp->xmac_stats.tx_pause_state++;
693844961713Sgirish 			if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE)
693944961713Sgirish 				statsp->xmac_stats.tx_nopause_state++;
694044961713Sgirish 		}
694144961713Sgirish 	} else if (nxgep->mac.porttype == PORT_TYPE_BMAC) {
694244961713Sgirish 		rs = npi_bmac_tx_get_istatus(handle, portn,
694352ccf843Smisaki 		    (bmac_tx_iconfig_t *)&status);
694444961713Sgirish 		if (rs != NPI_SUCCESS)
694544961713Sgirish 			goto npi_fail;
694644961713Sgirish 		if (status & ICFG_BMAC_TX_ALL) {
694744961713Sgirish 			if (status & ICFG_BMAC_TX_UNDERFLOW) {
694844961713Sgirish 				statsp->bmac_stats.tx_underrun_err++;
6949b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
695052ccf843Smisaki 				    NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
695144961713Sgirish 			}
695244961713Sgirish 			if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) {
695344961713Sgirish 				statsp->bmac_stats.tx_max_pkt_err++;
6954b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
695552ccf843Smisaki 				    NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR);
695644961713Sgirish 			}
695744961713Sgirish 			if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) {
695844961713Sgirish 				statsp->bmac_stats.tx_byte_cnt +=
695952ccf843Smisaki 				    BTXMAC_BYTE_CNT_MASK;
696044961713Sgirish 			}
696144961713Sgirish 			if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) {
696244961713Sgirish 				statsp->bmac_stats.tx_frame_cnt +=
696352ccf843Smisaki 				    BTXMAC_FRM_CNT_MASK;
696444961713Sgirish 			}
696544961713Sgirish 		}
696644961713Sgirish 
696744961713Sgirish 		rs = npi_bmac_rx_get_istatus(handle, portn,
696852ccf843Smisaki 		    (bmac_rx_iconfig_t *)&status);
696944961713Sgirish 		if (rs != NPI_SUCCESS)
697044961713Sgirish 			goto npi_fail;
697144961713Sgirish 		if (status & ICFG_BMAC_RX_ALL) {
697244961713Sgirish 			if (status & ICFG_BMAC_RX_OVERFLOW) {
697344961713Sgirish 				statsp->bmac_stats.rx_overflow_err++;
697444961713Sgirish 			}
697544961713Sgirish 			if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) {
697644961713Sgirish 				statsp->bmac_stats.rx_frame_cnt +=
697752ccf843Smisaki 				    RXMAC_FRM_CNT_MASK;
697844961713Sgirish 			}
697944961713Sgirish 			if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) {
698044961713Sgirish 				statsp->bmac_stats.rx_crc_err_cnt +=
698152ccf843Smisaki 				    BMAC_CRC_ER_CNT_MASK;
6982b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
698352ccf843Smisaki 				    NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP);
698444961713Sgirish 			}
698544961713Sgirish 			if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) {
698644961713Sgirish 				statsp->bmac_stats.rx_len_err_cnt +=
698752ccf843Smisaki 				    MAC_LEN_ER_CNT_MASK;
6988b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
698952ccf843Smisaki 				    NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP);
699044961713Sgirish 			}
69914df3b64dSToomas Soome 			if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP) {
699244961713Sgirish 				statsp->bmac_stats.rx_viol_err_cnt +=
699352ccf843Smisaki 				    BMAC_CD_VIO_CNT_MASK;
6994b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
699552ccf843Smisaki 				    NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP);
699644961713Sgirish 			}
699744961713Sgirish 			if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) {
699844961713Sgirish 				statsp->bmac_stats.rx_byte_cnt +=
699952ccf843Smisaki 				    BRXMAC_BYTE_CNT_MASK;
700044961713Sgirish 			}
700144961713Sgirish 			if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) {
700244961713Sgirish 				statsp->bmac_stats.rx_align_err_cnt +=
700352ccf843Smisaki 				    BMAC_AL_ER_CNT_MASK;
7004b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
700552ccf843Smisaki 				    NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP);
700644961713Sgirish 			}
700744961713Sgirish 
700844961713Sgirish 			rs = npi_bmac_ctl_get_istatus(handle, portn,
700952ccf843Smisaki 			    (bmac_ctl_iconfig_t *)&status);
701044961713Sgirish 			if (rs != NPI_SUCCESS)
701144961713Sgirish 				goto npi_fail;
701244961713Sgirish 
701344961713Sgirish 			if (status & ICFG_BMAC_CTL_ALL) {
701444961713Sgirish 				if (status & ICFG_BMAC_CTL_RCVPAUSE)
701544961713Sgirish 					statsp->bmac_stats.rx_pause_cnt++;
701644961713Sgirish 				if (status & ICFG_BMAC_CTL_INPAUSE_ST)
701744961713Sgirish 					statsp->bmac_stats.tx_pause_state++;
701844961713Sgirish 				if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST)
701944961713Sgirish 					statsp->bmac_stats.tx_nopause_state++;
702044961713Sgirish 			}
702144961713Sgirish 		}
70224df3b64dSToomas Soome 	}
702344961713Sgirish 
702444961713Sgirish 	if (ldgp->nldvs == 1) {
702544961713Sgirish 		(void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg,
702652ccf843Smisaki 		    B_TRUE, ldgp->ldg_timer);
702744961713Sgirish 	}
702844961713Sgirish 
702944961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
703044961713Sgirish 	return (DDI_INTR_CLAIMED);
703144961713Sgirish 
703244961713Sgirish npi_fail:
703344961713Sgirish 	NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
703444961713Sgirish 	return (DDI_INTR_UNCLAIMED);
703544961713Sgirish }
703644961713Sgirish 
703744961713Sgirish nxge_status_t
nxge_check_bcm8704_link(p_nxge_t nxgep,boolean_t * link_up)703844961713Sgirish nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up)
703944961713Sgirish {
704044961713Sgirish 	uint8_t		phy_port_addr;
704144961713Sgirish 	nxge_status_t	status = NXGE_OK;
704244961713Sgirish 	boolean_t	rx_sig_ok;
704344961713Sgirish 	boolean_t	pcs_blk_lock;
704444961713Sgirish 	boolean_t	link_align;
704544961713Sgirish 	uint16_t	val1, val2, val3;
704644961713Sgirish #ifdef	NXGE_DEBUG_SYMBOL_ERR
704744961713Sgirish 	uint16_t	val_debug;
70484df55fdeSJanie Lu 	uint32_t	val;
704944961713Sgirish #endif
705044961713Sgirish 
705144961713Sgirish 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
705244961713Sgirish 
705344961713Sgirish #ifdef	NXGE_DEBUG_SYMBOL_ERR
705444961713Sgirish 	/* Check Device 3 Register Device 3 0xC809 */
705544961713Sgirish 	(void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug);
705644961713Sgirish 	if ((val_debug & ~0x200) != 0) {
705744961713Sgirish 		cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n",
705852ccf843Smisaki 		    nxgep->mac.portnum, val_debug);
705944961713Sgirish 		(void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18,
706052ccf843Smisaki 		    &val_debug);
706144961713Sgirish 		cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n",
706252ccf843Smisaki 		    nxgep->mac.portnum, val_debug);
706344961713Sgirish 	}
706444961713Sgirish 
706544961713Sgirish 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
706652ccf843Smisaki 	    XPCS_REG_DESCWERR_COUNTER, &val);
706744961713Sgirish 	if (val != 0)
706844961713Sgirish 		cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val);
706944961713Sgirish 
707044961713Sgirish 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
707152ccf843Smisaki 	    XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
707244961713Sgirish 	if (val != 0)
707344961713Sgirish 		cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val);
707444961713Sgirish 
707544961713Sgirish 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
707652ccf843Smisaki 	    XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
707744961713Sgirish 	if (val != 0)
707844961713Sgirish 		cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val);
707944961713Sgirish #endif
708044961713Sgirish 
708144961713Sgirish 	/* Check from BCM8704 if 10G link is up or down */
708244961713Sgirish 
708344961713Sgirish 	/* Check Device 1 Register 0xA bit0 */
708452ccf843Smisaki 	status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PMA_PMD_DEV_ADDR,
708552ccf843Smisaki 	    BCM8704_PMD_RECEIVE_SIG_DETECT, &val1);
708644961713Sgirish 	if (status != NXGE_OK)
708744961713Sgirish 		goto fail;
708844961713Sgirish 	rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE);
708944961713Sgirish 
709044961713Sgirish 	/* Check Device 3 Register 0x20 bit0 */
709152ccf843Smisaki 	if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PCS_DEV_ADDR,
709252ccf843Smisaki 	    BCM8704_10GBASE_R_PCS_STATUS_REG, &val2)) != NPI_SUCCESS)
709344961713Sgirish 		goto fail;
709444961713Sgirish 	pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE);
709544961713Sgirish 
709644961713Sgirish 	/* Check Device 4 Register 0x18 bit12 */
709752ccf843Smisaki 	status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
709852ccf843Smisaki 	    BCM8704_PHYXS_XGXS_LANE_STATUS_REG, &val3);
709944961713Sgirish 	if (status != NXGE_OK)
710044961713Sgirish 		goto fail;
71012d17280bSsbehera 
71022d17280bSsbehera 	switch (nxgep->chip_id) {
71032d17280bSsbehera 	case BCM8704_CHIP_ID:
71042d17280bSsbehera 		link_align = (val3 == (XGXS_LANE_ALIGN_STATUS |
71052d17280bSsbehera 		    XGXS_LANE3_SYNC | XGXS_LANE2_SYNC | XGXS_LANE1_SYNC |
71062d17280bSsbehera 		    XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE;
71072d17280bSsbehera 		break;
71082d17280bSsbehera 	case BCM8706_CHIP_ID:
71092d17280bSsbehera 		link_align = ((val3 & XGXS_LANE_ALIGN_STATUS) &&
71102d17280bSsbehera 		    (val3 & XGXS_LANE3_SYNC) && (val3 & XGXS_LANE2_SYNC) &&
71112d17280bSsbehera 		    (val3 & XGXS_LANE1_SYNC) && (val3 & XGXS_LANE0_SYNC)) ?
71122d17280bSsbehera 		    B_TRUE : B_FALSE;
71132d17280bSsbehera 		break;
71142d17280bSsbehera 	default:
71152d17280bSsbehera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_check_bcm8704_link:"
71162d17280bSsbehera 		    "Unknown chip ID [0x%x]", nxgep->chip_id));
71172d17280bSsbehera 		goto fail;
71182d17280bSsbehera 	}
71192d17280bSsbehera 
712044961713Sgirish #ifdef	NXGE_DEBUG_ALIGN_ERR
712144961713Sgirish 	/* Temp workaround for link down issue */
712244961713Sgirish 	if (pcs_blk_lock == B_FALSE) {
712344961713Sgirish 		if (val2 != 0x4) {
712444961713Sgirish 			pcs_blk_lock = B_TRUE;
712552ccf843Smisaki 			cmn_err(CE_NOTE, "!LINK DEBUG: port%d PHY Dev3 "
712652ccf843Smisaki 			    "Reg 0x20 = 0x%x\n", nxgep->mac.portnum, val2);
712744961713Sgirish 		}
712844961713Sgirish 	}
712944961713Sgirish 
713044961713Sgirish 	if (link_align == B_FALSE) {
713144961713Sgirish 		if (val3 != 0x140f) {
713244961713Sgirish 			link_align = B_TRUE;
713352ccf843Smisaki 			cmn_err(CE_NOTE, "!LINK DEBUG: port%d PHY Dev4 "
713452ccf843Smisaki 			    "Reg 0x18 = 0x%x\n", nxgep->mac.portnum, val3);
713544961713Sgirish 		}
713644961713Sgirish 	}
713744961713Sgirish 
713844961713Sgirish 	if (rx_sig_ok == B_FALSE) {
713944961713Sgirish 		if ((val2 == 0) || (val3 == 0)) {
714044961713Sgirish 			rx_sig_ok = B_TRUE;
714144961713Sgirish 			cmn_err(CE_NOTE,
714252ccf843Smisaki 			    "!LINK DEBUG: port %d Dev3 or Dev4 read zero\n",
714352ccf843Smisaki 			    nxgep->mac.portnum);
714444961713Sgirish 		}
714544961713Sgirish 	}
714644961713Sgirish #endif
714744961713Sgirish 
714844961713Sgirish 	*link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) &&
714952ccf843Smisaki 	    (link_align == B_TRUE)) ? B_TRUE : B_FALSE;
715044961713Sgirish 
715144961713Sgirish 	return (NXGE_OK);
715244961713Sgirish fail:
715344961713Sgirish 	return (status);
715444961713Sgirish }
715544961713Sgirish 
715652cdd236Ssbehera static nxge_status_t
nxge_check_mrvl88x2011_link(p_nxge_t nxgep,boolean_t * link_up)715700161856Syc nxge_check_mrvl88x2011_link(p_nxge_t nxgep, boolean_t *link_up)
715852cdd236Ssbehera {
715952cdd236Ssbehera 	uint8_t		phy;
716052cdd236Ssbehera 	nxge_status_t   status = NXGE_OK;
716152cdd236Ssbehera 	boolean_t	pma_status;
716252cdd236Ssbehera 	boolean_t	pcs_status;
716352cdd236Ssbehera 	boolean_t	xgxs_status;
716452cdd236Ssbehera 	uint16_t	val;
716552cdd236Ssbehera 
716652cdd236Ssbehera 	phy = nxgep->statsp->mac_stats.xcvr_portn;
716752cdd236Ssbehera 
716852cdd236Ssbehera 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR,
716952cdd236Ssbehera 	    MRVL_88X2011_10G_PMD_STAT_2, &val);
717052cdd236Ssbehera 
717152cdd236Ssbehera 	*link_up = B_FALSE;
717252cdd236Ssbehera 
717352cdd236Ssbehera 	/* Check from Marvell 88X2011 if 10G link is up or down */
717452cdd236Ssbehera 
717552cdd236Ssbehera 	/* Check PMA/PMD Register: 1.0001.2 == 1 */
717652cdd236Ssbehera 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR,
717752cdd236Ssbehera 	    MRVL_88X2011_PMA_PMD_STAT_1, &val);
717852cdd236Ssbehera 
717952cdd236Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
718052cdd236Ssbehera 	    "nxge_check_mrvl88x2011_link: pmd=0x%x", val));
718152cdd236Ssbehera 
718252cdd236Ssbehera 	pma_status = ((val & MRVL_88X2011_LNK_STATUS_OK) ? B_TRUE : B_FALSE);
718352cdd236Ssbehera 
718452cdd236Ssbehera 	/* Check PMC Register : 3.0001.2 == 1: read twice */
718552cdd236Ssbehera 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
718652cdd236Ssbehera 	    MRVL_88X2011_PMA_PMD_STAT_1, &val);
718752cdd236Ssbehera 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
718852cdd236Ssbehera 	    MRVL_88X2011_PMA_PMD_STAT_1, &val);
718952cdd236Ssbehera 
719052cdd236Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
719152cdd236Ssbehera 	    "nxge_check_mrvl88x2011_link: pcs=0x%x", val));
719252cdd236Ssbehera 
719352cdd236Ssbehera 	pcs_status = ((val & MRVL_88X2011_LNK_STATUS_OK) ? B_TRUE : B_FALSE);
719452cdd236Ssbehera 
719552cdd236Ssbehera 	/* Check XGXS Register : 4.0018.[0-3,12] */
719652cdd236Ssbehera 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV4_ADDR,
719752cdd236Ssbehera 	    MRVL_88X2011_10G_XGXS_LANE_STAT, &val);
719852cdd236Ssbehera 
719952cdd236Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
720052cdd236Ssbehera 	    "nxge_check_mrvl88x2011_link: xgxs=0x%x", val));
720152cdd236Ssbehera 
720252cdd236Ssbehera 	xgxs_status = (val == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC |
720352cdd236Ssbehera 	    XGXS_LANE2_SYNC | XGXS_LANE1_SYNC |
720452cdd236Ssbehera 	    XGXS_LANE0_SYNC | XGXS_PATTERN_TEST_ABILITY |
720552cdd236Ssbehera 	    XGXS_LANE_STAT_MAGIC)) ? B_TRUE : B_FALSE;
720652cdd236Ssbehera 
720752cdd236Ssbehera 	*link_up = (pma_status && pcs_status && xgxs_status) ?
720852cdd236Ssbehera 	    B_TRUE : B_FALSE;
720952cdd236Ssbehera 
721052cdd236Ssbehera fail:
721152cdd236Ssbehera 
721252cdd236Ssbehera 	if (*link_up == B_FALSE) {
721352cdd236Ssbehera 		/* PCS OFF */
721452cdd236Ssbehera 		nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_CTL_OFF);
721552cdd236Ssbehera 	} else {
721652cdd236Ssbehera 		/* PCS Activity */
721752cdd236Ssbehera 		nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_CTL_PCS_ACT);
721852cdd236Ssbehera 	}
721952cdd236Ssbehera 
722052cdd236Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
722152cdd236Ssbehera 	    " <== nxge_check_mrvl88x2011_link: up=%d", *link_up));
722252cdd236Ssbehera 
722352cdd236Ssbehera 	return (status);
722452cdd236Ssbehera }
722552cdd236Ssbehera 
722689282175SSantwona Behera static nxge_status_t
nxge_check_nlp2020_link(p_nxge_t nxgep,boolean_t * link_up)722789282175SSantwona Behera nxge_check_nlp2020_link(p_nxge_t nxgep, boolean_t *link_up)
722889282175SSantwona Behera {
722989282175SSantwona Behera 	uint8_t		phy;
723089282175SSantwona Behera 	nxge_status_t   status = NXGE_OK;
723189282175SSantwona Behera 	uint16_t	pmd_rx_sig, pcs_10gbr_stat1, phy_xs_ln_stat;
723289282175SSantwona Behera 	uint8_t		connector = 0;
723389282175SSantwona Behera 
723489282175SSantwona Behera 	phy = nxgep->statsp->mac_stats.xcvr_portn;
723589282175SSantwona Behera 	*link_up = B_FALSE;
723689282175SSantwona Behera 
723789282175SSantwona Behera 	/* Check from Netlogic AEL2020 if 10G link is up or down */
723889282175SSantwona Behera 
723989282175SSantwona Behera 	status = nxge_mdio_read(nxgep, phy, NLP2020_PMA_PMD_ADDR,
724089282175SSantwona Behera 	    NLP2020_PMA_PMD_RX_SIG_DET_REG, &pmd_rx_sig);
724189282175SSantwona Behera 	if (status != NXGE_OK)
724289282175SSantwona Behera 		goto fail;
724389282175SSantwona Behera 
724489282175SSantwona Behera 	status = nxge_mdio_read(nxgep, phy, NLP2020_PHY_PCS_ADDR,
724589282175SSantwona Behera 	    NLP2020_PHY_PCS_10GBR_STAT1_REG, &pcs_10gbr_stat1);
724689282175SSantwona Behera 	if (status != NXGE_OK)
724789282175SSantwona Behera 		goto fail;
724889282175SSantwona Behera 
724989282175SSantwona Behera 	status = nxge_mdio_read(nxgep, phy, NLP2020_PHY_XS_ADDR,
725089282175SSantwona Behera 	    NLP2020_PHY_XS_LN_ST_REG, &phy_xs_ln_stat);
725189282175SSantwona Behera 	if (status != NXGE_OK)
725289282175SSantwona Behera 		goto fail;
725389282175SSantwona Behera 
725489282175SSantwona Behera 	if ((pmd_rx_sig & NLP2020_PMA_PMD_RX_SIG_ON) &&
725589282175SSantwona Behera 	    (pcs_10gbr_stat1 & NLP2020_PHY_PCS_10GBR_RX_LINK_UP) &&
725689282175SSantwona Behera 	    (phy_xs_ln_stat & NLP2020_PHY_XS_LN_ALIGN_SYNC))
725789282175SSantwona Behera 		*link_up = B_TRUE;
725889282175SSantwona Behera 	/*
725989282175SSantwona Behera 	 * If previously link was down, check the connector type as
726089282175SSantwona Behera 	 * it might have been changed.
726189282175SSantwona Behera 	 */
726289282175SSantwona Behera 	if (nxgep->statsp->mac_stats.link_up == 0) {
726389282175SSantwona Behera 		(void) nxge_nlp2020_i2c_read(nxgep, phy,
726489282175SSantwona Behera 		    NLP2020_XCVR_I2C_ADDR, QSFP_MSA_CONN_REG, &connector);
726589282175SSantwona Behera 
726689282175SSantwona Behera 		switch (connector) {
726789282175SSantwona Behera 		case SFPP_FIBER:
726889282175SSantwona Behera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
726989282175SSantwona Behera 			    "nxge_check_nlp2020_link: SFPP_FIBER"));
727089282175SSantwona Behera 			if (nxgep->mac.portmode != PORT_10G_FIBER) {
727189282175SSantwona Behera 				nxgep->mac.portmode = PORT_10G_FIBER;
727289282175SSantwona Behera 				(void) nxge_nlp2020_xcvr_init(nxgep);
727389282175SSantwona Behera 			}
727489282175SSantwona Behera 			break;
727589282175SSantwona Behera 		case QSFP_FIBER:
727689282175SSantwona Behera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
727789282175SSantwona Behera 			    "nxge_check_nlp2020_link: QSFP_FIBER"));
727889282175SSantwona Behera 			if (nxgep->mac.portmode != PORT_10G_FIBER) {
727989282175SSantwona Behera 				nxgep->mac.portmode = PORT_10G_FIBER;
728089282175SSantwona Behera 				(void) nxge_nlp2020_xcvr_init(nxgep);
728189282175SSantwona Behera 			}
728289282175SSantwona Behera 			break;
728389282175SSantwona Behera 		case QSFP_COPPER_TWINAX:
728489282175SSantwona Behera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
728589282175SSantwona Behera 			    "nxge_check_nlp2020_link: "
728689282175SSantwona Behera 			    "QSFP_COPPER_TWINAX/"
728789282175SSantwona Behera 			    "SFPP_COPPER_TWINAX"));
728889282175SSantwona Behera 			if (nxgep->mac.portmode != PORT_10G_COPPER) {
728989282175SSantwona Behera 				nxgep->mac.portmode = PORT_10G_COPPER;
729089282175SSantwona Behera 				(void) nxge_nlp2020_xcvr_init(nxgep);
729189282175SSantwona Behera 			} else {
729289282175SSantwona Behera 				uint8_t len = 0;
729389282175SSantwona Behera 				(void) nxge_nlp2020_i2c_read(nxgep, phy,
729489282175SSantwona Behera 				    NLP2020_XCVR_I2C_ADDR, QSFP_MSA_LEN_REG,
729589282175SSantwona Behera 				    &len);
729689282175SSantwona Behera 				if (((len < 7) &&
729789282175SSantwona Behera 				    (nxgep->nlp_conn ==
729889282175SSantwona Behera 				    NXGE_NLP_CONN_COPPER_7M_ABOVE)) ||
729989282175SSantwona Behera 				    ((len >= 7) &&
730089282175SSantwona Behera 				    (nxgep->nlp_conn ==
730189282175SSantwona Behera 				    NXGE_NLP_CONN_COPPER_LT_7M))) {
730289282175SSantwona Behera 					(void) nxge_nlp2020_xcvr_init(nxgep);
730389282175SSantwona Behera 				}
730489282175SSantwona Behera 			}
730589282175SSantwona Behera 			break;
730689282175SSantwona Behera 		default:
730789282175SSantwona Behera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
730889282175SSantwona Behera 			    "nxge_check_nlp2020_link: Unknown type [0x%x] "
730989282175SSantwona Behera 			    "detected...setting to QSFP_FIBER",
731089282175SSantwona Behera 			    connector));
731189282175SSantwona Behera 			if (nxgep->mac.portmode != PORT_10G_FIBER) {
731289282175SSantwona Behera 				nxgep->mac.portmode = PORT_10G_FIBER;
731389282175SSantwona Behera 				(void) nxge_nlp2020_xcvr_init(nxgep);
731489282175SSantwona Behera 			}
731589282175SSantwona Behera 			break;
731689282175SSantwona Behera 		}
731789282175SSantwona Behera 	}
731889282175SSantwona Behera fail:
731989282175SSantwona Behera 	if (*link_up == B_FALSE && nxgep->statsp->mac_stats.link_up == 1) {
732089282175SSantwona Behera 		/* Turn link LED OFF */
732189282175SSantwona Behera 		(void) nxge_mdio_write(nxgep, phy,
732289282175SSantwona Behera 		    NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG, 0xb000);
732389282175SSantwona Behera 		(void) nxge_mdio_write(nxgep, phy,
732489282175SSantwona Behera 		    NLP2020_GPIO_ADDR, NLP2020_GPIO_PT3_CFG_REG, 0x0);
732589282175SSantwona Behera 	} else if (*link_up == B_TRUE &&
732689282175SSantwona Behera 	    nxgep->statsp->mac_stats.link_up == 0) {
732789282175SSantwona Behera 		/* Turn link LED ON */
732889282175SSantwona Behera 		(void) nxge_mdio_write(nxgep, phy,
732989282175SSantwona Behera 		    NLP2020_GPIO_ADDR, NLP2020_GPIO_CTL_REG, 0xd000);
733089282175SSantwona Behera 		(void) nxge_mdio_write(nxgep, phy,
733189282175SSantwona Behera 		    NLP2020_GPIO_ADDR, NLP2020_GPIO_PT3_CFG_REG, 0xfbff);
733289282175SSantwona Behera 		(void) nxge_mdio_write(nxgep, phy,
733389282175SSantwona Behera 		    NLP2020_GPIO_ADDR, 0xff2a, 0x004a);
733489282175SSantwona Behera 	}
733589282175SSantwona Behera 
733689282175SSantwona Behera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
733789282175SSantwona Behera 	    " <== nxge_check_nlp2020_link: up=%d", *link_up));
733889282175SSantwona Behera 	return (status);
733989282175SSantwona Behera }
734089282175SSantwona Behera 
734189282175SSantwona Behera 
734259ac0c16Sdavemq nxge_status_t
nxge_10g_link_led_on(p_nxge_t nxgep)734359ac0c16Sdavemq nxge_10g_link_led_on(p_nxge_t nxgep)
734459ac0c16Sdavemq {
734559ac0c16Sdavemq 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE)
734659ac0c16Sdavemq 	    != NPI_SUCCESS)
734759ac0c16Sdavemq 		return (NXGE_ERROR);
734859ac0c16Sdavemq 	else
734959ac0c16Sdavemq 		return (NXGE_OK);
735059ac0c16Sdavemq }
735144961713Sgirish 
735244961713Sgirish nxge_status_t
nxge_10g_link_led_off(p_nxge_t nxgep)735359ac0c16Sdavemq nxge_10g_link_led_off(p_nxge_t nxgep)
735444961713Sgirish {
735559ac0c16Sdavemq 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE)
735659ac0c16Sdavemq 	    != NPI_SUCCESS)
735759ac0c16Sdavemq 		return (NXGE_ERROR);
735859ac0c16Sdavemq 	else
735959ac0c16Sdavemq 		return (NXGE_OK);
736059ac0c16Sdavemq }
736144961713Sgirish 
736289282175SSantwona Behera static boolean_t
nxge_hswap_phy_present(p_nxge_t nxgep,uint8_t portn)736389282175SSantwona Behera nxge_hswap_phy_present(p_nxge_t nxgep, uint8_t portn)
736489282175SSantwona Behera {
736589282175SSantwona Behera 	/*
736689282175SSantwona Behera 	 * check for BCM PHY (GOA NEM)
736789282175SSantwona Behera 	 */
736889282175SSantwona Behera 	/*
736989282175SSantwona Behera 	 * If this is the 2nd NIU port, then check 2 addresses
737089282175SSantwona Behera 	 * to take care of the Goa NEM card. Port 1 can have addr 17
737189282175SSantwona Behera 	 * (in the eval board) or 20 (in the P0 board).
737289282175SSantwona Behera 	 */
737389282175SSantwona Behera 	if (portn == 1) {
737489282175SSantwona Behera 		if (nxge_is_phy_present(nxgep, ALT_GOA_CLAUSE45_PORT1_ADDR,
737589282175SSantwona Behera 		    BCM8706_DEV_ID, BCM_PHY_ID_MASK)) {
737689282175SSantwona Behera 			nxgep->xcvr_addr = ALT_GOA_CLAUSE45_PORT1_ADDR;
737789282175SSantwona Behera 			goto found_phy;
737889282175SSantwona Behera 		}
737989282175SSantwona Behera 	}
738089282175SSantwona Behera 	if (nxge_is_phy_present(nxgep, GOA_CLAUSE45_PORT_ADDR_BASE + portn,
738189282175SSantwona Behera 	    BCM8706_DEV_ID, BCM_PHY_ID_MASK)) {
738289282175SSantwona Behera 		nxgep->xcvr_addr = GOA_CLAUSE45_PORT_ADDR_BASE + portn;
73834df3b64dSToomas Soome 		goto found_phy;
738489282175SSantwona Behera 	}
738589282175SSantwona Behera 
738689282175SSantwona Behera 	/*
738789282175SSantwona Behera 	 * check for NLP2020 PHY on C4 NEM
738889282175SSantwona Behera 	 */
738989282175SSantwona Behera 	switch (portn) {
739089282175SSantwona Behera 	case 0:
739189282175SSantwona Behera 		if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR0,
739289282175SSantwona Behera 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
739389282175SSantwona Behera 			nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR0;
739489282175SSantwona Behera 			goto found_phy;
739589282175SSantwona Behera 		} else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR1,
739689282175SSantwona Behera 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
739789282175SSantwona Behera 			nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR1;
739889282175SSantwona Behera 			goto found_phy;
739989282175SSantwona Behera 		} else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR2,
740089282175SSantwona Behera 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
740189282175SSantwona Behera 			nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR2;
740289282175SSantwona Behera 			goto found_phy;
740389282175SSantwona Behera 		} else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT0_ADDR3,
740489282175SSantwona Behera 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
740589282175SSantwona Behera 			nxgep->xcvr_addr = NLP2020_CL45_PORT0_ADDR3;
740689282175SSantwona Behera 			goto found_phy;
740789282175SSantwona Behera 		}
740889282175SSantwona Behera 		break;
740989282175SSantwona Behera 
741089282175SSantwona Behera 	case 1:
741189282175SSantwona Behera 		if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR0,
741289282175SSantwona Behera 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
741389282175SSantwona Behera 			nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR0;
741489282175SSantwona Behera 			goto found_phy;
741589282175SSantwona Behera 		} else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR1,
741689282175SSantwona Behera 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
741789282175SSantwona Behera 			nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR1;
741889282175SSantwona Behera 			goto found_phy;
741989282175SSantwona Behera 		} else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR2,
742089282175SSantwona Behera 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
742189282175SSantwona Behera 			nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR2;
742289282175SSantwona Behera 			goto found_phy;
742389282175SSantwona Behera 		} else if (nxge_is_phy_present(nxgep, NLP2020_CL45_PORT1_ADDR3,
742489282175SSantwona Behera 		    NLP2020_DEV_ID, NLP2020_DEV_ID_MASK)) {
742589282175SSantwona Behera 			nxgep->xcvr_addr = NLP2020_CL45_PORT1_ADDR3;
742689282175SSantwona Behera 			goto found_phy;
742789282175SSantwona Behera 		}
742889282175SSantwona Behera 		break;
742989282175SSantwona Behera 	default:
743089282175SSantwona Behera 		break;
743189282175SSantwona Behera 	}
743289282175SSantwona Behera 
743389282175SSantwona Behera 	return (B_FALSE);
743489282175SSantwona Behera found_phy:
743589282175SSantwona Behera 	return (B_TRUE);
743689282175SSantwona Behera 
743789282175SSantwona Behera }
743889282175SSantwona Behera 
74392d17280bSsbehera static boolean_t
nxge_is_phy_present(p_nxge_t nxgep,int addr,uint32_t id,uint32_t mask)74402d17280bSsbehera nxge_is_phy_present(p_nxge_t nxgep, int addr, uint32_t id, uint32_t mask)
74412d17280bSsbehera {
74422d17280bSsbehera 	uint32_t pma_pmd_id = 0;
74432d17280bSsbehera 	uint32_t pcs_id = 0;
74442d17280bSsbehera 	uint32_t phy_id = 0;
74452d17280bSsbehera 
74462d17280bSsbehera 	pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, addr);
74472d17280bSsbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
74482d17280bSsbehera 	    "nxge_is_phy_present: pma_pmd_id[0x%x]", pma_pmd_id));
74492d17280bSsbehera 	if ((pma_pmd_id & mask) == (id & mask))
74502d17280bSsbehera 		goto found_phy;
74512d17280bSsbehera 	pcs_id = nxge_get_cl45_pcs_id(nxgep, addr);
74522d17280bSsbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
74532d17280bSsbehera 	    "nxge_is_phy_present: pcs_id[0x%x]", pcs_id));
74542d17280bSsbehera 	if ((pcs_id & mask) == (id & mask))
74552d17280bSsbehera 		goto found_phy;
74562d17280bSsbehera 	phy_id = nxge_get_cl22_phy_id(nxgep, addr);
74572d17280bSsbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
74582d17280bSsbehera 	    "nxge_is_phy_present: phy_id[0x%x]", phy_id));
74592d17280bSsbehera 	if ((phy_id & mask) == (id & mask))
74602d17280bSsbehera 		goto found_phy;
74612d17280bSsbehera 
74622d17280bSsbehera 	return (B_FALSE);
74632d17280bSsbehera 
74642d17280bSsbehera found_phy:
74652d17280bSsbehera 	return (B_TRUE);
74662d17280bSsbehera }
74672d17280bSsbehera 
746859ac0c16Sdavemq /* Check if the given id read using the given MDIO Clause is supported */
746959ac0c16Sdavemq 
747059ac0c16Sdavemq static boolean_t
nxge_is_supported_phy(uint32_t id,uint8_t type)747159ac0c16Sdavemq nxge_is_supported_phy(uint32_t id, uint8_t type)
747259ac0c16Sdavemq {
747359ac0c16Sdavemq 	int		i;
747459ac0c16Sdavemq 	boolean_t	found = B_FALSE;
747559ac0c16Sdavemq 
747659ac0c16Sdavemq 	switch (type) {
747759ac0c16Sdavemq 	case CLAUSE_45_TYPE:
747800161856Syc 		for (i = 0; i < NUM_CLAUSE_45_IDS; i++) {
747900161856Syc 			if (((nxge_supported_cl45_ids[i] & BCM_PHY_ID_MASK) ==
748000161856Syc 			    (id & BCM_PHY_ID_MASK)) ||
748189282175SSantwona Behera 			    (TN1010_DEV_ID == (id & TN1010_DEV_ID_MASK)) ||
748289282175SSantwona Behera 			    (NLP2020_DEV_ID == (id & NLP2020_DEV_ID_MASK))) {
748359ac0c16Sdavemq 				found = B_TRUE;
748459ac0c16Sdavemq 				break;
748559ac0c16Sdavemq 			}
748659ac0c16Sdavemq 		}
748759ac0c16Sdavemq 		break;
748859ac0c16Sdavemq 	case CLAUSE_22_TYPE:
748900161856Syc 		for (i = 0; i < NUM_CLAUSE_22_IDS; i++) {
749030505775Ssbehera 			if ((nxge_supported_cl22_ids[i] & BCM_PHY_ID_MASK) ==
749130505775Ssbehera 			    (id & BCM_PHY_ID_MASK)) {
749259ac0c16Sdavemq 				found = B_TRUE;
749359ac0c16Sdavemq 				break;
749456d930aeSspeer 			}
749544961713Sgirish 		}
749659ac0c16Sdavemq 		break;
749759ac0c16Sdavemq 	default:
749859ac0c16Sdavemq 		break;
749956d930aeSspeer 	}
750056d930aeSspeer 
750159ac0c16Sdavemq 	return (found);
750259ac0c16Sdavemq }
750359ac0c16Sdavemq 
75042e59129aSraghus static uint32_t
nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep,int phy_port)75052e59129aSraghus nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep, int phy_port)
75062e59129aSraghus {
75072e59129aSraghus 	uint16_t	val1 = 0;
75082e59129aSraghus 	uint16_t	val2 = 0;
75092e59129aSraghus 	uint32_t	pma_pmd_dev_id = 0;
75102e59129aSraghus 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
75112e59129aSraghus 
751253560810Ssbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
75132e59129aSraghus 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR,
75142e59129aSraghus 	    NXGE_DEV_ID_REG_1, &val1);
75152e59129aSraghus 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR,
75162e59129aSraghus 	    NXGE_DEV_ID_REG_2, &val2);
751753560810Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
75182e59129aSraghus 
751900161856Syc 	/* Concatenate the Device ID stored in two registers. */
75202e59129aSraghus 	pma_pmd_dev_id = val1;
75212e59129aSraghus 	pma_pmd_dev_id = (pma_pmd_dev_id << 16);
75222e59129aSraghus 	pma_pmd_dev_id |= val2;
75232e59129aSraghus 
75242e59129aSraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PMA/PMD "
75252e59129aSraghus 	    "devid[0x%llx]", phy_port, pma_pmd_dev_id));
75262e59129aSraghus 
75272e59129aSraghus 	return (pma_pmd_dev_id);
75282e59129aSraghus }
75292e59129aSraghus 
75302e59129aSraghus static uint32_t
nxge_get_cl45_pcs_id(p_nxge_t nxgep,int phy_port)75312e59129aSraghus nxge_get_cl45_pcs_id(p_nxge_t nxgep, int phy_port)
75322e59129aSraghus {
75332e59129aSraghus 	uint16_t	val1 = 0;
75342e59129aSraghus 	uint16_t	val2 = 0;
75352e59129aSraghus 	uint32_t	pcs_dev_id = 0;
75362e59129aSraghus 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
75372e59129aSraghus 
753853560810Ssbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
75392e59129aSraghus 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR,
75402e59129aSraghus 	    NXGE_DEV_ID_REG_1, &val1);
75412e59129aSraghus 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR,
75422e59129aSraghus 	    NXGE_DEV_ID_REG_2, &val2);
754353560810Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
75442e59129aSraghus 
75452e59129aSraghus 	pcs_dev_id = val1;
75462e59129aSraghus 	pcs_dev_id = (pcs_dev_id << 16);
75472e59129aSraghus 	pcs_dev_id |= val2;
75482e59129aSraghus 
75492e59129aSraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS "
75502e59129aSraghus 	    "devid[0x%llx]", phy_port, pcs_dev_id));
75512e59129aSraghus 
75522e59129aSraghus 	return (pcs_dev_id);
75532e59129aSraghus }
75542e59129aSraghus 
75552e59129aSraghus static uint32_t
nxge_get_cl22_phy_id(p_nxge_t nxgep,int phy_port)75562e59129aSraghus nxge_get_cl22_phy_id(p_nxge_t nxgep, int phy_port)
75572e59129aSraghus {
75582e59129aSraghus 	uint16_t	val1 = 0;
75592e59129aSraghus 	uint16_t	val2 = 0;
75602e59129aSraghus 	uint32_t	phy_id = 0;
75612e59129aSraghus 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
75622e59129aSraghus 	npi_status_t	npi_status = NPI_SUCCESS;
75632e59129aSraghus 
7564321febdeSsbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
75652e59129aSraghus 	npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_1,
75662e59129aSraghus 	    &val1);
75672e59129aSraghus 	if (npi_status != NPI_SUCCESS) {
75682e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
75692e59129aSraghus 		    "clause 22 read to reg 2 failed!!!"));
75702e59129aSraghus 		goto exit;
75712e59129aSraghus 	}
75722e59129aSraghus 	npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_2,
75732e59129aSraghus 	    &val2);
75742e59129aSraghus 	if (npi_status != 0) {
75752e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
75762e59129aSraghus 		    "clause 22 read to reg 3 failed!!!"));
75772e59129aSraghus 		goto exit;
75782e59129aSraghus 	}
75792e59129aSraghus 	phy_id = val1;
75802e59129aSraghus 	phy_id = (phy_id << 16);
75812e59129aSraghus 	phy_id |= val2;
75822e59129aSraghus 
75832e59129aSraghus exit:
7584321febdeSsbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
75852e59129aSraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID [0x%llx]",
75862e59129aSraghus 	    phy_port, phy_id));
75872e59129aSraghus 
75882e59129aSraghus 	return (phy_id);
75892e59129aSraghus }
75902e59129aSraghus 
759159ac0c16Sdavemq /*
759259ac0c16Sdavemq  * Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO
759359ac0c16Sdavemq  * read and the PMA/PMD device ID and the PCS device ID using Clause 45 MDIO
759459ac0c16Sdavemq  * read. Then use the values obtained to determine the phy type of each port
759559ac0c16Sdavemq  * and the Neptune type.
759600161856Syc  *
759700161856Syc  * This function sets hw_p->xcvr_addr[i] for future MDIO access and set
759800161856Syc  * hw_p->niu_type for each nxge instance to figure out nxgep->mac.portmode
759900161856Syc  * in case the portmode information is not available via OBP, nxge.conf,
760000161856Syc  * VPD or SEEPROM.
760159ac0c16Sdavemq  */
760259ac0c16Sdavemq nxge_status_t
nxge_scan_ports_phy(p_nxge_t nxgep,p_nxge_hw_list_t hw_p)760359ac0c16Sdavemq nxge_scan_ports_phy(p_nxge_t nxgep, p_nxge_hw_list_t hw_p)
760459ac0c16Sdavemq {
760559a835ddSjoycey 	int		i, j, l;
760659ac0c16Sdavemq 	uint32_t	pma_pmd_dev_id = 0;
760759ac0c16Sdavemq 	uint32_t	pcs_dev_id = 0;
760859ac0c16Sdavemq 	uint32_t	phy_id = 0;
760930505775Ssbehera 	uint32_t	port_pma_pmd_dev_id[NXGE_PORTS_NEPTUNE];
761030505775Ssbehera 	uint32_t	port_pcs_dev_id[NXGE_PORTS_NEPTUNE];
761130505775Ssbehera 	uint32_t	port_phy_id[NXGE_PORTS_NEPTUNE];
761259ac0c16Sdavemq 	uint8_t		pma_pmd_dev_fd[NXGE_MAX_PHY_PORTS];
761359ac0c16Sdavemq 	uint8_t		pcs_dev_fd[NXGE_MAX_PHY_PORTS];
76142d17280bSsbehera 	uint8_t		phy_fd_arr[NXGE_MAX_PHY_PORTS];
76152d17280bSsbehera 	uint8_t		port_fd_arr[NXGE_MAX_PHY_PORTS];
761659ac0c16Sdavemq 	uint8_t		total_port_fd, total_phy_fd;
761700161856Syc 	uint8_t		num_xaui;
761859ac0c16Sdavemq 	nxge_status_t	status = NXGE_OK;
761956d930aeSspeer 
762059ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: "));
762156d930aeSspeer 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
762259ac0c16Sdavemq 	    "==> nxge_scan_ports_phy: nxge niu_type[0x%x]",
762359ac0c16Sdavemq 	    nxgep->niu_type));
762459ac0c16Sdavemq 
7625678453a8Sspeer 	if (isLDOMguest(nxgep)) {
7626678453a8Sspeer 		hw_p->niu_type = NIU_TYPE_NONE;
7627678453a8Sspeer 		hw_p->platform_type = P_NEPTUNE_NONE;
7628678453a8Sspeer 		return (NXGE_OK);
7629678453a8Sspeer 	}
7630678453a8Sspeer 
763159a835ddSjoycey 	j = l = 0;
763259ac0c16Sdavemq 	total_port_fd = total_phy_fd = 0;
763356d930aeSspeer 	/*
763423b952a3SSantwona Behera 	 * Clause 45 and Clause 22 port/phy addresses 0 through 5 are reserved
763523b952a3SSantwona Behera 	 * for on chip serdes usages. "i" in the following for loop starts at 6.
763656d930aeSspeer 	 */
763759ac0c16Sdavemq 	for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) {
76382e59129aSraghus 
76392e59129aSraghus 		pma_pmd_dev_id = nxge_get_cl45_pma_pmd_id(nxgep, i);
764059ac0c16Sdavemq 
764159ac0c16Sdavemq 		if (nxge_is_supported_phy(pma_pmd_dev_id, CLAUSE_45_TYPE)) {
764259ac0c16Sdavemq 			pma_pmd_dev_fd[i] = 1;
764359ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
764452cdd236Ssbehera 			    "PMA/PMD dev %x found", i, pma_pmd_dev_id));
764530505775Ssbehera 			if (j < NXGE_PORTS_NEPTUNE) {
764600161856Syc 				if ((pma_pmd_dev_id & TN1010_DEV_ID_MASK)
764700161856Syc 				    == TN1010_DEV_ID) {
764800161856Syc 					port_pma_pmd_dev_id[j] = TN1010_DEV_ID;
764989282175SSantwona Behera 				} else if ((pma_pmd_dev_id &
765089282175SSantwona Behera 				    NLP2020_DEV_ID_MASK) == NLP2020_DEV_ID) {
765189282175SSantwona Behera 					port_pma_pmd_dev_id[j] =
765289282175SSantwona Behera 					    NLP2020_DEV_ID;
765300161856Syc 				} else {
765400161856Syc 					port_pma_pmd_dev_id[j] =
765552ccf843Smisaki 					    pma_pmd_dev_id & BCM_PHY_ID_MASK;
765600161856Syc 				}
76572d17280bSsbehera 				port_fd_arr[j] = (uint8_t)i;
765859ac0c16Sdavemq 				j++;
765959ac0c16Sdavemq 			}
766059ac0c16Sdavemq 		} else {
766159ac0c16Sdavemq 			pma_pmd_dev_fd[i] = 0;
766259ac0c16Sdavemq 		}
766359ac0c16Sdavemq 
76642e59129aSraghus 		pcs_dev_id = nxge_get_cl45_pcs_id(nxgep, i);
766559ac0c16Sdavemq 
766659ac0c16Sdavemq 		if (nxge_is_supported_phy(pcs_dev_id, CLAUSE_45_TYPE)) {
766759ac0c16Sdavemq 			pcs_dev_fd[i] = 1;
766859ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS "
766952cdd236Ssbehera 			    "dev %x found", i, pcs_dev_id));
767059a835ddSjoycey 			if (pma_pmd_dev_fd[i] == 1) {
767100161856Syc 				if ((pcs_dev_id & TN1010_DEV_ID_MASK)
767200161856Syc 				    == TN1010_DEV_ID) {
767300161856Syc 					port_pcs_dev_id[j - 1] =
767400161856Syc 					    TN1010_DEV_ID;
767589282175SSantwona Behera 				} else if ((pcs_dev_id & NLP2020_DEV_ID_MASK)
767689282175SSantwona Behera 				    == NLP2020_DEV_ID) {
767789282175SSantwona Behera 					port_pcs_dev_id[j - 1] =
767889282175SSantwona Behera 					    NLP2020_DEV_ID;
767900161856Syc 				} else {
768000161856Syc 					port_pcs_dev_id[j - 1] =
768100161856Syc 					    pcs_dev_id &
768200161856Syc 					    BCM_PHY_ID_MASK;
768300161856Syc 				}
768459a835ddSjoycey 			} else {
768559a835ddSjoycey 				if (j < NXGE_PORTS_NEPTUNE) {
768600161856Syc 					if ((pcs_dev_id & TN1010_DEV_ID_MASK)
768752ccf843Smisaki 					    == TN1010_DEV_ID) {
768800161856Syc 						port_pcs_dev_id[j] =
768900161856Syc 						    TN1010_DEV_ID;
769089282175SSantwona Behera 					} else if ((pcs_dev_id &
769189282175SSantwona Behera 					    NLP2020_DEV_ID_MASK)
769289282175SSantwona Behera 					    == NLP2020_DEV_ID) {
769389282175SSantwona Behera 						port_pcs_dev_id[j] =
769489282175SSantwona Behera 						    NLP2020_DEV_ID;
769500161856Syc 					} else {
769600161856Syc 						port_pcs_dev_id[j] =
769700161856Syc 						    pcs_dev_id &
769800161856Syc 						    BCM_PHY_ID_MASK;
769900161856Syc 					}
770059a835ddSjoycey 					port_fd_arr[j] = (uint8_t)i;
770159a835ddSjoycey 					j++;
770259a835ddSjoycey 				}
770359ac0c16Sdavemq 			}
770459ac0c16Sdavemq 		} else {
770559ac0c16Sdavemq 			pcs_dev_fd[i] = 0;
770659ac0c16Sdavemq 		}
770759ac0c16Sdavemq 
77082d17280bSsbehera 		if (pcs_dev_fd[i] || pma_pmd_dev_fd[i]) {
77092d17280bSsbehera 			total_port_fd ++;
77102d17280bSsbehera 		}
771159ac0c16Sdavemq 
77122e59129aSraghus 		phy_id = nxge_get_cl22_phy_id(nxgep, i);
771359ac0c16Sdavemq 		if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) {
77142d17280bSsbehera 			total_phy_fd ++;
771559ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID"
771652cdd236Ssbehera 			    "%x found", i, phy_id));
771730505775Ssbehera 			if (l < NXGE_PORTS_NEPTUNE) {
771800161856Syc 				if ((phy_id & TN1010_DEV_ID_MASK)
771900161856Syc 				    == TN1010_DEV_ID) {
772000161856Syc 					port_phy_id[l] = TN1010_DEV_ID;
772100161856Syc 				} else {
772200161856Syc 					port_phy_id[l]
772300161856Syc 					    = phy_id & BCM_PHY_ID_MASK;
772400161856Syc 				}
77252d17280bSsbehera 				phy_fd_arr[l] = (uint8_t)i;
772659ac0c16Sdavemq 				l++;
772759ac0c16Sdavemq 			}
772859ac0c16Sdavemq 		}
772959ac0c16Sdavemq 	}
773059ac0c16Sdavemq 
773159ac0c16Sdavemq 	switch (total_port_fd) {
773259ac0c16Sdavemq 	case 2:
773359ac0c16Sdavemq 		switch (total_phy_fd) {
773459ac0c16Sdavemq 		case 2:
773523b952a3SSantwona Behera 			/* 2 10G, 2 1G RGMII Fiber / copper */
773659a835ddSjoycey 			if ((((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) &&
773759a835ddSjoycey 			    (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) ||
773859a835ddSjoycey 			    ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) &&
773959a835ddSjoycey 			    (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) &&
774059a835ddSjoycey 			    ((port_phy_id[0] == PHY_BCM5482_FAMILY) &&
774159a835ddSjoycey 			    (port_phy_id[1] == PHY_BCM5482_FAMILY))) {
774259a835ddSjoycey 
774323b952a3SSantwona Behera 				switch (hw_p->platform_type) {
774423b952a3SSantwona Behera 				case P_NEPTUNE_ROCK:
774523b952a3SSantwona Behera 					hw_p->niu_type = NEPTUNE_2_10GF_2_1GC;
774623b952a3SSantwona Behera 					/*
774723b952a3SSantwona Behera 					 * ROCK platform has assigned a lower
774823b952a3SSantwona Behera 					 * addr to port 1. (port 0 = 0x9 and
774923b952a3SSantwona Behera 					 * port 1 = 0x8).
775023b952a3SSantwona Behera 					 */
775123b952a3SSantwona Behera 					hw_p->xcvr_addr[1] = port_fd_arr[0];
775223b952a3SSantwona Behera 					hw_p->xcvr_addr[0] = port_fd_arr[1];
775323b952a3SSantwona Behera 
775423b952a3SSantwona Behera 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
775523b952a3SSantwona Behera 					    "Rock with 2 10G, 2 1GC"));
775623b952a3SSantwona Behera 					break;
775723b952a3SSantwona Behera 
775823b952a3SSantwona Behera 				case P_NEPTUNE_NONE:
775923b952a3SSantwona Behera 				default:
776023b952a3SSantwona Behera 					hw_p->platform_type =
776123b952a3SSantwona Behera 					    P_NEPTUNE_GENERIC;
776223b952a3SSantwona Behera 					hw_p->niu_type = NEPTUNE_2_10GF_2_1GRF;
776359a835ddSjoycey 
776423b952a3SSantwona Behera 					hw_p->xcvr_addr[0] = port_fd_arr[0];
776523b952a3SSantwona Behera 					hw_p->xcvr_addr[1] = port_fd_arr[1];
776623b952a3SSantwona Behera 
776723b952a3SSantwona Behera 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
776823b952a3SSantwona Behera 					    "ARTM card with 2 10G, 2 1GF"));
776923b952a3SSantwona Behera 					break;
777023b952a3SSantwona Behera 				}
777159a835ddSjoycey 
777259a835ddSjoycey 				hw_p->xcvr_addr[2] = phy_fd_arr[0];
777359a835ddSjoycey 				hw_p->xcvr_addr[3] = phy_fd_arr[1];
777459a835ddSjoycey 
777559a835ddSjoycey 			} else {
777659a835ddSjoycey 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
777759a835ddSjoycey 				    "Unsupported neptune type 1"));
777859a835ddSjoycey 				goto error_exit;
777959a835ddSjoycey 			}
778059a835ddSjoycey 			break;
778159a835ddSjoycey 
778259ac0c16Sdavemq 		case 1:
778359ac0c16Sdavemq 			/* TODO - 2 10G, 1 1G */
778459ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
778559ac0c16Sdavemq 			    "Unsupported neptune type 2 10G, 1 1G"));
778659ac0c16Sdavemq 			goto error_exit;
778759ac0c16Sdavemq 		case 0:
778800161856Syc 			/*
778900161856Syc 			 * 2 10G: 2XGF NIC, Marvell, Goa, Huron with 2 XAUI
779000161856Syc 			 * cards, etc.
779100161856Syc 			 */
779230505775Ssbehera 			if (((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) &&
779330505775Ssbehera 			    (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) ||
779430505775Ssbehera 			    ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) &&
779552cdd236Ssbehera 			    (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY)) ||
779652cdd236Ssbehera 			    ((port_pcs_dev_id[0] == MARVELL_88X201X_PHY_ID) &&
779752cdd236Ssbehera 			    (port_pcs_dev_id[1] == MARVELL_88X201X_PHY_ID)) ||
779852cdd236Ssbehera 			    ((port_pma_pmd_dev_id[0] ==
779952cdd236Ssbehera 			    MARVELL_88X201X_PHY_ID) &&
780052cdd236Ssbehera 			    (port_pma_pmd_dev_id[1] ==
780152cdd236Ssbehera 			    MARVELL_88X201X_PHY_ID))) {
78022e59129aSraghus 
78032e59129aSraghus 				/*
78042e59129aSraghus 				 * Check the first phy port address against
78052e59129aSraghus 				 * the known phy start addresses to determine
78062e59129aSraghus 				 * the platform type.
78072e59129aSraghus 				 */
78082d17280bSsbehera 
78092d17280bSsbehera 				switch (port_fd_arr[0]) {
781000161856Syc 				case NEPTUNE_CLAUSE45_PORT_ADDR_BASE:
781152cdd236Ssbehera 					/*
781252cdd236Ssbehera 					 * The Marvell case also falls into
781352cdd236Ssbehera 					 * this case as
781452cdd236Ssbehera 					 * MRVL88X2011_NEPTUNE_PORT_ADDR_BASE
781500161856Syc 					 * == NEPTUNE_CLAUSE45_PORT_ADDR_BASE.
781652cdd236Ssbehera 					 * This is OK for the 2 10G case.
781752cdd236Ssbehera 					 */
78182e59129aSraghus 					hw_p->niu_type = NEPTUNE_2_10GF;
78192e59129aSraghus 					hw_p->platform_type =
78202e59129aSraghus 					    P_NEPTUNE_ATLAS_2PORT;
78212d17280bSsbehera 					break;
782200161856Syc 				case GOA_CLAUSE45_PORT_ADDR_BASE:
78232d17280bSsbehera 					if (hw_p->platform_type !=
78242d17280bSsbehera 					    P_NEPTUNE_NIU) {
78252d17280bSsbehera 						hw_p->platform_type =
78262d17280bSsbehera 						    P_NEPTUNE_GENERIC;
78272d17280bSsbehera 						hw_p->niu_type =
78282d17280bSsbehera 						    NEPTUNE_2_10GF;
78292d17280bSsbehera 					}
78302d17280bSsbehera 					break;
78312d17280bSsbehera 				default:
78322d17280bSsbehera 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
78332e59129aSraghus 					    "Unsupported neptune type 2 - 1"));
78342e59129aSraghus 					goto error_exit;
78352e59129aSraghus 				}
78362d17280bSsbehera 
78372d17280bSsbehera 				for (i = 0; i < 2; i++) {
78382d17280bSsbehera 					hw_p->xcvr_addr[i] = port_fd_arr[i];
78392d17280bSsbehera 				}
784000161856Syc 
784189282175SSantwona Behera 			/* 2 10G optical Netlogic AEL2020 ports */
784289282175SSantwona Behera 			} else if (((port_pcs_dev_id[0] == NLP2020_DEV_ID) &&
784389282175SSantwona Behera 			    (port_pcs_dev_id[1]  == NLP2020_DEV_ID)) ||
784489282175SSantwona Behera 			    ((port_pma_pmd_dev_id[0]  == NLP2020_DEV_ID) &&
784589282175SSantwona Behera 			    (port_pma_pmd_dev_id[1] == NLP2020_DEV_ID))) {
784689282175SSantwona Behera 				if (hw_p->platform_type != P_NEPTUNE_NIU) {
784789282175SSantwona Behera 					hw_p->platform_type =
784889282175SSantwona Behera 					    P_NEPTUNE_GENERIC;
784989282175SSantwona Behera 					hw_p->niu_type =
785089282175SSantwona Behera 					    NEPTUNE_2_10GF;
785189282175SSantwona Behera 				}
785289282175SSantwona Behera 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
785389282175SSantwona Behera 				    "Found 2 NL PHYs at addrs 0x%x and 0x%x",
785489282175SSantwona Behera 				    port_fd_arr[0], port_fd_arr[1]));
785589282175SSantwona Behera 				hw_p->xcvr_addr[0] = port_fd_arr[0];
785689282175SSantwona Behera 				hw_p->xcvr_addr[1] = port_fd_arr[1];
785789282175SSantwona Behera 
785800161856Syc 			/* Both XAUI slots have copper XAUI cards */
785900161856Syc 			} else if ((((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
786000161856Syc 			    == TN1010_DEV_ID) &&
786100161856Syc 			    ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
786200161856Syc 			    == TN1010_DEV_ID)) ||
786300161856Syc 			    (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
786400161856Syc 			    == TN1010_DEV_ID) &&
786500161856Syc 			    ((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK)
786600161856Syc 			    == TN1010_DEV_ID))) {
786700161856Syc 				hw_p->niu_type = NEPTUNE_2_TN1010;
786800161856Syc 				hw_p->xcvr_addr[0] = port_fd_arr[0];
786900161856Syc 				hw_p->xcvr_addr[1] = port_fd_arr[1];
787000161856Syc 
787100161856Syc 			/* Slot0 has fiber XAUI, slot1 has copper XAUI */
787200161856Syc 			} else if ((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
787300161856Syc 			    (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
787400161856Syc 			    == TN1010_DEV_ID) ||
787500161856Syc 			    (port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY &&
787600161856Syc 			    (port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK) ==
787700161856Syc 			    TN1010_DEV_ID)) {
787800161856Syc 				hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010;
787900161856Syc 				hw_p->xcvr_addr[0] = port_fd_arr[0];
788000161856Syc 				hw_p->xcvr_addr[1] = port_fd_arr[1];
788100161856Syc 
788200161856Syc 			/* Slot0 has copper XAUI, slot1 has fiber XAUI */
788300161856Syc 			} else if ((port_pcs_dev_id[1] == PHY_BCM8704_FAMILY &&
788400161856Syc 			    (port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
788500161856Syc 			    == TN1010_DEV_ID) ||
788600161856Syc 			    (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY &&
788700161856Syc 			    (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
788800161856Syc 			    == TN1010_DEV_ID)) {
788900161856Syc 				hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF;
789000161856Syc 				hw_p->xcvr_addr[0] = port_fd_arr[0];
789100161856Syc 				hw_p->xcvr_addr[1] = port_fd_arr[1];
789200161856Syc 
789359ac0c16Sdavemq 			} else {
789459ac0c16Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
789559ac0c16Sdavemq 				    "Unsupported neptune type 2"));
789659ac0c16Sdavemq 				goto error_exit;
789759ac0c16Sdavemq 			}
789859ac0c16Sdavemq 			break;
789900161856Syc 
790059ac0c16Sdavemq 		case 4:
790100161856Syc 			if (nxge_get_num_of_xaui(
790200161856Syc 			    port_pma_pmd_dev_id, port_pcs_dev_id,
790300161856Syc 			    port_phy_id, &num_xaui) == NXGE_ERROR) {
790400161856Syc 				goto error_exit;
790500161856Syc 			}
790600161856Syc 			if (num_xaui != 2)
790700161856Syc 				goto error_exit;
790859ac0c16Sdavemq 
790900161856Syc 			/*
791000161856Syc 			 *  Maramba with 2 XAUIs (either fiber or copper)
791100161856Syc 			 *
791200161856Syc 			 * Check the first phy port address against
791300161856Syc 			 * the known phy start addresses to determine
791400161856Syc 			 * the platform type.
791500161856Syc 			 */
791600161856Syc 			switch (phy_fd_arr[0]) {
791700161856Syc 			case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE:
791800161856Syc 				hw_p->platform_type =
791900161856Syc 				    P_NEPTUNE_MARAMBA_P0;
792000161856Syc 				break;
792100161856Syc 			case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
792200161856Syc 				hw_p->platform_type =
792300161856Syc 				    P_NEPTUNE_MARAMBA_P1;
792400161856Syc 				break;
792500161856Syc 			default:
792600161856Syc 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
792700161856Syc 				    "Unknown port %d...Cannot "
792800161856Syc 				    "determine platform type", i));
792900161856Syc 				goto error_exit;
793000161856Syc 			}
79312d17280bSsbehera 
793200161856Syc 			hw_p->xcvr_addr[0] = port_fd_arr[0];
793300161856Syc 			hw_p->xcvr_addr[1] = port_fd_arr[1];
793400161856Syc 			hw_p->xcvr_addr[2] = phy_fd_arr[2];
793500161856Syc 			hw_p->xcvr_addr[3] = phy_fd_arr[3];
793600161856Syc 
793700161856Syc 			/* slot0 has fiber XAUI, slot1 has Cu XAUI */
793800161856Syc 			if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
793900161856Syc 			    (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
794000161856Syc 			    == TN1010_DEV_ID) {
794100161856Syc 				hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010_2_1GC;
794200161856Syc 
794300161856Syc 			/* slot0 has Cu XAUI, slot1 has fiber XAUI */
794400161856Syc 			} else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
794500161856Syc 			    == TN1010_DEV_ID) &&
794600161856Syc 			    port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) {
794700161856Syc 				hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF_2_1GC;
794800161856Syc 
794900161856Syc 			/* Both slots have fiber XAUI */
795000161856Syc 			} else if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
795100161856Syc 			    port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) {
79522e59129aSraghus 				hw_p->niu_type = NEPTUNE_2_10GF_2_1GC;
79532e59129aSraghus 
795400161856Syc 			/* Both slots have copper XAUI */
795500161856Syc 			} else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
795600161856Syc 			    == TN1010_DEV_ID) &&
795700161856Syc 			    (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
795800161856Syc 			    == TN1010_DEV_ID) {
795900161856Syc 				hw_p->niu_type = NEPTUNE_2_TN1010_2_1GC;
79602d17280bSsbehera 
796159ac0c16Sdavemq 			} else {
796259ac0c16Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
796359ac0c16Sdavemq 				    "Unsupported neptune type 3"));
796459ac0c16Sdavemq 				goto error_exit;
796559ac0c16Sdavemq 			}
796659ac0c16Sdavemq 			break;
796759ac0c16Sdavemq 		default:
796859ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
796959ac0c16Sdavemq 			    "Unsupported neptune type 5"));
797059ac0c16Sdavemq 			goto error_exit;
797159ac0c16Sdavemq 		}
797230505775Ssbehera 		break;
797391f84442SToomas Soome 	case 1:		/* Only one clause45 port */
797400161856Syc 		switch (total_phy_fd) {	/* Number of clause22 ports */
797559ac0c16Sdavemq 		case 3:
79762e59129aSraghus 			/*
79772e59129aSraghus 			 * TODO 3 1G, 1 10G mode.
79782e59129aSraghus 			 * Differentiate between 1_1G_1_10G_2_1G and
79792e59129aSraghus 			 * 1_10G_3_1G
79802e59129aSraghus 			 */
79812e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
79822e59129aSraghus 			    "Unsupported neptune type 7"));
79832e59129aSraghus 			goto error_exit;
798459ac0c16Sdavemq 		case 2:
798559ac0c16Sdavemq 			/*
798659ac0c16Sdavemq 			 * TODO 2 1G, 1 10G mode.
798759ac0c16Sdavemq 			 * Differentiate between 1_1G_1_10G_1_1G and
798859ac0c16Sdavemq 			 * 1_10G_2_1G
798959ac0c16Sdavemq 			 */
799059ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
799159ac0c16Sdavemq 			    "Unsupported neptune type 8"));
799259ac0c16Sdavemq 			goto error_exit;
799359ac0c16Sdavemq 		case 1:
799459ac0c16Sdavemq 			/*
799559ac0c16Sdavemq 			 * TODO 1 1G, 1 10G mode.
799659ac0c16Sdavemq 			 * Differentiate between 1_1G_1_10G and
799759ac0c16Sdavemq 			 * 1_10G_1_1G
799859ac0c16Sdavemq 			 */
799959ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
800059ac0c16Sdavemq 			    "Unsupported neptune type 9"));
800159ac0c16Sdavemq 			goto error_exit;
800200161856Syc 		case 0:	/* N2 with 1 XAUI (fiber or copper) */
800300161856Syc 			/* Fiber XAUI */
80042d17280bSsbehera 			if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY ||
80052d17280bSsbehera 			    port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) {
80062d17280bSsbehera 
80072d17280bSsbehera 				/*
80082d17280bSsbehera 				 * Check the first phy port address against
80092d17280bSsbehera 				 * the known phy start addresses to determine
80102d17280bSsbehera 				 * the platform type.
80112d17280bSsbehera 				 */
80122d17280bSsbehera 
80132d17280bSsbehera 				switch (port_fd_arr[0]) {
801400161856Syc 				case N2_CLAUSE45_PORT_ADDR_BASE:
801500161856Syc 				case (N2_CLAUSE45_PORT_ADDR_BASE + 1):
801600161856Syc 				case ALT_GOA_CLAUSE45_PORT1_ADDR:
801700161856Syc 					/*
801800161856Syc 					 * If hw_p->platform_type ==
801900161856Syc 					 * P_NEPTUNE_NIU, then portmode
802000161856Syc 					 * is already known, so there is
802100161856Syc 					 * no need to figure out hw_p->
802200161856Syc 					 * platform_type because
802300161856Syc 					 * platform_type is only for
802400161856Syc 					 * figuring out portmode.
802500161856Syc 					 */
80262d17280bSsbehera 					if (hw_p->platform_type !=
80272d17280bSsbehera 					    P_NEPTUNE_NIU) {
80282d17280bSsbehera 						hw_p->platform_type =
80292d17280bSsbehera 						    P_NEPTUNE_GENERIC;
80302d17280bSsbehera 						hw_p->niu_type =
80312d17280bSsbehera 						    NEPTUNE_2_10GF;
80322d17280bSsbehera 					}
80332d17280bSsbehera 					break;
80342d17280bSsbehera 				default:
80352d17280bSsbehera 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
80362d17280bSsbehera 					    "Unsupported neptune type 10"));
80372d17280bSsbehera 					goto error_exit;
80382d17280bSsbehera 				}
8039321febdeSsbehera 				/*
8040321febdeSsbehera 				 * For GOA, which is a hot swappable PHY, the
8041321febdeSsbehera 				 * phy address to function number mapping
8042321febdeSsbehera 				 * should be preserved, i.e., addr 16 is
8043321febdeSsbehera 				 * assigned to function 0 and 20 to function 1
8044321febdeSsbehera 				 * But for Huron XAUI, the assignment should
8045321febdeSsbehera 				 * be by function number, i.e., whichever
8046321febdeSsbehera 				 * function number attaches should be
8047321febdeSsbehera 				 * assigned the available PHY (this is required
8048321febdeSsbehera 				 * primarily to support pre-production Huron
8049321febdeSsbehera 				 * boards where function 0 is mapped to addr 17
8050321febdeSsbehera 				 */
8051321febdeSsbehera 				if (port_fd_arr[0] ==
805200161856Syc 				    ALT_GOA_CLAUSE45_PORT1_ADDR) {
8053321febdeSsbehera 					hw_p->xcvr_addr[1] = port_fd_arr[0];
8054321febdeSsbehera 				} else {
8055321febdeSsbehera 					hw_p->xcvr_addr[nxgep->function_num] =
8056321febdeSsbehera 					    port_fd_arr[0];
8057321febdeSsbehera 				}
805889282175SSantwona Behera 			} else if (port_pcs_dev_id[0] == NLP2020_DEV_ID ||
805989282175SSantwona Behera 			    port_pma_pmd_dev_id[0] == NLP2020_DEV_ID) {
806089282175SSantwona Behera 				/* A 10G NLP2020 PHY in slot0 or slot1 */
806189282175SSantwona Behera 				switch (port_fd_arr[0]) {
806289282175SSantwona Behera 				case NLP2020_CL45_PORT0_ADDR0:
806389282175SSantwona Behera 				case NLP2020_CL45_PORT0_ADDR1:
806489282175SSantwona Behera 				case NLP2020_CL45_PORT0_ADDR2:
806589282175SSantwona Behera 				case NLP2020_CL45_PORT0_ADDR3:
806689282175SSantwona Behera 				case NLP2020_CL45_PORT1_ADDR0:
806789282175SSantwona Behera 				case NLP2020_CL45_PORT1_ADDR1:
806889282175SSantwona Behera 				case NLP2020_CL45_PORT1_ADDR2:
806989282175SSantwona Behera 				case NLP2020_CL45_PORT1_ADDR3:
807089282175SSantwona Behera 					/*
807189282175SSantwona Behera 					 * If hw_p->platform_type ==
807289282175SSantwona Behera 					 * P_NEPTUNE_NIU, then portmode
807389282175SSantwona Behera 					 * is already known, so there is
807489282175SSantwona Behera 					 * no need to figure out hw_p->
807589282175SSantwona Behera 					 * platform_type because
807689282175SSantwona Behera 					 * platform_type is only for
807789282175SSantwona Behera 					 * figuring out portmode.
807889282175SSantwona Behera 					 */
807989282175SSantwona Behera 					if (hw_p->platform_type !=
808089282175SSantwona Behera 					    P_NEPTUNE_NIU) {
808189282175SSantwona Behera 						hw_p->platform_type =
808289282175SSantwona Behera 						    P_NEPTUNE_GENERIC;
808389282175SSantwona Behera 						hw_p->niu_type =
808489282175SSantwona Behera 						    NEPTUNE_2_10GF;
808589282175SSantwona Behera 					}
808689282175SSantwona Behera 					break;
808789282175SSantwona Behera 				default:
808889282175SSantwona Behera 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
808989282175SSantwona Behera 					    "Unsupported neptune type 10-1"));
809089282175SSantwona Behera 					goto error_exit;
809189282175SSantwona Behera 				}
809289282175SSantwona Behera 				switch (port_fd_arr[0]) {
809389282175SSantwona Behera 				case NLP2020_CL45_PORT0_ADDR0:
809489282175SSantwona Behera 				case NLP2020_CL45_PORT0_ADDR1:
809589282175SSantwona Behera 				case NLP2020_CL45_PORT0_ADDR2:
809689282175SSantwona Behera 				case NLP2020_CL45_PORT0_ADDR3:
809789282175SSantwona Behera 					hw_p->xcvr_addr[0] = port_fd_arr[0];
809889282175SSantwona Behera 					break;
809989282175SSantwona Behera 				case NLP2020_CL45_PORT1_ADDR0:
810089282175SSantwona Behera 				case NLP2020_CL45_PORT1_ADDR1:
810189282175SSantwona Behera 				case NLP2020_CL45_PORT1_ADDR2:
810289282175SSantwona Behera 				case NLP2020_CL45_PORT1_ADDR3:
810389282175SSantwona Behera 					hw_p->xcvr_addr[1] = port_fd_arr[0];
810489282175SSantwona Behera 					break;
810589282175SSantwona Behera 				default:
810689282175SSantwona Behera 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
810789282175SSantwona Behera 					    "Unsupported neptune type 10-11"));
810889282175SSantwona Behera 					goto error_exit;
810989282175SSantwona Behera 				}
811089282175SSantwona Behera 
811189282175SSantwona Behera 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
811289282175SSantwona Behera 				    "Found 1 NL PHYs at addr 0x%x",
811389282175SSantwona Behera 				    port_fd_arr[0]));
811400161856Syc 
811500161856Syc 			/* A 10G copper XAUI in either slot0 or slot1 */
811600161856Syc 			} else if ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
811700161856Syc 			    == TN1010_DEV_ID ||
811800161856Syc 			    (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
811900161856Syc 			    == TN1010_DEV_ID) {
812000161856Syc 				switch (port_fd_arr[0]) {
812100161856Syc 				/* The XAUI is in slot0 */
812200161856Syc 				case N2_CLAUSE45_PORT_ADDR_BASE:
812300161856Syc 					hw_p->niu_type = NEPTUNE_1_TN1010;
812400161856Syc 					break;
812500161856Syc 
812600161856Syc 				/* The XAUI is in slot1 */
812700161856Syc 				case (N2_CLAUSE45_PORT_ADDR_BASE + 1):
812800161856Syc 					hw_p->niu_type
812900161856Syc 					    = NEPTUNE_1_NONE_1_TN1010;
813000161856Syc 					break;
813100161856Syc 				default:
813200161856Syc 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
813300161856Syc 					    "Unsupported XAUI port address"));
813400161856Syc 					goto error_exit;
813500161856Syc 				}
813600161856Syc 				hw_p->xcvr_addr[nxgep->function_num]
813700161856Syc 				    = port_fd_arr[0];
813800161856Syc 
81392d17280bSsbehera 			} else {
81402d17280bSsbehera 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
814100161856Syc 				    "Unsupported PHY type"));
81422d17280bSsbehera 				goto error_exit;
81432d17280bSsbehera 			}
81442d17280bSsbehera 			break;
814500161856Syc 		case 4: /* Maramba always have 4 clause 45 ports */
814659ac0c16Sdavemq 
814700161856Syc 			/* Maramba with 1 XAUI */
814852ccf843Smisaki 			if ((port_pcs_dev_id[0] != PHY_BCM8704_FAMILY) &&
814952ccf843Smisaki 			    (port_pma_pmd_dev_id[0] != PHY_BCM8704_FAMILY) &&
815000161856Syc 			    ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
815152ccf843Smisaki 			    != TN1010_DEV_ID) &&
815200161856Syc 			    ((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
815352ccf843Smisaki 			    != TN1010_DEV_ID)) {
815452ccf843Smisaki 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
815552ccf843Smisaki 				    "Unsupported neptune type 12"));
815652ccf843Smisaki 				goto error_exit;
815752ccf843Smisaki 			}
81582e59129aSraghus 
815952ccf843Smisaki 			/*
816052ccf843Smisaki 			 * Check the first phy port address against
816152ccf843Smisaki 			 * the known phy start addresses to determine
816252ccf843Smisaki 			 * the platform type.
816352ccf843Smisaki 			 */
816452ccf843Smisaki 			switch (phy_fd_arr[0]) {
816552ccf843Smisaki 			case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE:
816652ccf843Smisaki 				hw_p->platform_type =
816752ccf843Smisaki 				    P_NEPTUNE_MARAMBA_P0;
816852ccf843Smisaki 				break;
816952ccf843Smisaki 			case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
817052ccf843Smisaki 				hw_p->platform_type =
817152ccf843Smisaki 				    P_NEPTUNE_MARAMBA_P1;
817252ccf843Smisaki 				break;
817352ccf843Smisaki 			default:
817452ccf843Smisaki 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
817552ccf843Smisaki 				    "Unknown port %d...Cannot "
817652ccf843Smisaki 				    "determine platform type 10 - 2",
817752ccf843Smisaki 				    i));
817852ccf843Smisaki 				goto error_exit;
817952ccf843Smisaki 			}
818052ccf843Smisaki 
818152ccf843Smisaki 			/*
818252ccf843Smisaki 			 * Check the clause45 address to determine
818352ccf843Smisaki 			 * if XAUI is in port 0 or port 1.
818452ccf843Smisaki 			 */
818552ccf843Smisaki 			switch (port_fd_arr[0]) {
818652ccf843Smisaki 			case MARAMBA_CLAUSE45_PORT_ADDR_BASE:
818752ccf843Smisaki 				if (port_pcs_dev_id[0]
818852ccf843Smisaki 				    == PHY_BCM8704_FAMILY ||
818952ccf843Smisaki 				    port_pma_pmd_dev_id[0]
819052ccf843Smisaki 				    == PHY_BCM8704_FAMILY) {
819152ccf843Smisaki 					hw_p->niu_type
819252ccf843Smisaki 					    = NEPTUNE_1_10GF_3_1GC;
819352ccf843Smisaki 				} else {
819452ccf843Smisaki 					hw_p->niu_type
819552ccf843Smisaki 					    = NEPTUNE_1_TN1010_3_1GC;
819659ac0c16Sdavemq 				}
819752ccf843Smisaki 				hw_p->xcvr_addr[0] = port_fd_arr[0];
819852ccf843Smisaki 				for (i = 1; i < NXGE_MAX_PORTS; i++) {
819952ccf843Smisaki 					hw_p->xcvr_addr[i] =
820052ccf843Smisaki 					    phy_fd_arr[i];
820152ccf843Smisaki 				}
820252ccf843Smisaki 				break;
820352ccf843Smisaki 			case (MARAMBA_CLAUSE45_PORT_ADDR_BASE + 1):
820452ccf843Smisaki 				if (port_pcs_dev_id[0]
820552ccf843Smisaki 				    == PHY_BCM8704_FAMILY ||
820652ccf843Smisaki 				    port_pma_pmd_dev_id[0]
820752ccf843Smisaki 				    == PHY_BCM8704_FAMILY) {
820852ccf843Smisaki 					hw_p->niu_type =
820952ccf843Smisaki 					    NEPTUNE_1_1GC_1_10GF_2_1GC;
821052ccf843Smisaki 				} else {
821152ccf843Smisaki 					hw_p->niu_type =
821252ccf843Smisaki 					    NEPTUNE_1_1GC_1_TN1010_2_1GC;
821352ccf843Smisaki 				}
821452ccf843Smisaki 				hw_p->xcvr_addr[0] = phy_fd_arr[0];
821552ccf843Smisaki 				hw_p->xcvr_addr[1] = port_fd_arr[0];
821652ccf843Smisaki 				hw_p->xcvr_addr[2] = phy_fd_arr[2];
821752ccf843Smisaki 				hw_p->xcvr_addr[3] = phy_fd_arr[3];
821852ccf843Smisaki 				break;
821952ccf843Smisaki 			default:
822059ac0c16Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
822152ccf843Smisaki 				    "Unsupported neptune type 11"));
822259ac0c16Sdavemq 				goto error_exit;
822359ac0c16Sdavemq 			}
822452ccf843Smisaki 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
822552ccf843Smisaki 			    "Maramba with 1 XAUI (fiber or copper)"));
822659ac0c16Sdavemq 			break;
822759ac0c16Sdavemq 		default:
822859ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
822959ac0c16Sdavemq 			    "Unsupported neptune type 13"));
823059ac0c16Sdavemq 			goto error_exit;
823159ac0c16Sdavemq 		}
823259ac0c16Sdavemq 		break;
823300161856Syc 	case 0: /* 4 ports Neptune based NIC */
823459ac0c16Sdavemq 		switch (total_phy_fd) {
823559ac0c16Sdavemq 		case 4:
823630505775Ssbehera 			if ((port_phy_id[0] == PHY_BCM5464R_FAMILY) &&
823730505775Ssbehera 			    (port_phy_id[1] == PHY_BCM5464R_FAMILY) &&
823830505775Ssbehera 			    (port_phy_id[2] == PHY_BCM5464R_FAMILY) &&
823930505775Ssbehera 			    (port_phy_id[3] == PHY_BCM5464R_FAMILY)) {
824059ac0c16Sdavemq 
824159ac0c16Sdavemq 				/*
824259ac0c16Sdavemq 				 * Check the first phy port address against
824359ac0c16Sdavemq 				 * the known phy start addresses to determine
824459ac0c16Sdavemq 				 * the platform type.
824559ac0c16Sdavemq 				 */
82462d17280bSsbehera 				switch (phy_fd_arr[0]) {
824700161856Syc 				case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
824859ac0c16Sdavemq 					hw_p->platform_type =
824959ac0c16Sdavemq 					    P_NEPTUNE_MARAMBA_P1;
82502d17280bSsbehera 					break;
825100161856Syc 				case NEPTUNE_CLAUSE22_PORT_ADDR_BASE:
82522e59129aSraghus 					hw_p->platform_type =
82532e59129aSraghus 					    P_NEPTUNE_ATLAS_4PORT;
82542d17280bSsbehera 					break;
82552d17280bSsbehera 				default:
82562e59129aSraghus 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
82572e59129aSraghus 					    "Unknown port %d...Cannot "
82582e59129aSraghus 					    "determine platform type", i));
82592e59129aSraghus 					goto error_exit;
826059ac0c16Sdavemq 				}
82612e59129aSraghus 				hw_p->niu_type = NEPTUNE_4_1GC;
82622d17280bSsbehera 				for (i = 0; i < NXGE_MAX_PORTS; i++) {
82632d17280bSsbehera 					hw_p->xcvr_addr[i] = phy_fd_arr[i];
82642d17280bSsbehera 				}
826559ac0c16Sdavemq 			} else {
826659ac0c16Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
826759ac0c16Sdavemq 				    "Unsupported neptune type 14"));
826859ac0c16Sdavemq 				goto error_exit;
826959ac0c16Sdavemq 			}
827059ac0c16Sdavemq 			break;
827159ac0c16Sdavemq 		case 3:
827259ac0c16Sdavemq 			/* TODO 3 1G mode */
827359ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
827459ac0c16Sdavemq 			    "Unsupported neptune type 15"));
827559ac0c16Sdavemq 			goto error_exit;
827659ac0c16Sdavemq 		case 2:
827759ac0c16Sdavemq 			/* TODO 2 1G mode */
827859a835ddSjoycey 			if ((port_phy_id[0] == PHY_BCM5482_FAMILY) &&
827959a835ddSjoycey 			    (port_phy_id[1] == PHY_BCM5482_FAMILY)) {
828059a835ddSjoycey 				hw_p->platform_type = P_NEPTUNE_GENERIC;
828159a835ddSjoycey 				hw_p->niu_type = NEPTUNE_2_1GRF;
828259a835ddSjoycey 				hw_p->xcvr_addr[2] = phy_fd_arr[0];
828359a835ddSjoycey 				hw_p->xcvr_addr[3] = phy_fd_arr[1];
828459a835ddSjoycey 			} else {
828559a835ddSjoycey 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
828659a835ddSjoycey 				    "Unsupported neptune type 16"));
828759a835ddSjoycey 				goto error_exit;
828859a835ddSjoycey 			}
828959ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
829059a835ddSjoycey 			    "2 RGMII Fiber ports - RTM"));
829159a835ddSjoycey 			break;
829259a835ddSjoycey 
829359ac0c16Sdavemq 		case 1:
829459ac0c16Sdavemq 			/* TODO 1 1G mode */
829559ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
829659ac0c16Sdavemq 			    "Unsupported neptune type 17"));
829759ac0c16Sdavemq 			goto error_exit;
829859ac0c16Sdavemq 		default:
829959ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
830059ac0c16Sdavemq 			    "Unsupported neptune type 18, total phy fd %d",
830159ac0c16Sdavemq 			    total_phy_fd));
830259ac0c16Sdavemq 			goto error_exit;
830359ac0c16Sdavemq 		}
830459ac0c16Sdavemq 		break;
830559ac0c16Sdavemq 	default:
830656d930aeSspeer 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
830759ac0c16Sdavemq 		    "Unsupported neptune type 19"));
830859ac0c16Sdavemq 		goto error_exit;
830944961713Sgirish 	}
831044961713Sgirish 
831159ac0c16Sdavemq scan_exit:
831244961713Sgirish 
831359ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, "
831459ac0c16Sdavemq 	    "niu type [0x%x]\n", hw_p->niu_type));
831559ac0c16Sdavemq 	return (status);
831644961713Sgirish 
831759ac0c16Sdavemq error_exit:
831859ac0c16Sdavemq 	return (NXGE_ERROR);
831944961713Sgirish }
832056d930aeSspeer 
832156d930aeSspeer boolean_t
nxge_is_valid_local_mac(ether_addr_st mac_addr)832256d930aeSspeer nxge_is_valid_local_mac(ether_addr_st mac_addr)
832356d930aeSspeer {
832456d930aeSspeer 	if ((mac_addr.ether_addr_octet[0] & 0x01) ||
832556d930aeSspeer 	    (ether_cmp(&mac_addr, &etherbroadcastaddr) == 0) ||
832656d930aeSspeer 	    (ether_cmp(&mac_addr, &etherzeroaddr) == 0))
832756d930aeSspeer 		return (B_FALSE);
832856d930aeSspeer 	else
832956d930aeSspeer 		return (B_TRUE);
833056d930aeSspeer }
833159ac0c16Sdavemq 
833259ac0c16Sdavemq static void
nxge_bcm5464_link_led_off(p_nxge_t nxgep)833391f84442SToomas Soome nxge_bcm5464_link_led_off(p_nxge_t nxgep)
833491f84442SToomas Soome {
833559ac0c16Sdavemq 
833659ac0c16Sdavemq 	npi_status_t rs = NPI_SUCCESS;
833759ac0c16Sdavemq 	uint8_t xcvr_portn;
833859ac0c16Sdavemq 	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
833959ac0c16Sdavemq 
834059ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_bcm5464_link_led_off"));
834159ac0c16Sdavemq 
8342*e3d11eeeSToomas Soome 	switch (nxgep->nxge_hw_p->platform_type) {
8343*e3d11eeeSToomas Soome 	case P_NEPTUNE_MARAMBA_P1:
834400161856Syc 		xcvr_portn = MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE;
8345*e3d11eeeSToomas Soome 		break;
8346*e3d11eeeSToomas Soome 	case P_NEPTUNE_MARAMBA_P0:
834700161856Syc 		xcvr_portn = MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE;
8348*e3d11eeeSToomas Soome 		break;
8349*e3d11eeeSToomas Soome 	default:
8350*e3d11eeeSToomas Soome 		xcvr_portn = 0;
8351*e3d11eeeSToomas Soome 		break;
835259ac0c16Sdavemq 	}
835359ac0c16Sdavemq 	/*
835459ac0c16Sdavemq 	 * For Altas 4-1G copper, Xcvr port numbers are
835559ac0c16Sdavemq 	 * swapped with ethernet port number. This is
835659ac0c16Sdavemq 	 * designed for better signal integrity in routing.
835759ac0c16Sdavemq 	 */
835859ac0c16Sdavemq 	switch (portn) {
835959ac0c16Sdavemq 	case 0:
836059ac0c16Sdavemq 		xcvr_portn += 3;
836159ac0c16Sdavemq 		break;
836259ac0c16Sdavemq 	case 1:
836359ac0c16Sdavemq 		xcvr_portn += 2;
836459ac0c16Sdavemq 		break;
836559ac0c16Sdavemq 	case 2:
836659ac0c16Sdavemq 		xcvr_portn += 1;
836759ac0c16Sdavemq 		break;
836859ac0c16Sdavemq 	case 3:
836959ac0c16Sdavemq 	default:
837059ac0c16Sdavemq 		break;
837159ac0c16Sdavemq 	}
837259ac0c16Sdavemq 
8373321febdeSsbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
837459ac0c16Sdavemq 	rs = npi_mac_mif_mii_write(nxgep->npi_handle,
837559ac0c16Sdavemq 	    xcvr_portn, BCM5464R_MISC, 0xb4ee);
837659ac0c16Sdavemq 	if (rs != NPI_SUCCESS) {
837759ac0c16Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
837859ac0c16Sdavemq 		    "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
837959ac0c16Sdavemq 		    "returned error 0x[%x]", rs));
8380321febdeSsbehera 		MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
838159ac0c16Sdavemq 		return;
838259ac0c16Sdavemq 	}
838359ac0c16Sdavemq 
838459ac0c16Sdavemq 	rs = npi_mac_mif_mii_write(nxgep->npi_handle,
838559ac0c16Sdavemq 	    xcvr_portn, BCM5464R_MISC, 0xb8ee);
838659ac0c16Sdavemq 	if (rs != NPI_SUCCESS) {
838759ac0c16Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
838859ac0c16Sdavemq 		    "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
838959ac0c16Sdavemq 		    "returned error 0x[%x]", rs));
839059ac0c16Sdavemq 	}
839159ac0c16Sdavemq 
8392321febdeSsbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
839359ac0c16Sdavemq }
8394d81011f0Ssbehera 
8395d81011f0Ssbehera static nxge_status_t
nxge_mii_get_link_mode(p_nxge_t nxgep)8396d81011f0Ssbehera nxge_mii_get_link_mode(p_nxge_t nxgep)
8397d81011f0Ssbehera {
8398d81011f0Ssbehera 	p_nxge_stats_t	statsp;
8399d81011f0Ssbehera 	uint8_t		xcvr_portn;
8400d81011f0Ssbehera 	p_mii_regs_t	mii_regs;
8401d81011f0Ssbehera 	mii_mode_control_stat_t	mode;
8402d81011f0Ssbehera 	int		status = NXGE_OK;
8403d81011f0Ssbehera 
8404d81011f0Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_get_link_mode"));
8405d81011f0Ssbehera 
8406d81011f0Ssbehera 	statsp = nxgep->statsp;
8407d81011f0Ssbehera 	xcvr_portn = statsp->mac_stats.xcvr_portn;
8408d81011f0Ssbehera 	mii_regs = NULL;
8409d81011f0Ssbehera 	mode.value = 0;
84106b438925Ssbehera 	mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG;
8411d81011f0Ssbehera 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
8412d81011f0Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->shadow),
8413d81011f0Ssbehera 	    mode.value)) != NXGE_OK) {
8414d81011f0Ssbehera 		goto fail;
8415d81011f0Ssbehera 	}
8416d81011f0Ssbehera 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
8417d81011f0Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->shadow),
8418d81011f0Ssbehera 	    &mode.value)) != NXGE_OK) {
8419d81011f0Ssbehera 		goto fail;
8420d81011f0Ssbehera 	}
8421d81011f0Ssbehera 
8422d81011f0Ssbehera 	if (mode.bits.mode == NXGE_MODE_SELECT_FIBER) {
8423d81011f0Ssbehera 		nxgep->mac.portmode = PORT_1G_RGMII_FIBER;
8424d81011f0Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
8425d81011f0Ssbehera 		    "nxge_mii_get_link_mode: fiber mode"));
8426d81011f0Ssbehera 	}
8427d81011f0Ssbehera 
8428d81011f0Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
8429d81011f0Ssbehera 	    "nxge_mii_get_link_mode: "
8430d81011f0Ssbehera 	    "(address 0x%x) port 0x%x mode value 0x%x link mode 0x%x",
84316b438925Ssbehera 	    NXGE_MII_MODE_CONTROL_REG, xcvr_portn,
8432d81011f0Ssbehera 	    mode.value, nxgep->mac.portmode));
8433d81011f0Ssbehera 
8434d81011f0Ssbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
8435d81011f0Ssbehera 	    "<== nxge_mii_get_link_mode"));
8436d81011f0Ssbehera 	return (status);
8437d81011f0Ssbehera fail:
8438d81011f0Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8439d81011f0Ssbehera 	    "<== nxge_mii_get_link_mode (failed)"));
8440d81011f0Ssbehera 	return (NXGE_ERROR);
8441d81011f0Ssbehera }
8442d81011f0Ssbehera 
84431bd6825cSml nxge_status_t
nxge_mac_set_framesize(p_nxge_t nxgep)84441bd6825cSml nxge_mac_set_framesize(p_nxge_t nxgep)
84451bd6825cSml {
84461bd6825cSml 	npi_attr_t		ap;
84471bd6825cSml 	uint8_t			portn;
84481bd6825cSml 	npi_handle_t		handle;
84491bd6825cSml 	npi_status_t		rs = NPI_SUCCESS;
84501bd6825cSml 
84511bd6825cSml 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_set_framesize"));
84521bd6825cSml 
84531bd6825cSml 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
84541bd6825cSml 	handle = nxgep->npi_handle;
84551bd6825cSml 
84561bd6825cSml 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84571bd6825cSml 	    "==> nxge_mac_sec_framesize: port<%d> "
84581bd6825cSml 	    "min framesize %d max framesize %d ",
84591bd6825cSml 	    portn,
84601bd6825cSml 	    nxgep->mac.minframesize,
84611bd6825cSml 	    nxgep->mac.maxframesize));
84621bd6825cSml 
84631bd6825cSml 	SET_MAC_ATTR2(handle, ap, portn,
84641bd6825cSml 	    MAC_PORT_FRAME_SIZE,
84651bd6825cSml 	    nxgep->mac.minframesize,
84661bd6825cSml 	    nxgep->mac.maxframesize,
84671bd6825cSml 	    rs);
84681bd6825cSml 	if (rs != NPI_SUCCESS) {
84691bd6825cSml 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84701bd6825cSml 		    "<== nxge_mac_set_framesize: failed to configure "
84711bd6825cSml 		    "max/min frame size port %d", portn));
84721bd6825cSml 
84731bd6825cSml 		return (NXGE_ERROR | rs);
84741bd6825cSml 	}
84751bd6825cSml 
84761bd6825cSml 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84771bd6825cSml 	    "<== nxge_mac_set_framesize: port<%d>", portn));
84781bd6825cSml 
84791bd6825cSml 	return (NXGE_OK);
84801bd6825cSml }
84811bd6825cSml 
848200161856Syc static nxge_status_t
nxge_get_num_of_xaui(uint32_t * port_pma_pmd_dev_id,uint32_t * port_pcs_dev_id,uint32_t * port_phy_id,uint8_t * num_xaui)848300161856Syc nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id,
848400161856Syc     uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui)
848500161856Syc {
848600161856Syc 	uint8_t i;
848700161856Syc 
848800161856Syc 	for (i = 0; i < 4; i++) {
848900161856Syc 		if (port_phy_id[i] != PHY_BCM5464R_FAMILY)
849000161856Syc 			return (NXGE_ERROR);
849100161856Syc 	}
849200161856Syc 
849300161856Syc 	*num_xaui = 0;
849400161856Syc 	if ((port_pma_pmd_dev_id[0]  == PHY_BCM8704_FAMILY &&
849591f84442SToomas Soome 	    port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) ||
849600161856Syc 	    (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
849700161856Syc 	    == TN1010_DEV_ID) &&
849800161856Syc 	    ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
849900161856Syc 	    == TN1010_DEV_ID))) {
850000161856Syc 		(*num_xaui) ++;
850100161856Syc 	}
850200161856Syc 	if ((port_pma_pmd_dev_id[1]  == PHY_BCM8704_FAMILY &&
850300161856Syc 	    port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) ||
850400161856Syc 	    (((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK)
850500161856Syc 	    == TN1010_DEV_ID) &&
850600161856Syc 	    ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
850700161856Syc 	    == TN1010_DEV_ID))) {
850800161856Syc 		(*num_xaui) ++;
850900161856Syc 	}
851000161856Syc 	return (NXGE_OK);
851100161856Syc }
851200161856Syc 
851300161856Syc /*
851400161856Syc  * Instruction from Teranetics:  Once you detect link is up, go
851500161856Syc  * read Reg 30.1.4 for link speed: '1' for 1G and '0' for 10G. You
851600161856Syc  * may want to qualify it by first checking Register 30.1.7:6 and
851700161856Syc  * making sure it reads "01" (Auto-Neg Complete).
851800161856Syc  *
851900161856Syc  * If this function is called when the link is down or before auto-
852000161856Syc  * negotiation has completed, then the speed of the PHY is not certain.
852100161856Syc  * In such cases, this function returns 1G as the default speed with
852200161856Syc  * NXGE_OK status instead of NXGE_ERROR.  It is OK to initialize the
852300161856Syc  * driver based on a default speed because this function will be called
852400161856Syc  * again when the link comes up.  Returning NXGE_ERROR, which may
852500161856Syc  * cause brutal chain reaction in caller functions, is not necessary.
852600161856Syc  */
852700161856Syc static nxge_status_t
nxge_get_tn1010_speed(p_nxge_t nxgep,uint16_t * speed)852800161856Syc nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed)
852900161856Syc {
853000161856Syc 	uint8_t		phy_port_addr, autoneg_stat, link_up;
853100161856Syc 	nxge_status_t	status = NXGE_OK;
853200161856Syc 	uint16_t	val;
853300161856Syc 	uint8_t		portn = NXGE_GET_PORT_NUM(nxgep->function_num);
853400161856Syc 
853500161856Syc 	/* Set default speed to 10G */
853600161856Syc 	*speed = TN1010_SPEED_10G;
853700161856Syc 
853800161856Syc 	/* Set Clause 45 */
853900161856Syc 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
854000161856Syc 
854100161856Syc 	phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
854200161856Syc 
854300161856Syc 	/* Check Device 1 Register 0xA bit0 for link up status */
854400161856Syc 	status = nxge_mdio_read(nxgep, phy_port_addr,
854500161856Syc 	    TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val);
854600161856Syc 	if (status != NXGE_OK)
854700161856Syc 		goto fail;
854800161856Syc 
854900161856Syc 	link_up = ((val & TN1010_AN_LINK_STAT_BIT)
855000161856Syc 	    ? B_TRUE : B_FALSE);
855100161856Syc 	if (link_up == B_FALSE) {
855200161856Syc 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
855300161856Syc 		    "nxge_get_tn1010_speed: link is down"));
855400161856Syc 		goto nxge_get_tn1010_speed_exit;
855500161856Syc 	}
855600161856Syc 
855700161856Syc 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
855800161856Syc 	    TN1010_VENDOR_MMD1_DEV_ADDR, TN1010_VENDOR_MMD1_STATUS_REG,
855900161856Syc 	    &val)) != NXGE_OK) {
856000161856Syc 		goto fail;
856100161856Syc 	}
856200161856Syc 	autoneg_stat = (val & TN1010_VENDOR_MMD1_AN_STAT_BITS) >>
856300161856Syc 	    TN1010_VENDOR_MMD1_AN_STAT_SHIFT;
856400161856Syc 
856500161856Syc 	/*
856600161856Syc 	 * Return NXGE_OK even when we can not get a settled speed. In
856700161856Syc 	 * such case, the speed reported should not be trusted but that
856800161856Syc 	 * is OK, we will call this function periodically and will get
856900161856Syc 	 * the correct speed after the link is up.
857000161856Syc 	 */
857100161856Syc 	switch (autoneg_stat) {
857200161856Syc 	case TN1010_AN_IN_PROG:
857300161856Syc 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
857400161856Syc 		    "nxge_get_tn1010_speed: Auto-negotiation in progress"));
857500161856Syc 		break;
857600161856Syc 	case TN1010_AN_COMPLETE:
857700161856Syc 		if ((status = nxge_mdio_read(nxgep, phy_port_addr,
857800161856Syc 		    TN1010_VENDOR_MMD1_DEV_ADDR,
857900161856Syc 		    TN1010_VENDOR_MMD1_STATUS_REG,
858000161856Syc 		    &val)) != NXGE_OK) {
858100161856Syc 			goto fail;
858200161856Syc 		}
858300161856Syc 		*speed = (val & TN1010_VENDOR_MMD1_AN_SPEED_BIT) >>
858400161856Syc 		    TN1010_VENDOR_MMD1_AN_SPEED_SHIFT;
858500161856Syc 		break;
858600161856Syc 	case TN1010_AN_RSVD:
858700161856Syc 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
858800161856Syc 		    "nxge_get_tn1010_speed: Autoneg status undefined"));
858900161856Syc 		break;
859000161856Syc 	case TN1010_AN_FAILED:
859100161856Syc 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
859200161856Syc 		    "nxge_get_tn1010_speed: Auto-negotiation failed"));
859300161856Syc 		break;
859400161856Syc 	default:
859500161856Syc 		break;
859600161856Syc 	}
859700161856Syc nxge_get_tn1010_speed_exit:
859800161856Syc 	return (NXGE_OK);
859900161856Syc fail:
860000161856Syc 	return (status);
860100161856Syc }
860200161856Syc 
860300161856Syc 
860400161856Syc /*
860500161856Syc  * Teranetics TN1010 PHY chip supports both 1G and 10G modes, this function
860600161856Syc  * figures out the speed of the PHY determined by the autonegotiation
860700161856Syc  * process and sets the following 3 parameters,
860891f84442SToomas Soome  *	nxgep->mac.portmode
860991f84442SToomas Soome  *	nxgep->statsp->mac_stats.link_speed
861000161856Syc  *	nxgep->statsp->mac_stats.xcvr_inuse
861100161856Syc  */
861200161856Syc static nxge_status_t
nxge_set_tn1010_param(p_nxge_t nxgep)861300161856Syc nxge_set_tn1010_param(p_nxge_t nxgep)
861400161856Syc {
861500161856Syc 	uint16_t speed;
861600161856Syc 
861700161856Syc 	if (nxge_get_tn1010_speed(nxgep,  &speed) != NXGE_OK) {
861800161856Syc 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
861900161856Syc 		    "nxge_set_tn1010_param: "
862000161856Syc 		    "Failed to get TN1010 speed"));
862100161856Syc 		return (NXGE_ERROR);
862200161856Syc 	}
862300161856Syc 	if (speed == TN1010_SPEED_1G) {
862400161856Syc 		nxgep->mac.portmode = PORT_1G_TN1010;
862500161856Syc 		nxgep->statsp->mac_stats.link_speed = 1000;
862600161856Syc 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
862700161856Syc 	} else {
862800161856Syc 		nxgep->mac.portmode = PORT_10G_TN1010;
862900161856Syc 		nxgep->statsp->mac_stats.link_speed = 10000;
863000161856Syc 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
863100161856Syc 	}
863200161856Syc 	return (NXGE_OK);
863300161856Syc }
863400161856Syc 
8635d81011f0Ssbehera #ifdef NXGE_DEBUG
8636d81011f0Ssbehera static void
nxge_mii_dump(p_nxge_t nxgep)8637d81011f0Ssbehera nxge_mii_dump(p_nxge_t nxgep)
8638d81011f0Ssbehera {
8639d81011f0Ssbehera 	p_nxge_stats_t	statsp;
8640d81011f0Ssbehera 	uint8_t		xcvr_portn;
8641d81011f0Ssbehera 	p_mii_regs_t	mii_regs;
8642d81011f0Ssbehera 	mii_bmcr_t	bmcr;
8643d81011f0Ssbehera 	mii_bmsr_t	bmsr;
8644d81011f0Ssbehera 	mii_idr1_t	idr1;
8645d81011f0Ssbehera 	mii_idr2_t	idr2;
8646d81011f0Ssbehera 	mii_mode_control_stat_t	mode;
8647678453a8Sspeer 	p_nxge_param_t	param_arr;
8648d81011f0Ssbehera 
8649d81011f0Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "==> nxge_mii_dump"));
8650d81011f0Ssbehera 
8651d81011f0Ssbehera 	statsp = nxgep->statsp;
8652d81011f0Ssbehera 	xcvr_portn = statsp->mac_stats.xcvr_portn;
8653d81011f0Ssbehera 
8654d81011f0Ssbehera 	mii_regs = NULL;
8655d81011f0Ssbehera 
8656d81011f0Ssbehera 	(void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn,
8657d81011f0Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value);
8658d81011f0Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8659d81011f0Ssbehera 	    "nxge_mii_dump: bmcr (0) xcvr 0x%x value 0x%x",
8660d81011f0Ssbehera 	    xcvr_portn, bmcr.value));
8661d81011f0Ssbehera 
8662d81011f0Ssbehera 	(void) nxge_mii_read(nxgep,
8663d81011f0Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
8664d81011f0Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value);
8665d81011f0Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8666d81011f0Ssbehera 	    "nxge_mii_dump: bmsr (1) xcvr 0x%x value 0x%x",
8667d81011f0Ssbehera 	    xcvr_portn, bmsr.value));
8668d81011f0Ssbehera 
8669d81011f0Ssbehera 	(void) nxge_mii_read(nxgep,
8670d81011f0Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
8671d81011f0Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->idr1), &idr1.value);
8672d81011f0Ssbehera 
8673d81011f0Ssbehera 
8674d81011f0Ssbehera 	(void) nxge_mii_read(nxgep,
8675d81011f0Ssbehera 	    nxgep->statsp->mac_stats.xcvr_portn,
8676d81011f0Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->idr2), &idr2.value);
8677d81011f0Ssbehera 
8678d81011f0Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8679d81011f0Ssbehera 	    "nxge_mii_dump: idr1 (2) xcvr 0x%x value 0x%x",
8680d81011f0Ssbehera 	    xcvr_portn, idr1.value));
8681d81011f0Ssbehera 
8682d81011f0Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8683d81011f0Ssbehera 	    "nxge_mii_dump: idr2 (3) xcvr 0x%x value 0x%x",
8684d81011f0Ssbehera 	    xcvr_portn, idr2.value));
8685d81011f0Ssbehera 
8686d81011f0Ssbehera 	mode.value = 0;
86876b438925Ssbehera 	mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG;
8688d81011f0Ssbehera 
8689d81011f0Ssbehera 	(void) nxge_mii_write(nxgep, xcvr_portn,
8690d81011f0Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->shadow), mode.value);
8691d81011f0Ssbehera 
8692d81011f0Ssbehera 	(void) nxge_mii_read(nxgep, xcvr_portn,
8693d81011f0Ssbehera 	    (uint8_t)(uint64_t)(&mii_regs->shadow), &mode.value);
8694d81011f0Ssbehera 
8695d81011f0Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
8696d81011f0Ssbehera 	    "nxge_mii_dump: mode control xcvr 0x%x value 0x%x",
8697d81011f0Ssbehera 	    xcvr_portn, mode.value));
8698d81011f0Ssbehera }
8699d81011f0Ssbehera #endif
8700