xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_mac.c (revision 86ef0a63e1cfa5dc98606efef379365acca98063)
16f45ec7bSml29623 /*
26f45ec7bSml29623  * CDDL HEADER START
36f45ec7bSml29623  *
46f45ec7bSml29623  * The contents of this file are subject to the terms of the
56f45ec7bSml29623  * Common Development and Distribution License (the "License").
66f45ec7bSml29623  * You may not use this file except in compliance with the License.
76f45ec7bSml29623  *
86f45ec7bSml29623  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96f45ec7bSml29623  * or http://www.opensolaris.org/os/licensing.
106f45ec7bSml29623  * See the License for the specific language governing permissions
116f45ec7bSml29623  * and limitations under the License.
126f45ec7bSml29623  *
136f45ec7bSml29623  * When distributing Covered Code, include this CDDL HEADER in each
146f45ec7bSml29623  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156f45ec7bSml29623  * If applicable, add the following below this CDDL HEADER, with the
166f45ec7bSml29623  * fields enclosed by brackets "[]" replaced with your own identifying
176f45ec7bSml29623  * information: Portions Copyright [yyyy] [name of copyright owner]
186f45ec7bSml29623  *
196f45ec7bSml29623  * CDDL HEADER END
206f45ec7bSml29623  */
216f45ec7bSml29623 /*
2289282175SSantwona Behera  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
236f45ec7bSml29623  */
246f45ec7bSml29623 
256f45ec7bSml29623 #include <sys/nxge/nxge_impl.h>
266f45ec7bSml29623 #include <sys/nxge/nxge_mac.h>
27678453a8Sspeer #include <sys/nxge/nxge_hio.h>
286f45ec7bSml29623 
2998ecde52Stm144005 #define	LINK_MONITOR_PERIOD	(1000 * 1000)
3098ecde52Stm144005 #define	LM_WAIT_MULTIPLIER	8
3198ecde52Stm144005 
32321febdeSsbehera #define	SERDES_RDY_WT_INTERVAL	50
33321febdeSsbehera #define	MAX_SERDES_RDY_RETRIES	10
34321febdeSsbehera 
3500161856Syc148097 #define	TN1010_SPEED_1G		1
3600161856Syc148097 #define	TN1010_SPEED_10G	0
3700161856Syc148097 #define	TN1010_AN_IN_PROG	0	/* Auto negotiation in progress */
3800161856Syc148097 #define	TN1010_AN_COMPLETE	1
3900161856Syc148097 #define	TN1010_AN_RSVD		2
4000161856Syc148097 #define	TN1010_AN_FAILED	3
4100161856Syc148097 
426f45ec7bSml29623 extern uint32_t nxge_no_link_notify;
4359ac0c16Sdavemq extern boolean_t nxge_no_msg;
446f45ec7bSml29623 extern uint32_t nxge_lb_dbg;
454202ea4bSsbehera extern uint32_t nxge_jumbo_mtu;
466f45ec7bSml29623 
4798ecde52Stm144005 typedef enum {
4898ecde52Stm144005 	CHECK_LINK_RESCHEDULE,
4998ecde52Stm144005 	CHECK_LINK_STOP
5098ecde52Stm144005 } check_link_state_t;
5198ecde52Stm144005 
5298ecde52Stm144005 static check_link_state_t nxge_check_link_stop(nxge_t *);
5398ecde52Stm144005 
546f45ec7bSml29623 /*
556f45ec7bSml29623  * Ethernet broadcast address definition.
566f45ec7bSml29623  */
576f45ec7bSml29623 static ether_addr_st etherbroadcastaddr =
586f45ec7bSml29623 				{{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,
7000161856Syc148097 	BCM8706_DEV_ID,
7100161856Syc148097 	TN1010_DEV_ID
7252cdd236Ssbehera };
7352cdd236Ssbehera 
74b1000363Sml29623 static uint32_t nxge_supported_cl22_ids[] = {
75b1000363Sml29623     BCM5464R_PHY_ID,
76b1000363Sml29623     BCM5482_PHY_ID
77b1000363Sml29623 };
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);
10900161856Syc148097 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);
11800161856Syc148097 static nxge_status_t nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id,
11900161856Syc148097 	uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui);
12000161856Syc148097 static nxge_status_t nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed);
12100161856Syc148097 static nxge_status_t nxge_set_tn1010_param(p_nxge_t nxgep);
12200161856Syc148097 static nxge_status_t nxge_tn1010_check(p_nxge_t nxgep,
12300161856Syc148097 	nxge_link_state_t *link_up);
12400161856Syc148097 static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep);
12500161856Syc148097 static nxge_status_t nxge_tn1010_xcvr_init(p_nxge_t nxgep);
12600161856Syc148097 
12700161856Syc148097 nxge_status_t nxge_mac_init(p_nxge_t);
12800161856Syc148097 static nxge_status_t nxge_mii_get_link_mode(p_nxge_t);
12900161856Syc148097 
13000161856Syc148097 #ifdef NXGE_DEBUG
13100161856Syc148097 static void nxge_mii_dump(p_nxge_t);
13200161856Syc148097 static nxge_status_t nxge_tn1010_reset(p_nxge_t nxgep);
13300161856Syc148097 static void nxge_dump_tn1010_status_regs(p_nxge_t nxgep);
13400161856Syc148097 #endif
13559ac0c16Sdavemq 
13659ac0c16Sdavemq /*
13759ac0c16Sdavemq  * xcvr tables for supported transceivers
13859ac0c16Sdavemq  */
13959ac0c16Sdavemq 
14000161856Syc148097 /*
14100161856Syc148097  * nxge_n2_10G_table is for 10G fiber or serdes on N2-NIU systems.
14200161856Syc148097  * The Teranetics TN1010 based copper XAUI card can also be used
14300161856Syc148097  * on N2-NIU systems in 10G mode, but it uses its own table
14400161856Syc148097  * nxge_n2_10G_tn1010_table below.
14500161856Syc148097  */
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 
15500161856Syc148097 /*
15600161856Syc148097  * For the Teranetics TN1010 based copper XAUI card
15700161856Syc148097  */
15800161856Syc148097 static nxge_xcvr_table_t nxge_n2_10G_tn1010_table = {
15900161856Syc148097 	nxge_n2_serdes_init,		/* Handle both 1G and 10G */
16000161856Syc148097 	nxge_tn1010_xcvr_init,		/* Handle both 1G and 10G */
16100161856Syc148097 	nxge_10G_link_intr_stop,
16200161856Syc148097 	nxge_10G_link_intr_start,
16300161856Syc148097 	nxge_check_tn1010_link,		/* Will figure out speed */
16400161856Syc148097 	XPCS_XCVR
16500161856Syc148097 };
16600161856Syc148097 
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 
17600161856Syc148097 static nxge_xcvr_table_t nxge_n2_1G_tn1010_table = {
17700161856Syc148097 	nxge_n2_serdes_init,
17800161856Syc148097 	nxge_tn1010_xcvr_init,
17900161856Syc148097 	nxge_1G_fiber_link_intr_stop,	/* TN1010 is a Cu PHY, but it uses */
18000161856Syc148097 	nxge_1G_fiber_link_intr_start,	/* PCS for 1G, so call fiber func */
18100161856Syc148097 	nxge_check_tn1010_link,
18200161856Syc148097 	PCS_XCVR
18300161856Syc148097 };
18400161856Syc148097 
18500161856Syc148097 static nxge_xcvr_table_t nxge_10G_tn1010_table = {
18600161856Syc148097 	nxge_neptune_10G_serdes_init,
18700161856Syc148097 	nxge_tn1010_xcvr_init,
18800161856Syc148097 	nxge_10G_link_intr_stop,
18900161856Syc148097 	nxge_10G_link_intr_start,
19000161856Syc148097 	nxge_check_tn1010_link,
19100161856Syc148097 	XPCS_XCVR
19200161856Syc148097 };
19300161856Syc148097 
19400161856Syc148097 static nxge_xcvr_table_t nxge_1G_tn1010_table = {
19500161856Syc148097 	nxge_1G_serdes_init,
19600161856Syc148097 	nxge_tn1010_xcvr_init,
19700161856Syc148097 	nxge_1G_fiber_link_intr_stop,
19800161856Syc148097 	nxge_1G_fiber_link_intr_start,
19900161856Syc148097 	nxge_check_tn1010_link,
20000161856Syc148097 	PCS_XCVR
20100161856Syc148097 };
20200161856Syc148097 
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 
22100161856Syc148097 /* 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 };
2396f45ec7bSml29623 
24000161856Syc148097 /*
24100161856Syc148097  * NXGE_PORT_TN1010 is defined as,
24200161856Syc148097  *      NXGE_PORT_SPD_NONE | (NXGE_PHY_TN1010 << NXGE_PHY_SHIFT)
24300161856Syc148097  *	= 0 | 5 << 16 = 0x50000
24400161856Syc148097  *
24500161856Syc148097  * So NEPTUNE_2_TN1010 =
24600161856Syc148097  *      (NXGE_PORT_TN1010 |
24700161856Syc148097  *      (NXGE_PORT_TN1010 << 4) |
24800161856Syc148097  *      (NXGE_PORT_NONE << 8) |
24900161856Syc148097  *      (NXGE_PORT_NONE << 12)),
25000161856Syc148097  *      = 0x50000 | (0x50000 << 4)
25100161856Syc148097  *	= 0x550000
25200161856Syc148097  *
25300161856Syc148097  * This function partitions nxgep->nxge_hw_p->niu_type (which may have
25400161856Syc148097  * value NEPTUNE_2_TN1010) and checks if a port has type = NXGE_PORT_TN1010
25500161856Syc148097  * = 0x50000
25600161856Syc148097  */
nxge_is_tn1010_phy(p_nxge_t nxgep)25700161856Syc148097 static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep)
25800161856Syc148097 {
25900161856Syc148097 	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
2606f45ec7bSml29623 
26100161856Syc148097 	if (((nxgep->nxge_hw_p->niu_type >> (NXGE_PORT_TYPE_SHIFT * portn))
26200161856Syc148097 	    & NXGE_PHY_MASK) == NXGE_PORT_TN1010) {
26300161856Syc148097 		return (B_TRUE);
26400161856Syc148097 	} else {
26500161856Syc148097 		return (B_FALSE);
26600161856Syc148097 	}
26700161856Syc148097 }
268d81011f0Ssbehera 
26900161856Syc148097 
27000161856Syc148097 /*
27100161856Syc148097  * Figure out nxgep->mac.portmode from nxge.conf, OBP's device properties,
27200161856Syc148097  * serial EEPROM or VPD if possible.  Note that not all systems could get
27300161856Syc148097  * the portmode information by calling this function.  For example, the
27400161856Syc148097  * Maramba system figures out the portmode information by calling function
27500161856Syc148097  * nxge_setup_xcvr_table.
27600161856Syc148097  */
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;
28300161856Syc148097 	uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num);
2841c7408c9Stc99174@train 	uint32_t	val;
2851c7408c9Stc99174@train 	npi_status_t	rs;
2861c7408c9Stc99174@train 
2871c7408c9Stc99174@train 	/* For Opus NEM, skip xcvr checking if 10G Serdes link is up */
2881c7408c9Stc99174@train 	if (nxgep->mac.portmode == PORT_10G_SERDES &&
2891c7408c9Stc99174@train 	    nxgep->statsp->mac_stats.link_up) {
2901c7408c9Stc99174@train 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
2911c7408c9Stc99174@train 		return (status);
2921c7408c9Stc99174@train 	}
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;
3311c7408c9Stc99174@train 
3321c7408c9Stc99174@train 		/* Check Serdes link to detect Opus NEM */
3331c7408c9Stc99174@train 		rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
3341c7408c9Stc99174@train 		    XPCS_REG_STATUS, &val);
3351c7408c9Stc99174@train 
3361c7408c9Stc99174@train 		if (rs == 0 && val & XPCS_STATUS_LANE_ALIGN) {
3371c7408c9Stc99174@train 			nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3381c7408c9Stc99174@train 			nxgep->mac.portmode = PORT_10G_SERDES;
3391c7408c9Stc99174@train 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3401c7408c9Stc99174@train 			    "HSP 10G Serdes FOUND!!"));
3411c7408c9Stc99174@train 		}
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 
35300161856Syc148097 	/* 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) {
37700161856Syc148097 			/*
37800161856Syc148097 			 * Before OBP supports new phy-type property
37900161856Syc148097 			 * value "xgc", the 10G copper XAUI may carry
38000161856Syc148097 			 * "xgf" instead of "xgc". If the OBP is
38100161856Syc148097 			 * upgraded to a newer version which supports
38200161856Syc148097 			 * "xgc", then the TN1010 related code in this
38300161856Syc148097 			 * "xgf" case will not be used anymore.
38400161856Syc148097 			 */
38500161856Syc148097 			if (nxge_is_tn1010_phy(nxgep)) {
38600161856Syc148097 				if ((status = nxge_set_tn1010_param(nxgep))
38700161856Syc148097 				    != NXGE_OK) {
38800161856Syc148097 					return (status);
38900161856Syc148097 				}
39000161856Syc148097 				NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
39100161856Syc148097 			} else {  /* For Fiber XAUI */
392321febdeSsbehera 				nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
393321febdeSsbehera 				nxgep->mac.portmode = PORT_10G_FIBER;
39400161856Syc148097 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
39500161856Syc148097 				    "10G Fiber Xcvr"));
39600161856Syc148097 			}
39700161856Syc148097 		} else if (strcmp("xgc", prop_val) == 0) {
39800161856Syc148097 			if ((status = nxge_set_tn1010_param(nxgep)) != NXGE_OK)
39900161856Syc148097 				return (status);
40000161856Syc148097 			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) {
41900161856Syc148097 				/*
42000161856Syc148097 				 * Before OBP supports new phy-type property
42100161856Syc148097 				 * value "xgc", the 10G copper XAUI may carry
42200161856Syc148097 				 * "xgf" instead of "xgc". If the OBP is
42300161856Syc148097 				 * upgraded to a newer version which supports
42400161856Syc148097 				 * "xgc", then the TN1010 related code in this
42500161856Syc148097 				 * "xgf" case will not be used anymore.
42600161856Syc148097 				 */
42700161856Syc148097 				if (nxge_is_tn1010_phy(nxgep)) {
42800161856Syc148097 					if ((status =
42900161856Syc148097 					    nxge_set_tn1010_param(nxgep))
43000161856Syc148097 					    != NXGE_OK) {
43100161856Syc148097 						return (status);
43200161856Syc148097 					}
43300161856Syc148097 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
43400161856Syc148097 					    "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"));
44300161856Syc148097 				} else { /* For Fiber XAUI */
44400161856Syc148097 					nxgep->statsp->mac_stats.xcvr_inuse
44500161856Syc148097 					    = XPCS_XCVR;
4462e59129aSraghus 					nxgep->mac.portmode = PORT_10G_FIBER;
4472e59129aSraghus 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4482e59129aSraghus 					    "10G Fiber Xcvr"));
44900161856Syc148097 				}
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) {
46200161856Syc148097 				status = nxge_set_tn1010_param(nxgep);
46300161856Syc148097 				if (status != NXGE_OK)
46400161856Syc148097 					return (status);
46500161856Syc148097 				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) {
52600161856Syc148097 		status = nxge_set_tn1010_param(nxgep);
52700161856Syc148097 		if (status != NXGE_OK) {
52800161856Syc148097 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
52900161856Syc148097 			    "nxge_get_xcvr_type: Failed to set TN1010 param"));
53000161856Syc148097 			goto read_seeprom;
53100161856Syc148097 		}
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;
60700161856Syc148097 		case PORT_1G_TN1010:
60800161856Syc148097 			nxgep->xcvr = nxge_n2_1G_tn1010_table;
60900161856Syc148097 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
61000161856Syc148097 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61100161856Syc148097 			    "TN1010 Copper Xcvr in 1G"));
61200161856Syc148097 			break;
61300161856Syc148097 		case PORT_10G_TN1010:
61400161856Syc148097 			nxgep->xcvr = nxge_n2_10G_tn1010_table;
61500161856Syc148097 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
61600161856Syc148097 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61700161856Syc148097 			    "TN1010 Copper Xcvr in 10G"));
61800161856Syc148097 			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);
64959ac0c16Sdavemq 			port_type = port_type & (NXGE_PORT_TYPE_MASK);
6502e59129aSraghus 
65159ac0c16Sdavemq 			switch (port_type) {
6522e59129aSraghus 
65359ac0c16Sdavemq 			case NXGE_PORT_1G_COPPER:
65459ac0c16Sdavemq 				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;
67100161856Syc148097 			/* 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;
67500161856Syc148097 			case NXGE_PORT_TN1010:
67600161856Syc148097 				/*
67700161856Syc148097 				 * If this port uses the TN1010 copper
67800161856Syc148097 				 * PHY, then its speed is not known yet
67900161856Syc148097 				 * because nxge_scan_ports_phy could only
68000161856Syc148097 				 * figure out the vendor of the PHY but
68100161856Syc148097 				 * not its speed. nxge_set_tn1010_param
68200161856Syc148097 				 * will read the PHY speed and set
68300161856Syc148097 				 * portmode accordingly.
68400161856Syc148097 				 */
68500161856Syc148097 				if ((status = nxge_set_tn1010_param(nxgep))
68600161856Syc148097 				    != NXGE_OK) {
68700161856Syc148097 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
68800161856Syc148097 					    "nxge_set_tn1010_param failed"));
68900161856Syc148097 					return (status);
69000161856Syc148097 				}
69100161856Syc148097 				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 
70000161856Syc148097 		/*
70100161856Syc148097 		 * Above switch has figured out nxge->mac.portmode, now set
70200161856Syc148097 		 * nxgep->xcvr (the table) and nxgep->xcvr_addr according
70300161856Syc148097 		 * to portmode.
70400161856Syc148097 		 */
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:
72259ac0c16Sdavemq 				switch (portn) {
72359ac0c16Sdavemq 				case 0:
7242d17280bSsbehera 					nxgep->xcvr_addr += 3;
72559ac0c16Sdavemq 					break;
72659ac0c16Sdavemq 				case 1:
7272d17280bSsbehera 					nxgep->xcvr_addr += 1;
72859ac0c16Sdavemq 					break;
72959ac0c16Sdavemq 				case 2:
7302d17280bSsbehera 					nxgep->xcvr_addr -= 1;
73159ac0c16Sdavemq 					break;
73259ac0c16Sdavemq 				case 3:
7332d17280bSsbehera 					nxgep->xcvr_addr -= 3;
73459ac0c16Sdavemq 					break;
73559ac0c16Sdavemq 				default:
73659ac0c16Sdavemq 					return (NXGE_ERROR);
73759ac0c16Sdavemq 				}
73859ac0c16Sdavemq 				break;
7392e59129aSraghus 			default:
7402e59129aSraghus 				break;
7412e59129aSraghus 			}
742d81011f0Ssbehera 
7432e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
7442e59129aSraghus 			    (nxgep->mac.portmode == PORT_1G_COPPER) ?
7452e59129aSraghus 			    "Copper" : "RGMII Fiber"));
7462e59129aSraghus 			break;
74700161856Syc148097 
7482e59129aSraghus 		case PORT_10G_COPPER:
74959ac0c16Sdavemq 			nxgep->xcvr = nxge_10G_copper_table;
75059ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr"));
75159ac0c16Sdavemq 			break;
75200161856Syc148097 
75300161856Syc148097 		case PORT_1G_TN1010:
75400161856Syc148097 			nxgep->xcvr = nxge_1G_tn1010_table;
75500161856Syc148097 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
75600161856Syc148097 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
75700161856Syc148097 			    "1G TN1010 copper Xcvr"));
75800161856Syc148097 			break;
75900161856Syc148097 
76000161856Syc148097 		case PORT_10G_TN1010:
76100161856Syc148097 			nxgep->xcvr = nxge_10G_tn1010_table;
76200161856Syc148097 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
76300161856Syc148097 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
76400161856Syc148097 			    "10G TN1010 copper Xcvr"));
76500161856Syc148097 			break;
76600161856Syc148097 
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 
8946f45ec7bSml29623 /* Initialize the entire MAC and physical layer */
8956f45ec7bSml29623 
8966f45ec7bSml29623 nxge_status_t
nxge_mac_init(p_nxge_t nxgep)8976f45ec7bSml29623 nxge_mac_init(p_nxge_t nxgep)
8986f45ec7bSml29623 {
8996f45ec7bSml29623 	uint8_t			portn;
9006f45ec7bSml29623 	nxge_status_t		status = NXGE_OK;
9016f45ec7bSml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
9026f45ec7bSml29623 
9036f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn));
9046f45ec7bSml29623 
9056f45ec7bSml29623 	nxgep->mac.portnum = portn;
9066f45ec7bSml29623 	nxgep->mac.porttype = PORT_TYPE_XMAC;
9076f45ec7bSml29623 
9086f45ec7bSml29623 	if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1))
9096f45ec7bSml29623 		nxgep->mac.porttype = PORT_TYPE_BMAC;
9106f45ec7bSml29623 
91100161856Syc148097 
9126f45ec7bSml29623 	/* Initialize XIF to configure a network mode */
9136f45ec7bSml29623 	if ((status = nxge_xif_init(nxgep)) != NXGE_OK) {
9146f45ec7bSml29623 		goto fail;
9156f45ec7bSml29623 	}
9166f45ec7bSml29623 
9176f45ec7bSml29623 	if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) {
9186f45ec7bSml29623 		goto fail;
9196f45ec7bSml29623 	}
9206f45ec7bSml29623 
9216f45ec7bSml29623 	/* Initialize TX and RX MACs */
9226f45ec7bSml29623 	/*
9236f45ec7bSml29623 	 * Always perform XIF init first, before TX and RX MAC init
9246f45ec7bSml29623 	 */
9256f45ec7bSml29623 	if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK)
9266f45ec7bSml29623 		goto fail;
9276f45ec7bSml29623 
9286f45ec7bSml29623 	if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
9296f45ec7bSml29623 		goto fail;
9306f45ec7bSml29623 
9316f45ec7bSml29623 	if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK)
9326f45ec7bSml29623 		goto fail;
9336f45ec7bSml29623 
9346f45ec7bSml29623 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
9356f45ec7bSml29623 		goto fail;
9366f45ec7bSml29623 
9376f45ec7bSml29623 	if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK)
9386f45ec7bSml29623 		goto fail;
9396f45ec7bSml29623 
940e759c33aSMichael Speer 	if (nxgep->nxge_mac_state == NXGE_MAC_STARTED) {
9416f45ec7bSml29623 		if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
9426f45ec7bSml29623 			goto fail;
943e759c33aSMichael Speer 	}
9446f45ec7bSml29623 
945cb9d3ae6Smisaki 	/* Initialize MAC control configuration */
946cb9d3ae6Smisaki 	if ((status = nxge_mac_ctrl_init(nxgep)) != NXGE_OK) {
947cb9d3ae6Smisaki 		goto fail;
948cb9d3ae6Smisaki 	}
949cb9d3ae6Smisaki 
9506f45ec7bSml29623 	nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize;
9516f45ec7bSml29623 
952d81011f0Ssbehera 	/* The Neptune Serdes needs to be reinitialized again */
953d81011f0Ssbehera 	if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
954d81011f0Ssbehera 	    ((nxgep->mac.portmode == PORT_1G_SERDES) ||
95500161856Syc148097 	    (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 
9666f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn));
9676f45ec7bSml29623 
9686f45ec7bSml29623 	return (NXGE_OK);
9696f45ec7bSml29623 fail:
9706f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
97152ccf843Smisaki 	    "nxge_mac_init: failed to initialize MAC port<%d>", portn));
9726f45ec7bSml29623 	return (status);
9736f45ec7bSml29623 }
9746f45ec7bSml29623 
9756f45ec7bSml29623 /* Initialize the Ethernet Link */
9766f45ec7bSml29623 
9776f45ec7bSml29623 nxge_status_t
nxge_link_init(p_nxge_t nxgep)9786f45ec7bSml29623 nxge_link_init(p_nxge_t nxgep)
9796f45ec7bSml29623 {
9806f45ec7bSml29623 	nxge_status_t		status = NXGE_OK;
9812e59129aSraghus 	nxge_port_mode_t	portmode;
9826f45ec7bSml29623 #ifdef	NXGE_DEBUG
9836f45ec7bSml29623 	uint8_t			portn;
9846f45ec7bSml29623 
9856f45ec7bSml29623 	portn = nxgep->mac.portnum;
9866f45ec7bSml29623 
9876f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn));
9886f45ec7bSml29623 #endif
9891c7408c9Stc99174@train 	/* For Opus NEM, Serdes always needs to be initialized */
9906f45ec7bSml29623 
9912e59129aSraghus 	portmode = nxgep->mac.portmode;
9922d17280bSsbehera 
99300161856Syc148097 	/*
99400161856Syc148097 	 * Workaround to get link up in both NIU ports. Some portmodes require
99500161856Syc148097 	 * that the xcvr be initialized twice, the first time before calling
99600161856Syc148097 	 * nxge_serdes_init.
99700161856Syc148097 	 */
9982e59129aSraghus 	if (nxgep->niu_type == N2_NIU && (portmode != PORT_10G_SERDES) &&
99900161856Syc148097 	    (portmode != PORT_10G_TN1010) &&
100000161856Syc148097 	    (portmode != PORT_1G_TN1010) &&
10012e59129aSraghus 	    (portmode != PORT_1G_SERDES)) {
10022e59129aSraghus 		if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) {
10036f45ec7bSml29623 			goto fail;
10046f45ec7bSml29623 		}
10052e59129aSraghus 	}
100600161856Syc148097 
10076f45ec7bSml29623 	NXGE_DELAY(200000);
10086f45ec7bSml29623 	/* Initialize internal serdes */
10096f45ec7bSml29623 	if ((status = nxge_serdes_init(nxgep)) != NXGE_OK)
10106f45ec7bSml29623 		goto fail;
10116f45ec7bSml29623 	NXGE_DELAY(200000);
10126f45ec7bSml29623 	if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK)
10136f45ec7bSml29623 		goto fail;
10146f45ec7bSml29623 
10156f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn));
10166f45ec7bSml29623 
10176f45ec7bSml29623 	return (NXGE_OK);
10186f45ec7bSml29623 
10196f45ec7bSml29623 fail:
102052ccf843Smisaki 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_link_init: ",
102152ccf843Smisaki 	    "failed to initialize Ethernet link on port<%d>", portn));
10226f45ec7bSml29623 
10236f45ec7bSml29623 	return (status);
10246f45ec7bSml29623 }
10256f45ec7bSml29623 
10266f45ec7bSml29623 
10276f45ec7bSml29623 /* Initialize the XIF sub-block within the MAC */
10286f45ec7bSml29623 
10296f45ec7bSml29623 nxge_status_t
nxge_xif_init(p_nxge_t nxgep)10306f45ec7bSml29623 nxge_xif_init(p_nxge_t nxgep)
10316f45ec7bSml29623 {
10326f45ec7bSml29623 	uint32_t		xif_cfg = 0;
10336f45ec7bSml29623 	npi_attr_t		ap;
10346f45ec7bSml29623 	uint8_t			portn;
10356f45ec7bSml29623 	nxge_port_t		portt;
10366f45ec7bSml29623 	nxge_port_mode_t	portmode;
10376f45ec7bSml29623 	p_nxge_stats_t		statsp;
10386f45ec7bSml29623 	npi_status_t		rs = NPI_SUCCESS;
10396f45ec7bSml29623 	npi_handle_t		handle;
10406f45ec7bSml29623 
10416f45ec7bSml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
10426f45ec7bSml29623 
10436f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn));
10446f45ec7bSml29623 
10456f45ec7bSml29623 	handle = nxgep->npi_handle;
10466f45ec7bSml29623 	portmode = nxgep->mac.portmode;
10476f45ec7bSml29623 	portt = nxgep->mac.porttype;
10486f45ec7bSml29623 	statsp = nxgep->statsp;
10496f45ec7bSml29623 
1050d81011f0Ssbehera 	if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
1051d81011f0Ssbehera 	    ((nxgep->mac.portmode == PORT_1G_SERDES) ||
105200161856Syc148097 	    (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 
10606f45ec7bSml29623 	if (portt == PORT_TYPE_XMAC) {
10616f45ec7bSml29623 
10626f45ec7bSml29623 		/* Setup XIF Configuration for XMAC */
10636f45ec7bSml29623 
10646f45ec7bSml29623 		if ((portmode == PORT_10G_FIBER) ||
10652e59129aSraghus 		    (portmode == PORT_10G_COPPER) ||
106600161856Syc148097 		    (portmode == PORT_10G_TN1010) ||
10671c7408c9Stc99174@train 		    (portmode == PORT_HSP_MODE) ||
10682e59129aSraghus 		    (portmode == PORT_10G_SERDES))
10696f45ec7bSml29623 			xif_cfg |= CFG_XMAC_XIF_LFS;
10706f45ec7bSml29623 
107100161856Syc148097 		/* Bypass PCS so that RGMII will be used */
10726f45ec7bSml29623 		if (portmode == PORT_1G_COPPER) {
10736f45ec7bSml29623 			xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS;
10746f45ec7bSml29623 		}
10756f45ec7bSml29623 
10766f45ec7bSml29623 		/* Set MAC Internal Loopback if necessary */
10776f45ec7bSml29623 		if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
10786f45ec7bSml29623 			xif_cfg |= CFG_XMAC_XIF_LOOPBACK;
10796f45ec7bSml29623 
10806f45ec7bSml29623 		if (statsp->mac_stats.link_speed == 100)
10816f45ec7bSml29623 			xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ;
10826f45ec7bSml29623 
10836f45ec7bSml29623 		xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT;
10846f45ec7bSml29623 
10852e59129aSraghus 		if ((portmode == PORT_10G_FIBER) ||
108689282175SSantwona Behera 		    (portmode == PORT_10G_COPPER) ||
108700161856Syc148097 		    (portmode == PORT_10G_TN1010) ||
108800161856Syc148097 		    (portmode == PORT_1G_TN1010) ||
10891c7408c9Stc99174@train 		    (portmode == PORT_HSP_MODE) ||
10902e59129aSraghus 		    (portmode == PORT_10G_SERDES)) {
109100161856Syc148097 			/* Assume LED same for 1G and 10G */
10926f45ec7bSml29623 			if (statsp->mac_stats.link_up) {
10936f45ec7bSml29623 				xif_cfg |= CFG_XMAC_XIF_LED_POLARITY;
10946f45ec7bSml29623 			} else {
10956f45ec7bSml29623 				xif_cfg |= CFG_XMAC_XIF_LED_FORCE;
10966f45ec7bSml29623 			}
10976f45ec7bSml29623 		}
10986f45ec7bSml29623 
10996f45ec7bSml29623 		rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg);
11006f45ec7bSml29623 		if (rs != NPI_SUCCESS)
11016f45ec7bSml29623 			goto fail;
11026f45ec7bSml29623 
11036f45ec7bSml29623 		nxgep->mac.xif_config = xif_cfg;
11046f45ec7bSml29623 
11056f45ec7bSml29623 		/* Set Port Mode */
11066f45ec7bSml29623 		if ((portmode == PORT_10G_FIBER) ||
11072e59129aSraghus 		    (portmode == PORT_10G_COPPER) ||
110800161856Syc148097 		    (portmode == PORT_10G_TN1010) ||
11091c7408c9Stc99174@train 		    (portmode == PORT_HSP_MODE) ||
11102e59129aSraghus 		    (portmode == PORT_10G_SERDES)) {
11116f45ec7bSml29623 			SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
11126f45ec7bSml29623 			    MAC_XGMII_MODE, rs);
11136f45ec7bSml29623 			if (rs != NPI_SUCCESS)
11146f45ec7bSml29623 				goto fail;
11156f45ec7bSml29623 			if (statsp->mac_stats.link_up) {
11166f45ec7bSml29623 				if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
11176f45ec7bSml29623 					goto fail;
11186f45ec7bSml29623 			} else {
11196f45ec7bSml29623 				if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
11206f45ec7bSml29623 					goto fail;
11216f45ec7bSml29623 			}
11226f45ec7bSml29623 		} else if ((portmode == PORT_1G_FIBER) ||
11232e59129aSraghus 		    (portmode == PORT_1G_COPPER) ||
1124d81011f0Ssbehera 		    (portmode == PORT_1G_SERDES) ||
112500161856Syc148097 		    (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));
11306f45ec7bSml29623 			if (statsp->mac_stats.link_speed == 1000) {
11316f45ec7bSml29623 				SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
11326f45ec7bSml29623 				    MAC_GMII_MODE, rs);
11336f45ec7bSml29623 			} else {
11346f45ec7bSml29623 				SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
11356f45ec7bSml29623 				    MAC_MII_MODE, rs);
11366f45ec7bSml29623 			}
11376f45ec7bSml29623 			if (rs != NPI_SUCCESS)
11386f45ec7bSml29623 				goto fail;
11396f45ec7bSml29623 		} else {
11406f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
11416f45ec7bSml29623 			    "nxge_xif_init: Unknown port mode (%d)"
11426f45ec7bSml29623 			    " for port<%d>", portmode, portn));
11436f45ec7bSml29623 			goto fail;
11446f45ec7bSml29623 		}
11456f45ec7bSml29623 
1146d81011f0Ssbehera 		/* Enable ATCA mode */
1147d81011f0Ssbehera 
11486f45ec7bSml29623 	} else if (portt == PORT_TYPE_BMAC) {
11496f45ec7bSml29623 
11506f45ec7bSml29623 		/* Setup XIF Configuration for BMAC */
11516f45ec7bSml29623 
1152d81011f0Ssbehera 		if ((portmode == PORT_1G_COPPER) ||
1153d81011f0Ssbehera 		    (portmode == PORT_1G_RGMII_FIBER)) {
11546f45ec7bSml29623 			if (statsp->mac_stats.link_speed == 100)
11556f45ec7bSml29623 				xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ;
11566f45ec7bSml29623 		}
11576f45ec7bSml29623 
11586f45ec7bSml29623 		if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
11596f45ec7bSml29623 			xif_cfg |= CFG_BMAC_XIF_LOOPBACK;
11606f45ec7bSml29623 
11616f45ec7bSml29623 		if (statsp->mac_stats.link_speed == 1000)
11626f45ec7bSml29623 			xif_cfg |= CFG_BMAC_XIF_GMII_MODE;
11636f45ec7bSml29623 
11646f45ec7bSml29623 		xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT;
11656f45ec7bSml29623 
11666f45ec7bSml29623 		rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg);
11676f45ec7bSml29623 		if (rs != NPI_SUCCESS)
11686f45ec7bSml29623 			goto fail;
11696f45ec7bSml29623 		nxgep->mac.xif_config = xif_cfg;
11706f45ec7bSml29623 	}
11716f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn));
11726f45ec7bSml29623 	return (NXGE_OK);
11736f45ec7bSml29623 fail:
11746f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
117552ccf843Smisaki 	    "nxge_xif_init: Failed to initialize XIF port<%d>", portn));
11766f45ec7bSml29623 	return (NXGE_ERROR | rs);
11776f45ec7bSml29623 }
11786f45ec7bSml29623 
11796f45ec7bSml29623 
118000161856Syc148097 /*
118100161856Syc148097  * Initialize the PCS sub-block in the MAC.  Note that PCS does not
118200161856Syc148097  * support loopback like XPCS.
118300161856Syc148097  */
11846f45ec7bSml29623 nxge_status_t
nxge_pcs_init(p_nxge_t nxgep)11856f45ec7bSml29623 nxge_pcs_init(p_nxge_t nxgep)
11866f45ec7bSml29623 {
11876f45ec7bSml29623 	pcs_cfg_t		pcs_cfg;
11886f45ec7bSml29623 	uint32_t		val;
11896f45ec7bSml29623 	uint8_t			portn;
11906f45ec7bSml29623 	nxge_port_mode_t	portmode;
11916f45ec7bSml29623 	npi_handle_t		handle;
11926f45ec7bSml29623 	p_nxge_stats_t		statsp;
119300161856Syc148097 	pcs_ctrl_t		pcs_ctrl;
11946f45ec7bSml29623 	npi_status_t		rs = NPI_SUCCESS;
119500161856Syc148097 	uint8_t i;
11966f45ec7bSml29623 
11976f45ec7bSml29623 	handle = nxgep->npi_handle;
11986f45ec7bSml29623 	portmode = nxgep->mac.portmode;
11996f45ec7bSml29623 	portn = nxgep->mac.portnum;
12006f45ec7bSml29623 	statsp = nxgep->statsp;
12016f45ec7bSml29623 
12026f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn));
12036f45ec7bSml29623 
120400161856Syc148097 	if (portmode == PORT_1G_FIBER ||
120500161856Syc148097 	    portmode == PORT_1G_TN1010 ||
120600161856Syc148097 	    portmode == PORT_1G_SERDES) {
120700161856Syc148097 		if (portmode == PORT_1G_TN1010) {
120800161856Syc148097 			/* Reset PCS multiple time in PORT_1G_TN1010 mode */
120900161856Syc148097 			for (i = 0; i < 6; i ++) {
121000161856Syc148097 				if ((rs = npi_mac_pcs_reset(handle, portn))
121100161856Syc148097 				    != NPI_SUCCESS) {
121200161856Syc148097 					goto fail;
121300161856Syc148097 				}
121400161856Syc148097 			}
121500161856Syc148097 		} else {
121600161856Syc148097 			if ((rs = npi_mac_pcs_reset(handle, portn))
121700161856Syc148097 			    != NPI_SUCCESS)
12182e59129aSraghus 				goto fail;
12192e59129aSraghus 		}
12202e59129aSraghus 
12216f45ec7bSml29623 		/* Initialize port's PCS */
12226f45ec7bSml29623 		pcs_cfg.value = 0;
12236f45ec7bSml29623 		pcs_cfg.bits.w0.enable = 1;
12246f45ec7bSml29623 		pcs_cfg.bits.w0.mask = 1;
12256f45ec7bSml29623 		PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value);
12266f45ec7bSml29623 		PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0);
12276f45ec7bSml29623 
12282e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
12292e59129aSraghus 		    "==> nxge_pcs_init: (1G) port<%d> write config 0x%llx",
12302e59129aSraghus 		    portn, pcs_cfg.value));
123100161856Syc148097 
123200161856Syc148097 		if (portmode == PORT_1G_TN1010) {
123300161856Syc148097 			/*
123400161856Syc148097 			 * Must disable PCS auto-negotiation when the the driver
123500161856Syc148097 			 * is driving the TN1010 based XAUI card  Otherwise the
123600161856Syc148097 			 * autonegotiation between the PCS and the TN1010 PCS
123700161856Syc148097 			 * will never complete and the Neptune/NIU will not work
123800161856Syc148097 			 */
123900161856Syc148097 			pcs_ctrl.value = 0;
124000161856Syc148097 			PCS_REG_WR(handle, portn, PCS_MII_CTRL_REG,
124100161856Syc148097 			    pcs_ctrl.value);
124200161856Syc148097 		}
124300161856Syc148097 	} else if (portmode == PORT_10G_FIBER ||
124400161856Syc148097 	    portmode == PORT_10G_COPPER ||
124500161856Syc148097 	    portmode == PORT_10G_TN1010 ||
12461c7408c9Stc99174@train 	    portmode == PORT_HSP_MODE ||
124700161856Syc148097 	    portmode == PORT_10G_SERDES) {
12486f45ec7bSml29623 		/* Use internal XPCS, bypass 1G PCS */
12496f45ec7bSml29623 		XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val);
12506f45ec7bSml29623 		val &= ~XMAC_XIF_XPCS_BYPASS;
12516f45ec7bSml29623 		XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val);
12526f45ec7bSml29623 
12536f45ec7bSml29623 		if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS)
12546f45ec7bSml29623 			goto fail;
12556f45ec7bSml29623 
12566f45ec7bSml29623 		/* Set XPCS Internal Loopback if necessary */
12576f45ec7bSml29623 		if ((rs = npi_xmac_xpcs_read(handle, portn,
125852ccf843Smisaki 		    XPCS_REG_CONTROL1, &val)) != NPI_SUCCESS)
12596f45ec7bSml29623 			goto fail;
126000161856Syc148097 
12616f45ec7bSml29623 		if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) ||
12626f45ec7bSml29623 		    (statsp->port_stats.lb_mode == nxge_lb_mac1000))
12636f45ec7bSml29623 			val |= XPCS_CTRL1_LOOPBK;
12646f45ec7bSml29623 		else
12656f45ec7bSml29623 			val &= ~XPCS_CTRL1_LOOPBK;
12666f45ec7bSml29623 		if ((rs = npi_xmac_xpcs_write(handle, portn,
126752ccf843Smisaki 		    XPCS_REG_CONTROL1, val)) != NPI_SUCCESS)
12686f45ec7bSml29623 			goto fail;
12696f45ec7bSml29623 
12706f45ec7bSml29623 		/* Clear descw errors */
12716f45ec7bSml29623 		if ((rs = npi_xmac_xpcs_write(handle, portn,
127252ccf843Smisaki 		    XPCS_REG_DESCWERR_COUNTER, 0)) != NPI_SUCCESS)
12736f45ec7bSml29623 			goto fail;
12746f45ec7bSml29623 		/* Clear symbol errors */
12756f45ec7bSml29623 		if ((rs = npi_xmac_xpcs_read(handle, portn,
127652ccf843Smisaki 		    XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val)) != NPI_SUCCESS)
12776f45ec7bSml29623 			goto fail;
12786f45ec7bSml29623 		if ((rs = npi_xmac_xpcs_read(handle, portn,
127952ccf843Smisaki 		    XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val)) != NPI_SUCCESS)
12806f45ec7bSml29623 			goto fail;
12816f45ec7bSml29623 
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));
12866f45ec7bSml29623 		if (portn < 4) {
12876f45ec7bSml29623 			PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG,
12886f45ec7bSml29623 			    PCS_DATAPATH_MODE_MII);
12896f45ec7bSml29623 		}
12906f45ec7bSml29623 		if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS)
12916f45ec7bSml29623 			goto fail;
12926f45ec7bSml29623 
12936f45ec7bSml29623 	} else {
12946f45ec7bSml29623 		goto fail;
12956f45ec7bSml29623 	}
12966f45ec7bSml29623 pass:
12976f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn));
12986f45ec7bSml29623 	return (NXGE_OK);
12996f45ec7bSml29623 fail:
13006f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
130152ccf843Smisaki 	    "nxge_pcs_init: Failed to initialize PCS port<%d>", portn));
13026f45ec7bSml29623 	return (NXGE_ERROR | rs);
13036f45ec7bSml29623 }
13046f45ec7bSml29623 
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) {
132800161856Syc148097 		/* 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 {
13511bd6825cSml29623 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
13521bd6825cSml29623 			    "==> nxge_mac_ctrl_init: port<%d>: pause",
13531bd6825cSml29623 			    portn));
1354cb9d3ae6Smisaki 			if (statsp->mac_stats.adv_cap_pause) {
13551bd6825cSml29623 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
13561bd6825cSml29623 				    "==> nxge_mac_ctrl_init: port<%d>: "
13571bd6825cSml29623 				    "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 				 */
13691bd6825cSml29623 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
13701bd6825cSml29623 				    "==> nxge_mac_ctrl_init: port<%d>: "
13711bd6825cSml29623 				    "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) {
137700161856Syc148097 		/* 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 &
1413cb9d3ae6Smisaki 				    ~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 
14256f45ec7bSml29623 /* Initialize the Internal Serdes */
14266f45ec7bSml29623 
14276f45ec7bSml29623 nxge_status_t
nxge_serdes_init(p_nxge_t nxgep)14286f45ec7bSml29623 nxge_serdes_init(p_nxge_t nxgep)
14296f45ec7bSml29623 {
14306f45ec7bSml29623 	p_nxge_stats_t		statsp;
14316f45ec7bSml29623 #ifdef	NXGE_DEBUG
14326f45ec7bSml29623 	uint8_t			portn;
14336f45ec7bSml29623 #endif
14346f45ec7bSml29623 	nxge_status_t		status = NXGE_OK;
14356f45ec7bSml29623 
14366f45ec7bSml29623 #ifdef	NXGE_DEBUG
14376f45ec7bSml29623 	portn = nxgep->mac.portnum;
14386f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
14396f45ec7bSml29623 	    "==> nxge_serdes_init port<%d>", portn));
14406f45ec7bSml29623 #endif
14416f45ec7bSml29623 
144259ac0c16Sdavemq 	if (nxgep->xcvr.serdes_init) {
14436f45ec7bSml29623 		statsp = nxgep->statsp;
144459ac0c16Sdavemq 		status = nxgep->xcvr.serdes_init(nxgep);
144559ac0c16Sdavemq 		if (status != NXGE_OK)
14466f45ec7bSml29623 			goto fail;
14476f45ec7bSml29623 		statsp->mac_stats.serdes_inits++;
144859ac0c16Sdavemq 	}
14496f45ec7bSml29623 
14506f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>",
14516f45ec7bSml29623 	    portn));
14526f45ec7bSml29623 
14536f45ec7bSml29623 	return (NXGE_OK);
14546f45ec7bSml29623 
14556f45ec7bSml29623 fail:
14566f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
14576f45ec7bSml29623 	    "nxge_serdes_init: Failed to initialize serdes for port<%d>",
14586f45ec7bSml29623 	    portn));
14596f45ec7bSml29623 
14606f45ec7bSml29623 	return (status);
14616f45ec7bSml29623 }
14626f45ec7bSml29623 
14636f45ec7bSml29623 /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */
14646f45ec7bSml29623 
146559ac0c16Sdavemq static nxge_status_t
nxge_n2_serdes_init(p_nxge_t nxgep)14666f45ec7bSml29623 nxge_n2_serdes_init(p_nxge_t nxgep)
14676f45ec7bSml29623 {
14686f45ec7bSml29623 	uint8_t portn;
14696f45ec7bSml29623 	int chan;
14706f45ec7bSml29623 	esr_ti_cfgpll_l_t pll_cfg_l;
14712e59129aSraghus 	esr_ti_cfgpll_l_t pll_sts_l;
14726f45ec7bSml29623 	esr_ti_cfgrx_l_t rx_cfg_l;
14736f45ec7bSml29623 	esr_ti_cfgrx_h_t rx_cfg_h;
14746f45ec7bSml29623 	esr_ti_cfgtx_l_t tx_cfg_l;
14756f45ec7bSml29623 	esr_ti_cfgtx_h_t tx_cfg_h;
14762e59129aSraghus #ifdef NXGE_DEBUG
14772e59129aSraghus 	esr_ti_testcfg_t cfg;
14782e59129aSraghus #endif
14796f45ec7bSml29623 	esr_ti_testcfg_t test_cfg;
14806f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
14816f45ec7bSml29623 
14826f45ec7bSml29623 	portn = nxgep->mac.portnum;
14836f45ec7bSml29623 
14846f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>",
14856f45ec7bSml29623 	    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 	}
14916f45ec7bSml29623 
14926f45ec7bSml29623 	tx_cfg_l.value = 0;
14936f45ec7bSml29623 	tx_cfg_h.value = 0;
14946f45ec7bSml29623 	rx_cfg_l.value = 0;
14956f45ec7bSml29623 	rx_cfg_h.value = 0;
14966f45ec7bSml29623 	pll_cfg_l.value = 0;
14972e59129aSraghus 	pll_sts_l.value = 0;
14986f45ec7bSml29623 	test_cfg.value = 0;
14996f45ec7bSml29623 
150000161856Syc148097 	/*
150100161856Syc148097 	 * If the nxge driver has been plumbed without a link, then it will
150200161856Syc148097 	 * detect a link up when a cable connecting to an anto-negotiation
150300161856Syc148097 	 * partner is plugged into the port. Because the TN1010 PHY supports
150400161856Syc148097 	 * both 1G and 10G speeds, the driver must re-configure the
150500161856Syc148097 	 * Neptune/NIU according to the negotiated speed.  nxge_n2_serdes_init
150600161856Syc148097 	 * is called at the post-link-up reconfiguration time. Here it calls
150700161856Syc148097 	 * nxge_set_tn1010_param to set portmode before re-initializing
150800161856Syc148097 	 * the serdes.
150900161856Syc148097 	 */
151000161856Syc148097 	if (nxgep->mac.portmode == PORT_1G_TN1010 ||
151100161856Syc148097 	    nxgep->mac.portmode == PORT_10G_TN1010) {
151200161856Syc148097 		if (nxge_set_tn1010_param(nxgep) != NXGE_OK) {
151300161856Syc148097 			goto fail;
151400161856Syc148097 		}
151500161856Syc148097 	}
151600161856Syc148097 
151700161856Syc148097 	if (nxgep->mac.portmode == PORT_10G_FIBER ||
151889282175SSantwona Behera 	    nxgep->mac.portmode == PORT_10G_COPPER ||
151900161856Syc148097 	    nxgep->mac.portmode == PORT_10G_TN1010 ||
15201c7408c9Stc99174@train 	    nxgep->mac.portmode == PORT_HSP_MODE ||
152100161856Syc148097 	    nxgep->mac.portmode == PORT_10G_SERDES) {
15226f45ec7bSml29623 		/* 0x0E01 */
15236f45ec7bSml29623 		tx_cfg_l.bits.entx = 1;
15246f45ec7bSml29623 		tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
15256f45ec7bSml29623 
15266f45ec7bSml29623 		/* 0x9101 */
15276f45ec7bSml29623 		rx_cfg_l.bits.enrx = 1;
15286f45ec7bSml29623 		rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
15296f45ec7bSml29623 		rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
15306f45ec7bSml29623 		rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
15316f45ec7bSml29623 
15326f45ec7bSml29623 		/* 0x0008 */
15336f45ec7bSml29623 		rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
15346f45ec7bSml29623 
15356f45ec7bSml29623 		/* Set loopback mode if necessary */
15366f45ec7bSml29623 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
15376f45ec7bSml29623 			tx_cfg_l.bits.entest = 1;
15386f45ec7bSml29623 			rx_cfg_l.bits.entest = 1;
15396f45ec7bSml29623 			test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
15406f45ec7bSml29623 			if ((status = nxge_mdio_write(nxgep, portn,
15416f45ec7bSml29623 			    ESR_N2_DEV_ADDR,
154252ccf843Smisaki 			    ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK)
15436f45ec7bSml29623 				goto fail;
15446f45ec7bSml29623 		}
15456f45ec7bSml29623 
154600161856Syc148097 		/* Initialize PLL for 10G */
154700161856Syc148097 		pll_cfg_l.bits.mpy = CFGPLL_MPY_10X;
154800161856Syc148097 		pll_cfg_l.bits.enpll = 1;
154900161856Syc148097 		pll_sts_l.bits.enpll = 1;
155000161856Syc148097 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
155100161856Syc148097 		    ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK)
155200161856Syc148097 			goto fail;
15536f45ec7bSml29623 
155400161856Syc148097 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
155500161856Syc148097 		    ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK)
155600161856Syc148097 			goto fail;
15576f45ec7bSml29623 
155800161856Syc148097 #ifdef  NXGE_DEBUG
155900161856Syc148097 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
156000161856Syc148097 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
156100161856Syc148097 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
156200161856Syc148097 		    "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
156300161856Syc148097 		    portn, pll_cfg_l.value, cfg.value));
156400161856Syc148097 
156500161856Syc148097 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
156600161856Syc148097 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
156700161856Syc148097 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
156800161856Syc148097 		    "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)",
156900161856Syc148097 		    portn, pll_sts_l.value, cfg.value));
157000161856Syc148097 #endif
157100161856Syc148097 	} else if (nxgep->mac.portmode == PORT_1G_FIBER ||
157200161856Syc148097 	    nxgep->mac.portmode == PORT_1G_TN1010 ||
157300161856Syc148097 	    nxgep->mac.portmode == PORT_1G_SERDES) {
15746f45ec7bSml29623 		/* 0x0E21 */
15756f45ec7bSml29623 		tx_cfg_l.bits.entx = 1;
15766f45ec7bSml29623 		tx_cfg_l.bits.rate = CFGTX_RATE_HALF;
15776f45ec7bSml29623 		tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
15786f45ec7bSml29623 
15796f45ec7bSml29623 		/* 0x9121 */
15806f45ec7bSml29623 		rx_cfg_l.bits.enrx = 1;
15816f45ec7bSml29623 		rx_cfg_l.bits.rate = CFGRX_RATE_HALF;
15826f45ec7bSml29623 		rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
15836f45ec7bSml29623 		rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
15846f45ec7bSml29623 		rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
15856f45ec7bSml29623 
15862e59129aSraghus 		if (portn == 0) {
15876f45ec7bSml29623 			/* 0x8 */
15886f45ec7bSml29623 			rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
15892e59129aSraghus 		}
15906f45ec7bSml29623 
159100161856Syc148097 		/* Initialize PLL for 1G */
15926f45ec7bSml29623 		pll_cfg_l.bits.mpy = CFGPLL_MPY_8X;
15936f45ec7bSml29623 		pll_cfg_l.bits.enpll = 1;
15942e59129aSraghus 		pll_sts_l.bits.enpll = 1;
15956f45ec7bSml29623 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
159652ccf843Smisaki 		    ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK)
15976f45ec7bSml29623 			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 		}
16316f45ec7bSml29623 	} else {
16326f45ec7bSml29623 		goto fail;
16336f45ec7bSml29623 	}
16346f45ec7bSml29623 
16356f45ec7bSml29623 	/*   MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */
16366f45ec7bSml29623 
16376f45ec7bSml29623 	NXGE_DELAY(20);
16386f45ec7bSml29623 
16396f45ec7bSml29623 	/* init TX channels */
16406f45ec7bSml29623 	for (chan = 0; chan < 4; chan++) {
16416f45ec7bSml29623 		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)
16436f45ec7bSml29623 			goto fail;
16446f45ec7bSml29623 
16456f45ec7bSml29623 		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)
16476f45ec7bSml29623 			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));
16556f45ec7bSml29623 	}
16566f45ec7bSml29623 
16576f45ec7bSml29623 	/* init RX channels */
16586f45ec7bSml29623 	for (chan = 0; chan < 4; chan++) {
16596f45ec7bSml29623 		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)
16616f45ec7bSml29623 			goto fail;
16626f45ec7bSml29623 
16636f45ec7bSml29623 		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)
16656f45ec7bSml29623 			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));
167000161856Syc148097 
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));
16746f45ec7bSml29623 	}
16756f45ec7bSml29623 
16766f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>",
16776f45ec7bSml29623 	    portn));
16786f45ec7bSml29623 
16796f45ec7bSml29623 	return (NXGE_OK);
16806f45ec7bSml29623 fail:
16812d17280bSsbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16826f45ec7bSml29623 	    "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>",
16836f45ec7bSml29623 	    portn));
16846f45ec7bSml29623 
16856f45ec7bSml29623 	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 {
17524df55fdeSJanie Lu 			tx_cfg_l.bits.entx = K_CFGTX_ENABLE_TX;
17534df55fdeSJanie Lu 			/* 0x1e21 */
17544df55fdeSJanie Lu 			tx_cfg_l.bits.swing = K_CFGTX_SWING_2000MV;
17554df55fdeSJanie Lu 			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 {
17644df55fdeSJanie Lu 			/* channel 0: enable syn. master */
17654df55fdeSJanie Lu 			/* 0x40 */
17664df55fdeSJanie Lu 			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 {
17754df55fdeSJanie Lu 			/* 0x4821 */
17764df55fdeSJanie Lu 			rx_cfg_l.bits.enrx = K_CFGRX_ENABLE_RX;
17774df55fdeSJanie Lu 			rx_cfg_l.bits.rate = K_CFGRX_RATE_HALF;
17784df55fdeSJanie Lu 			rx_cfg_l.bits.align = K_CFGRX_ALIGN_EN;
17794df55fdeSJanie Lu 			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 {
17884df55fdeSJanie Lu 			/* 0x0008 */
17894df55fdeSJanie Lu 			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 {
17994df55fdeSJanie Lu 			/* 0xa1: Initialize PLL for 10G */
18004df55fdeSJanie Lu 			pll_cfg_l.bits.mpy = K_CFGPLL_MPY_20X;
18014df55fdeSJanie Lu 			pll_cfg_l.bits.enpll = K_CFGPLL_ENABLE_PLL;
18029d587972SSantwona Behera 		}
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));
200589282175SSantwona Behera 			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));
203489282175SSantwona Behera 			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);
20496f45ec7bSml29623 }
20506f45ec7bSml29623 
205159ac0c16Sdavemq /* Initialize the Neptune Internal Serdes for 10G (Neptune only) */
20526f45ec7bSml29623 
205359ac0c16Sdavemq static nxge_status_t
nxge_neptune_10G_serdes_init(p_nxge_t nxgep)205459ac0c16Sdavemq nxge_neptune_10G_serdes_init(p_nxge_t nxgep)
20556f45ec7bSml29623 {
20566f45ec7bSml29623 	npi_handle_t		handle;
20576f45ec7bSml29623 	uint8_t			portn;
2058321febdeSsbehera 	int			chan, i;
20596f45ec7bSml29623 	sr_rx_tx_ctrl_l_t	rx_tx_ctrl_l;
20606f45ec7bSml29623 	sr_rx_tx_ctrl_h_t	rx_tx_ctrl_h;
20616f45ec7bSml29623 	sr_glue_ctrl0_l_t	glue_ctrl0_l;
20626f45ec7bSml29623 	sr_glue_ctrl0_h_t	glue_ctrl0_h;
20636f45ec7bSml29623 	uint64_t		val;
20646f45ec7bSml29623 	uint16_t		val16l;
20656f45ec7bSml29623 	uint16_t		val16h;
20666f45ec7bSml29623 	nxge_status_t		status = NXGE_OK;
20676f45ec7bSml29623 
20686f45ec7bSml29623 	portn = nxgep->mac.portnum;
20696f45ec7bSml29623 
20706f45ec7bSml29623 	if ((portn != 0) && (portn != 1))
20716f45ec7bSml29623 		return (NXGE_OK);
20726f45ec7bSml29623 
207359ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
207459ac0c16Sdavemq 	    "==> nxge_neptune_10G_serdes_init port<%d>", portn));
20756f45ec7bSml29623 	handle = nxgep->npi_handle;
20766f45ec7bSml29623 	switch (portn) {
20776f45ec7bSml29623 	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 
20886f45ec7bSml29623 		ESR_REG_WR(handle, ESR_0_CONTROL_REG,
20896f45ec7bSml29623 		    ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
20906f45ec7bSml29623 		    ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
20916f45ec7bSml29623 		    (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
20926f45ec7bSml29623 		    (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
20936f45ec7bSml29623 		    (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
20946f45ec7bSml29623 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
20956f45ec7bSml29623 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
20966f45ec7bSml29623 		    (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
20976f45ec7bSml29623 		    (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
20986f45ec7bSml29623 		    (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
20996f45ec7bSml29623 		    (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
21006f45ec7bSml29623 
21016f45ec7bSml29623 		/* Set Serdes0 Internal Loopback if necessary */
210259ac0c16Sdavemq 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
21036f45ec7bSml29623 			ESR_REG_WR(handle,
21046f45ec7bSml29623 			    ESR_0_TEST_CONFIG_REG,
21056f45ec7bSml29623 			    ESR_PAD_LOOPBACK_CH3 |
21066f45ec7bSml29623 			    ESR_PAD_LOOPBACK_CH2 |
21076f45ec7bSml29623 			    ESR_PAD_LOOPBACK_CH1 |
21086f45ec7bSml29623 			    ESR_PAD_LOOPBACK_CH0);
21096f45ec7bSml29623 		} else {
211059ac0c16Sdavemq 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0);
21116f45ec7bSml29623 		}
21126f45ec7bSml29623 		break;
21136f45ec7bSml29623 	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 
21246f45ec7bSml29623 		ESR_REG_WR(handle, ESR_1_CONTROL_REG,
21256f45ec7bSml29623 		    ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
21266f45ec7bSml29623 		    ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
21276f45ec7bSml29623 		    (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
21286f45ec7bSml29623 		    (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
21296f45ec7bSml29623 		    (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
21306f45ec7bSml29623 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
21316f45ec7bSml29623 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
21326f45ec7bSml29623 		    (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
21336f45ec7bSml29623 		    (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
21346f45ec7bSml29623 		    (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
21356f45ec7bSml29623 		    (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
21366f45ec7bSml29623 
21376f45ec7bSml29623 		/* 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);
21426f45ec7bSml29623 		} else {
214359ac0c16Sdavemq 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0);
21446f45ec7bSml29623 		}
21456f45ec7bSml29623 		break;
21466f45ec7bSml29623 	default:
21476f45ec7bSml29623 		/* Nothing to do here */
21486f45ec7bSml29623 		goto done;
21496f45ec7bSml29623 	}
21506f45ec7bSml29623 
21516f45ec7bSml29623 	/* init TX RX channels */
21526f45ec7bSml29623 	for (chan = 0; chan < 4; chan++) {
21536f45ec7bSml29623 		if ((status = nxge_mdio_read(nxgep, portn,
215459ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
21556f45ec7bSml29623 		    &rx_tx_ctrl_l.value)) != NXGE_OK)
21566f45ec7bSml29623 			goto fail;
21576f45ec7bSml29623 		if ((status = nxge_mdio_read(nxgep, portn,
215859ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
21596f45ec7bSml29623 		    &rx_tx_ctrl_h.value)) != NXGE_OK)
21606f45ec7bSml29623 			goto fail;
21616f45ec7bSml29623 		if ((status = nxge_mdio_read(nxgep, portn,
216259ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
21636f45ec7bSml29623 		    &glue_ctrl0_l.value)) != NXGE_OK)
21646f45ec7bSml29623 			goto fail;
21656f45ec7bSml29623 		if ((status = nxge_mdio_read(nxgep, portn,
216659ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
21676f45ec7bSml29623 		    &glue_ctrl0_h.value)) != NXGE_OK)
21686f45ec7bSml29623 			goto fail;
21696f45ec7bSml29623 		rx_tx_ctrl_l.bits.enstretch = 1;
21706f45ec7bSml29623 		rx_tx_ctrl_h.bits.vmuxlo = 2;
21716f45ec7bSml29623 		rx_tx_ctrl_h.bits.vpulselo = 2;
21726f45ec7bSml29623 		glue_ctrl0_l.bits.rxlosenable = 1;
21736f45ec7bSml29623 		glue_ctrl0_l.bits.samplerate = 0xF;
21746f45ec7bSml29623 		glue_ctrl0_l.bits.thresholdcount = 0xFF;
21756f45ec7bSml29623 		glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
21766f45ec7bSml29623 		if ((status = nxge_mdio_write(nxgep, portn,
217759ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
21786f45ec7bSml29623 		    rx_tx_ctrl_l.value)) != NXGE_OK)
21796f45ec7bSml29623 			goto fail;
21806f45ec7bSml29623 		if ((status = nxge_mdio_write(nxgep, portn,
218159ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
21826f45ec7bSml29623 		    rx_tx_ctrl_h.value)) != NXGE_OK)
21836f45ec7bSml29623 			goto fail;
21846f45ec7bSml29623 		if ((status = nxge_mdio_write(nxgep, portn,
218559ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
21866f45ec7bSml29623 		    glue_ctrl0_l.value)) != NXGE_OK)
21876f45ec7bSml29623 			goto fail;
21886f45ec7bSml29623 		if ((status = nxge_mdio_write(nxgep, portn,
218959ac0c16Sdavemq 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
21906f45ec7bSml29623 		    glue_ctrl0_h.value)) != NXGE_OK)
21916f45ec7bSml29623 			goto fail;
21926f45ec7bSml29623 		}
21936f45ec7bSml29623 
21946f45ec7bSml29623 	/* Apply Tx core reset */
21956f45ec7bSml29623 	if ((status = nxge_mdio_write(nxgep, portn,
219659ac0c16Sdavemq 	    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
21976f45ec7bSml29623 	    (uint16_t)0)) != NXGE_OK)
21986f45ec7bSml29623 		goto fail;
21996f45ec7bSml29623 
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)
22036f45ec7bSml29623 		goto fail;
22046f45ec7bSml29623 
22056f45ec7bSml29623 	NXGE_DELAY(200);
22066f45ec7bSml29623 
22076f45ec7bSml29623 	/* 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)
22116f45ec7bSml29623 		goto fail;
22126f45ec7bSml29623 
22136f45ec7bSml29623 	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)
22166f45ec7bSml29623 		goto fail;
22176f45ec7bSml29623 
22186f45ec7bSml29623 	NXGE_DELAY(200);
22196f45ec7bSml29623 	if ((status = nxge_mdio_read(nxgep, portn,
222059ac0c16Sdavemq 	    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
22216f45ec7bSml29623 	    &val16l)) != NXGE_OK)
22226f45ec7bSml29623 		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)
22256f45ec7bSml29623 		goto fail;
22266f45ec7bSml29623 	if ((val16l != 0) || (val16h != 0)) {
22276f45ec7bSml29623 		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));
22316f45ec7bSml29623 	}
22326f45ec7bSml29623 
22336f45ec7bSml29623 	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);
22376f45ec7bSml29623 			if ((val & ESR_SIG_P0_BITS_MASK) !=
22386f45ec7bSml29623 			    (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 |
22396f45ec7bSml29623 			    ESR_SIG_XSERDES_RDY_P0 |
22406f45ec7bSml29623 			    ESR_SIG_XDETECT_P0_CH3 |
22416f45ec7bSml29623 			    ESR_SIG_XDETECT_P0_CH2 |
22426f45ec7bSml29623 			    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 			 */
2257774da109Stc99174@train 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2258321febdeSsbehera 			    "nxge_neptune_10G_serdes_init: "
2259321febdeSsbehera 			    "Serdes/signal for port<%d> not ready", portn));
2260ab6abb7aSjoycey 				goto done;
22616f45ec7bSml29623 		}
22626f45ec7bSml29623 	} 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);
22666f45ec7bSml29623 			if ((val & ESR_SIG_P1_BITS_MASK) !=
22676f45ec7bSml29623 			    (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 |
22686f45ec7bSml29623 			    ESR_SIG_XSERDES_RDY_P1 |
22696f45ec7bSml29623 			    ESR_SIG_XDETECT_P1_CH3 |
22706f45ec7bSml29623 			    ESR_SIG_XDETECT_P1_CH2 |
22716f45ec7bSml29623 			    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 			 */
2286774da109Stc99174@train 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2287321febdeSsbehera 			    "nxge_neptune_10G_serdes_init: "
2288321febdeSsbehera 			    "Serdes/signal for port<%d> not ready", portn));
2289ab6abb7aSjoycey 				goto done;
22906f45ec7bSml29623 		}
22916f45ec7bSml29623 	}
22926f45ec7bSml29623 
229359ac0c16Sdavemq done:
229459ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
229559ac0c16Sdavemq 	    "<== nxge_neptune_10G_serdes_init port<%d>", portn));
229659ac0c16Sdavemq 
229759ac0c16Sdavemq 	return (NXGE_OK);
229859ac0c16Sdavemq 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));
230259ac0c16Sdavemq 
230359ac0c16Sdavemq 	return (status);
230459ac0c16Sdavemq }
230559ac0c16Sdavemq 
230659ac0c16Sdavemq /* Initialize Neptune Internal Serdes for 1G (Neptune only) */
230759ac0c16Sdavemq 
230859ac0c16Sdavemq static nxge_status_t
nxge_1G_serdes_init(p_nxge_t nxgep)230959ac0c16Sdavemq nxge_1G_serdes_init(p_nxge_t nxgep)
231059ac0c16Sdavemq {
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;
232259ac0c16Sdavemq 
232359ac0c16Sdavemq 	portn = nxgep->mac.portnum;
232459ac0c16Sdavemq 
232559ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
232659ac0c16Sdavemq 	    "==> nxge_1G_serdes_init port<%d>", portn));
232759ac0c16Sdavemq 
232859ac0c16Sdavemq 	handle = nxgep->npi_handle;
232959ac0c16Sdavemq 
23306f45ec7bSml29623 	switch (portn) {
23316f45ec7bSml29623 	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);
23576f45ec7bSml29623 		break;
2358d81011f0Ssbehera 
23596f45ec7bSml29623 	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);
23856f45ec7bSml29623 		break;
2386d81011f0Ssbehera 
23876f45ec7bSml29623 	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) {
24126f45ec7bSml29623 			goto fail;
24136f45ec7bSml29623 		}
24146f45ec7bSml29623 
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) {
2458d81011f0Ssbehera 		goto fail;
2459d81011f0Ssbehera 	}
2460d81011f0Ssbehera 
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));
2522ab6abb7aSjoycey 			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));
2536ab6abb7aSjoycey 			goto done;
253700161856Syc148097 
2538d81011f0Ssbehera 		}
2539d81011f0Ssbehera 	}
2540d81011f0Ssbehera done:
25416f45ec7bSml29623 
254259ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
254359ac0c16Sdavemq 	    "<== nxge_1G_serdes_init port<%d>", portn));
25446f45ec7bSml29623 	return (NXGE_OK);
25456f45ec7bSml29623 fail:
2546d81011f0Ssbehera 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
254759ac0c16Sdavemq 	    "nxge_1G_serdes_init: "
25486f45ec7bSml29623 	    "Failed to initialize Neptune serdes for port<%d>",
25496f45ec7bSml29623 	    portn));
25506f45ec7bSml29623 
2551d81011f0Ssbehera 	return (status);
25526f45ec7bSml29623 }
25536f45ec7bSml29623 
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 */
25776f45ec7bSml29623 
257859ac0c16Sdavemq static nxge_status_t
nxge_BCM8704_xcvr_init(p_nxge_t nxgep)25792d17280bSsbehera nxge_BCM8704_xcvr_init(p_nxge_t nxgep)
25806f45ec7bSml29623 {
25816f45ec7bSml29623 	uint16_t		val;
25826f45ec7bSml29623 #ifdef	NXGE_DEBUG
25836f45ec7bSml29623 	uint8_t			portn;
25846f45ec7bSml29623 	uint16_t		val1;
25856f45ec7bSml29623 #endif
25866f45ec7bSml29623 	uint8_t			phy_port_addr;
25876f45ec7bSml29623 	pmd_tx_control_t	tx_ctl;
25886f45ec7bSml29623 	control_t		ctl;
25896f45ec7bSml29623 	phyxs_control_t		phyxs_ctl;
25906f45ec7bSml29623 	pcs_control_t		pcs_ctl;
25916f45ec7bSml29623 	uint32_t		delay = 0;
25926f45ec7bSml29623 	optics_dcntr_t		op_ctr;
25936f45ec7bSml29623 	nxge_status_t		status = NXGE_OK;
25946f45ec7bSml29623 #ifdef	NXGE_DEBUG
25956f45ec7bSml29623 	portn = nxgep->mac.portnum;
25966f45ec7bSml29623 #endif
25979d587972SSantwona Behera 
25982d17280bSsbehera 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>",
259959ac0c16Sdavemq 	    portn));
26006f45ec7bSml29623 
26016f45ec7bSml29623 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
26026f45ec7bSml29623 
26036f45ec7bSml29623 	/* 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)
26066f45ec7bSml29623 		goto fail;
26076f45ec7bSml29623 
26086f45ec7bSml29623 	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)
26116f45ec7bSml29623 		goto fail;
26126f45ec7bSml29623 
26136f45ec7bSml29623 	do {
26146f45ec7bSml29623 		drv_usecwait(500);
261559ac0c16Sdavemq 		if ((status = nxge_mdio_read(nxgep, phy_port_addr,
261659ac0c16Sdavemq 		    BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG,
26176f45ec7bSml29623 		    &phyxs_ctl.value)) != NXGE_OK)
26186f45ec7bSml29623 			goto fail;
26196f45ec7bSml29623 		delay++;
26206f45ec7bSml29623 	} while ((phyxs_ctl.bits.reset) && (delay < 100));
26216f45ec7bSml29623 	if (delay == 100) {
262259ac0c16Sdavemq 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
262359ac0c16Sdavemq 		    "failed to reset Transceiver on port<%d>", portn));
26246f45ec7bSml29623 		status = NXGE_ERROR;
26256f45ec7bSml29623 		goto fail;
26266f45ec7bSml29623 	}
26276f45ec7bSml29623 
26286f45ec7bSml29623 	/* Set to 0x7FBF */
26296f45ec7bSml29623 	ctl.value = 0;
26306f45ec7bSml29623 	ctl.bits.res1 = 0x3F;
26316f45ec7bSml29623 	ctl.bits.optxon_lvl = 1;
26326f45ec7bSml29623 	ctl.bits.oprxflt_lvl = 1;
26336f45ec7bSml29623 	ctl.bits.optrxlos_lvl = 1;
26346f45ec7bSml29623 	ctl.bits.optxflt_lvl = 1;
26356f45ec7bSml29623 	ctl.bits.opprflt_lvl = 1;
26366f45ec7bSml29623 	ctl.bits.obtmpflt_lvl = 1;
26376f45ec7bSml29623 	ctl.bits.opbiasflt_lvl = 1;
26386f45ec7bSml29623 	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))
26416f45ec7bSml29623 	    != NXGE_OK)
26426f45ec7bSml29623 		goto fail;
26436f45ec7bSml29623 
26446f45ec7bSml29623 	/* Set to 0x164 */
26456f45ec7bSml29623 	tx_ctl.value = 0;
26466f45ec7bSml29623 	tx_ctl.bits.tsck_lpwren = 1;
26476f45ec7bSml29623 	tx_ctl.bits.tx_dac_txck = 0x2;
26486f45ec7bSml29623 	tx_ctl.bits.tx_dac_txd = 0x1;
26496f45ec7bSml29623 	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)
26536f45ec7bSml29623 		goto fail;
26546f45ec7bSml29623 	/*
26556f45ec7bSml29623 	 * According to Broadcom's instruction, SW needs to read
26566f45ec7bSml29623 	 * back these registers twice after written.
26576f45ec7bSml29623 	 */
265859ac0c16Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
265959ac0c16Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
26606f45ec7bSml29623 	    != NXGE_OK)
26616f45ec7bSml29623 		goto fail;
26626f45ec7bSml29623 
266359ac0c16Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
266459ac0c16Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
26656f45ec7bSml29623 	    != NXGE_OK)
26666f45ec7bSml29623 		goto fail;
26676f45ec7bSml29623 
266859ac0c16Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
266959ac0c16Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
26706f45ec7bSml29623 	    != NXGE_OK)
26716f45ec7bSml29623 		goto fail;
26726f45ec7bSml29623 
267359ac0c16Sdavemq 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
267459ac0c16Sdavemq 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
26756f45ec7bSml29623 	    != NXGE_OK)
26766f45ec7bSml29623 		goto fail;
26776f45ec7bSml29623 
26786f45ec7bSml29623 	/* 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,
26816f45ec7bSml29623 	    &op_ctr.value)) != NXGE_OK)
26826f45ec7bSml29623 		goto fail;
2683cb9d3ae6Smisaki 	if (NXGE_IS_XAUI_PLATFORM(nxgep)) {
2684cb9d3ae6Smisaki 		op_ctr.bits.gpio_sel = 0x1;
2685cb9d3ae6Smisaki 	} else {
26866f45ec7bSml29623 		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,
26906f45ec7bSml29623 	    op_ctr.value)) != NXGE_OK)
26916f45ec7bSml29623 		goto fail;
26926f45ec7bSml29623 
26936f45ec7bSml29623 	NXGE_DELAY(1000000);
26946f45ec7bSml29623 
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 
27056f45ec7bSml29623 	/* 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)
27096f45ec7bSml29623 		goto fail;
27106f45ec7bSml29623 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
27116f45ec7bSml29623 		pcs_ctl.bits.loopback = 1;
27126f45ec7bSml29623 	else
27136f45ec7bSml29623 		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)
27176f45ec7bSml29623 		goto fail;
27186f45ec7bSml29623 
271959ac0c16Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x1, 0xA, &val);
27206f45ec7bSml29623 	if (status != NXGE_OK)
27216f45ec7bSml29623 		goto fail;
27226f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
272359ac0c16Sdavemq 	    "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", portn, val));
27246f45ec7bSml29623 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val);
27256f45ec7bSml29623 	if (status != NXGE_OK)
27266f45ec7bSml29623 		goto fail;
27276f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
272859ac0c16Sdavemq 	    "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", portn, val));
27296f45ec7bSml29623 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val);
27306f45ec7bSml29623 	if (status != NXGE_OK)
27316f45ec7bSml29623 		goto fail;
27326f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
273359ac0c16Sdavemq 	    "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", portn, val));
27346f45ec7bSml29623 
27356f45ec7bSml29623 #ifdef	NXGE_DEBUG
27366f45ec7bSml29623 	/* Diagnose link issue if link is not up */
273759ac0c16Sdavemq 	status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_USER_DEV3_ADDR,
27386f45ec7bSml29623 	    BCM8704_USER_ANALOG_STATUS0_REG,
27396f45ec7bSml29623 	    &val);
27406f45ec7bSml29623 	if (status != NXGE_OK)
27416f45ec7bSml29623 		goto fail;
27426f45ec7bSml29623 
27436f45ec7bSml29623 	status = nxge_mdio_read(nxgep, phy_port_addr,
274452ccf843Smisaki 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_ANALOG_STATUS0_REG, &val);
27456f45ec7bSml29623 	if (status != NXGE_OK)
27466f45ec7bSml29623 		goto fail;
27476f45ec7bSml29623 
27486f45ec7bSml29623 	status = nxge_mdio_read(nxgep, phy_port_addr,
274952ccf843Smisaki 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1);
27506f45ec7bSml29623 	if (status != NXGE_OK)
27516f45ec7bSml29623 		goto fail;
27526f45ec7bSml29623 
27536f45ec7bSml29623 	status = nxge_mdio_read(nxgep, phy_port_addr,
275452ccf843Smisaki 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1);
27556f45ec7bSml29623 	if (status != NXGE_OK)
27566f45ec7bSml29623 		goto fail;
27576f45ec7bSml29623 
27586f45ec7bSml29623 	if (val != 0x3FC) {
27596f45ec7bSml29623 		if ((val == 0x43BC) && (val1 != 0)) {
27606f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
27616f45ec7bSml29623 			    "Cable not connected to peer or bad"
27626f45ec7bSml29623 			    " cable on port<%d>\n", portn));
27636f45ec7bSml29623 		} else if (val == 0x639C) {
27646f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
276559ac0c16Sdavemq 			    "Optical module (XFP) is bad or absent"
27666f45ec7bSml29623 			    " on port<%d>\n", portn));
27676f45ec7bSml29623 		}
27686f45ec7bSml29623 	}
27696f45ec7bSml29623 #endif
27706f45ec7bSml29623 
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,
287989282175SSantwona Behera     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;
37761bd6825cSml29623 	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 
37861c7408c9Stc99174@train 	/* Disable Link LEDs, with or without PHY */
37871c7408c9Stc99174@train 	if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
37881c7408c9Stc99174@train 		goto done;
37891c7408c9Stc99174@train 
37901c7408c9Stc99174@train 	/* Skip MDIO, if PHY absent */
37911c7408c9Stc99174@train 	if (nxgep->mac.portmode == PORT_10G_SERDES || nxgep->phy_absent) {
37922d17280bSsbehera 		goto done;
37932d17280bSsbehera 	}
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:
380000161856Syc148097 		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:
380500161856Syc148097 		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:
381000161856Syc148097 		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:
38306f45ec7bSml29623 	statsp->mac_stats.cap_10gfdx = 1;
38316f45ec7bSml29623 	statsp->mac_stats.lp_cap_10gfdx = 1;
38321bd6825cSml29623 	statsp->mac_stats.adv_cap_asmpause =
38331bd6825cSml29623 	    param_arr[param_anar_asmpause].value;
38341bd6825cSml29623 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
383559ac0c16Sdavemq 
383659ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
383759ac0c16Sdavemq 	    portn));
383859ac0c16Sdavemq 	return (NXGE_OK);
383959ac0c16Sdavemq 
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 }
384659ac0c16Sdavemq 
384759ac0c16Sdavemq /* Initialize the 1G copper (BCM 5464) Transceiver */
384859ac0c16Sdavemq 
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;
385559ac0c16Sdavemq 
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 
38626f45ec7bSml29623 	/* Set Clause 22 */
38636f45ec7bSml29623 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE);
38646f45ec7bSml29623 
38656f45ec7bSml29623 	/* 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 	}
38746f45ec7bSml29623 
387559ac0c16Sdavemq 	status = nxge_mii_xcvr_init(nxgep);
38762e59129aSraghus done:
387759ac0c16Sdavemq 	return (status);
38786f45ec7bSml29623 }
38796f45ec7bSml29623 
388000161856Syc148097 /*
388100161856Syc148097  * Although the Teranetics copper transceiver (TN1010) does not need
388200161856Syc148097  * to be initialized by the driver for passing packets, this funtion
388300161856Syc148097  * initializes the members of nxgep->statsp->mac_stats struct for
388400161856Syc148097  * kstat based on the value of nxgep->statsp->ports_stats.lb_mode.
388500161856Syc148097  * It also configures the TN1010 for PHY loopback to support SunVTS.
388600161856Syc148097  *
388700161856Syc148097  * TN1010 only has the option to disable advertisement for the 10G
388800161856Syc148097  * mode. So we can set it to either Dual Mode or 1G Only mode but
388900161856Syc148097  * can't set it to 10G Only mode.
389000161856Syc148097  *
389100161856Syc148097  * ndd -set command can set the following 6 speed/duplex related parameters.
389200161856Syc148097  *
389300161856Syc148097  * ----------------------------------------------------------------
389400161856Syc148097  * ndd -set /dev/nxgeX param n		kstat nxge:X | grep param
389500161856Syc148097  * ----------------------------------------------------------------
389600161856Syc148097  * adv_autoneg_cap		kstat nxge:1 | grep adv_cap_autoneg
389700161856Syc148097  * adv_10gfdx_cap
389800161856Syc148097  * adv_1000fdx_cap		kstat nxge:1 | grep adv_cap_1000fdx
389900161856Syc148097  * adv_100fdx_cap		kstat nxge:1 | grep adv_cap_100fdx
390000161856Syc148097  * adv_10fdx_cap		kstat nxge:1 | grep adv_cap_10fdx
390100161856Syc148097  * adv_pause_cap		kstat nxge:1 | grep adv_cap_pause
390200161856Syc148097  * ----------------------------------------------------------------
390300161856Syc148097  */
390400161856Syc148097 static nxge_status_t
nxge_tn1010_xcvr_init(p_nxge_t nxgep)390500161856Syc148097 nxge_tn1010_xcvr_init(p_nxge_t nxgep)
390600161856Syc148097 {
390700161856Syc148097 	p_nxge_param_t		param_arr;
390800161856Syc148097 	p_nxge_stats_t		statsp;
390900161856Syc148097 	tn1010_pcs_ctrl_t	tn1010_pcs_ctrl;
391000161856Syc148097 	uint16_t		speed;
391100161856Syc148097 	uint8_t			phy_port_addr;
391200161856Syc148097 	uint8_t			portn = NXGE_GET_PORT_NUM(nxgep->function_num);
391300161856Syc148097 	int			status = NXGE_OK;
391400161856Syc148097 
391500161856Syc148097 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_1G_tn1010_xcvr_init"));
391600161856Syc148097 
391700161856Syc148097 	param_arr	= nxgep->param_arr;
391800161856Syc148097 	statsp		= nxgep->statsp;
391900161856Syc148097 
392000161856Syc148097 	/*
392100161856Syc148097 	 * Initialize the xcvr statistics which are NOT controlled by ndd
392200161856Syc148097 	 */
392300161856Syc148097 	statsp->mac_stats.cap_autoneg  = 1; /* TN1010 autoneg is always on */
392400161856Syc148097 	statsp->mac_stats.cap_100T4    = 0;
392500161856Syc148097 
392600161856Syc148097 	/*
392700161856Syc148097 	 * Read the TN1010 link speed and initialize capabilities kstat. Note
392800161856Syc148097 	 * that function nxge_check_tn1010_link repeatedly invoked by the
392900161856Syc148097 	 * timer will update link_speed real time.
393000161856Syc148097 	 */
393100161856Syc148097 	if (nxge_get_tn1010_speed(nxgep,  &speed) != NXGE_OK) {
393200161856Syc148097 		goto fail;
393300161856Syc148097 	}
393400161856Syc148097 	if (speed == TN1010_SPEED_1G) {
393500161856Syc148097 		statsp->mac_stats.cap_10gfdx = 0;
393600161856Syc148097 	} else {
393700161856Syc148097 		statsp->mac_stats.cap_10gfdx = 1;
393800161856Syc148097 	}
393900161856Syc148097 
394000161856Syc148097 	/* Whether we are in 1G or 10G mode, we always have the 1G capability */
394100161856Syc148097 	statsp->mac_stats.cap_1000fdx  = 1;
394200161856Syc148097 
394300161856Syc148097 	/* TN1010 is not able to operate in the following states */
394400161856Syc148097 	statsp->mac_stats.cap_1000hdx  = 0;
394500161856Syc148097 	statsp->mac_stats.cap_100fdx   = 0;
394600161856Syc148097 	statsp->mac_stats.cap_100hdx   = 0;
394700161856Syc148097 	statsp->mac_stats.cap_10fdx    = 0;
394800161856Syc148097 	statsp->mac_stats.cap_10hdx    = 0;
394900161856Syc148097 
395000161856Syc148097 	/* param_anar_pause can be modified by ndd -set */
395100161856Syc148097 	statsp->mac_stats.cap_pause    = param_arr[param_anar_pause].value;
395200161856Syc148097 
395300161856Syc148097 	/*
395400161856Syc148097 	 * The following 4 lines actually overwrites what ever the ndd command
395500161856Syc148097 	 * has set. For example, by command
395600161856Syc148097 	 *	ndd -set /dev/nxge1 adv_autoneg_cap n (n = 0 or 1)
395700161856Syc148097 	 * we could set param_arr[param_autoneg].value to n.  However, because
395800161856Syc148097 	 * here we assign constants to these parameters, whatever we set with
395900161856Syc148097 	 * the "ndd -set" command will be replaced. So command
396000161856Syc148097 	 *	kstat nxge:X | grep param
396100161856Syc148097 	 * will always show those constant values.  In other words, the
396200161856Syc148097 	 * "ndd -set" command can NOT change the values of these 4 parameters
396300161856Syc148097 	 * even though the command appears to be successful.
396400161856Syc148097 	 *
396500161856Syc148097 	 * Note: TN1010 auto negotiation is always enabled.
396600161856Syc148097 	 */
396700161856Syc148097 	statsp->mac_stats.adv_cap_autoneg
396800161856Syc148097 	    = param_arr[param_autoneg].value = 1;
396900161856Syc148097 	statsp->mac_stats.adv_cap_1000fdx
397000161856Syc148097 	    = param_arr[param_anar_1000fdx].value = 1;
397100161856Syc148097 	statsp->mac_stats.adv_cap_100fdx
397200161856Syc148097 	    = param_arr[param_anar_100fdx].value = 0;
397300161856Syc148097 	statsp->mac_stats.adv_cap_10fdx
397400161856Syc148097 	    = param_arr[param_anar_10fdx].value = 0;
397500161856Syc148097 
397600161856Syc148097 	/*
397700161856Syc148097 	 * The following 4 ndd params have type NXGE_PARAM_MAC_DONT_SHOW as
397800161856Syc148097 	 * defined in nxge_param_arr[], therefore they are not seen by the
397900161856Syc148097 	 * "ndd -get" command and can not be changed by ndd.  We just set
398000161856Syc148097 	 * them (both ndd param and kstat values) to constant 0 because TN1010
398100161856Syc148097 	 * does not support those speeds.
398200161856Syc148097 	 */
398300161856Syc148097 	statsp->mac_stats.adv_cap_100T4
398400161856Syc148097 	    = param_arr[param_anar_100T4].value = 0;
398500161856Syc148097 	statsp->mac_stats.adv_cap_1000hdx
398600161856Syc148097 	    = param_arr[param_anar_1000hdx].value = 0;
398700161856Syc148097 	statsp->mac_stats.adv_cap_100hdx
398800161856Syc148097 	    = param_arr[param_anar_100hdx].value = 0;
398900161856Syc148097 	statsp->mac_stats.adv_cap_10hdx
399000161856Syc148097 	    = param_arr[param_anar_10hdx].value = 0;
399100161856Syc148097 
399200161856Syc148097 	/*
399300161856Syc148097 	 * adv_cap_pause has type NXGE_PARAM_MAC_RW, so it can be modified
399400161856Syc148097 	 * by ndd
399500161856Syc148097 	 */
399600161856Syc148097 	statsp->mac_stats.adv_cap_pause    = param_arr[param_anar_pause].value;
399700161856Syc148097 
399800161856Syc148097 	/*
399900161856Syc148097 	 * nxge_param_arr[] defines the adv_cap_asmpause with type
400000161856Syc148097 	 * NXGE_PARAM_DONT_SHOW, therefore they are NOT seen by the
400100161856Syc148097 	 * "ndd -get" command and can not be changed by ndd. Here we do not
400200161856Syc148097 	 * assign a constant to it so the default value defined in
400300161856Syc148097 	 * nxge_param_arr[] will be used to set the parameter and
400400161856Syc148097 	 * will be shown by the kstat.
400500161856Syc148097 	 */
400600161856Syc148097 	statsp->mac_stats.adv_cap_asmpause
400700161856Syc148097 	    = param_arr[param_anar_asmpause].value;
400800161856Syc148097 
400900161856Syc148097 	/*
401000161856Syc148097 	 * Initialize the link statistics.
401100161856Syc148097 	 */
401200161856Syc148097 	statsp->mac_stats.link_T4 = 0;
401300161856Syc148097 	statsp->mac_stats.link_asmpause = 0;
401400161856Syc148097 	statsp->mac_stats.link_pause = 0;
401500161856Syc148097 	if (speed == TN1010_SPEED_1G) {
401600161856Syc148097 		statsp->mac_stats.link_speed = 1000;
401700161856Syc148097 		statsp->mac_stats.link_duplex = 2;	/* Full duplex */
401800161856Syc148097 		statsp->mac_stats.link_up = 1;
401900161856Syc148097 	} else {
402000161856Syc148097 		statsp->mac_stats.link_speed = 10000;
402100161856Syc148097 		statsp->mac_stats.link_duplex = 2;
402200161856Syc148097 		statsp->mac_stats.link_up = 1;
402300161856Syc148097 	}
402400161856Syc148097 
402500161856Syc148097 	/*
402600161856Syc148097 	 * Because TN1010 does not have a link partner register, to
402700161856Syc148097 	 * figure out the link partner's capabilities is tricky. Here we
402800161856Syc148097 	 * just set the kstat based on our knowledge about the partner
402900161856Syc148097 	 * (The partner must support auto-neg because auto-negotiation
403000161856Syc148097 	 * has completed, it must support 1G or 10G because that is the
403100161856Syc148097 	 * negotiated speed we are using.)
403200161856Syc148097 	 *
403300161856Syc148097 	 * Note: Current kstat does not show lp_cap_10gfdx and
403400161856Syc148097 	 *	lp_cap_10ghdx.
403500161856Syc148097 	 */
403600161856Syc148097 	if (speed == TN1010_SPEED_1G) {
403700161856Syc148097 		statsp->mac_stats.lp_cap_1000fdx  = 1;
403800161856Syc148097 		statsp->mac_stats.lp_cap_10gfdx   = 0;
403900161856Syc148097 	} else {
404000161856Syc148097 		statsp->mac_stats.lp_cap_1000fdx  = 0;
404100161856Syc148097 		statsp->mac_stats.lp_cap_10gfdx   = 1;
404200161856Syc148097 	}
404300161856Syc148097 	statsp->mac_stats.lp_cap_10ghdx   = 0;
404400161856Syc148097 	statsp->mac_stats.lp_cap_1000hdx  = 0;
404500161856Syc148097 	statsp->mac_stats.lp_cap_100fdx   = 0;
404600161856Syc148097 	statsp->mac_stats.lp_cap_100hdx   = 0;
404700161856Syc148097 	statsp->mac_stats.lp_cap_10fdx    = 0;
404800161856Syc148097 	statsp->mac_stats.lp_cap_10hdx    = 0;
404900161856Syc148097 	statsp->mac_stats.lp_cap_10gfdx   = 0;
405000161856Syc148097 	statsp->mac_stats.lp_cap_10ghdx   = 0;
405100161856Syc148097 	statsp->mac_stats.lp_cap_100T4    = 0;
405200161856Syc148097 	statsp->mac_stats.lp_cap_autoneg  = 1;
405300161856Syc148097 	statsp->mac_stats.lp_cap_asmpause = 0;
405400161856Syc148097 	statsp->mac_stats.lp_cap_pause    = 0;
405500161856Syc148097 
405600161856Syc148097 	/* Handle PHY loopback for SunVTS loopback test */
405700161856Syc148097 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
405800161856Syc148097 	phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
405900161856Syc148097 
406000161856Syc148097 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
406100161856Syc148097 	    TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG,
406200161856Syc148097 	    &tn1010_pcs_ctrl.value)) != NXGE_OK) {
406300161856Syc148097 		goto fail;
406400161856Syc148097 	}
406500161856Syc148097 	if ((statsp->port_stats.lb_mode == nxge_lb_phy1000) ||
406600161856Syc148097 	    (statsp->port_stats.lb_mode == nxge_lb_phy10g)) {
406700161856Syc148097 		tn1010_pcs_ctrl.bits.loopback = 1;
406800161856Syc148097 	} else {
406900161856Syc148097 		tn1010_pcs_ctrl.bits.loopback = 0;
407000161856Syc148097 	}
407100161856Syc148097 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
407200161856Syc148097 	    TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG,
407300161856Syc148097 	    tn1010_pcs_ctrl.value)) != NXGE_OK) {
407400161856Syc148097 		goto fail;
407500161856Syc148097 	}
407600161856Syc148097 
407700161856Syc148097 	statsp->mac_stats.xcvr_inits++;
407800161856Syc148097 
407900161856Syc148097 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
408000161856Syc148097 	    "<== nxge_1G_tn1010_xcvr_init status 0x%x", status));
408100161856Syc148097 	return (status);
408200161856Syc148097 fail:
408300161856Syc148097 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
408400161856Syc148097 	    "<== nxge_1G_tn1010_xcvr_init status 0x%x", status));
408500161856Syc148097 	return (status);
408600161856Syc148097 }
408700161856Syc148097 
408859ac0c16Sdavemq /* Initialize transceiver */
40896f45ec7bSml29623 
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;
409659ac0c16Sdavemq #endif
409759ac0c16Sdavemq 
409859ac0c16Sdavemq 	nxge_status_t		status = NXGE_OK;
409959ac0c16Sdavemq #ifdef	NXGE_DEBUG
410059ac0c16Sdavemq 	portn = nxgep->mac.portnum;
410159ac0c16Sdavemq #endif
41026f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn));
410359ac0c16Sdavemq 	statsp = nxgep->statsp;
410459ac0c16Sdavemq 
410559ac0c16Sdavemq 	/*
410600161856Syc148097 	 * Initialize the xcvr statistics. nxgep->xcvr.xcvr_init will
410700161856Syc148097 	 * 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;
412859ac0c16Sdavemq 
412959ac0c16Sdavemq 	if (nxgep->xcvr.xcvr_init) {
413059ac0c16Sdavemq 		status = nxgep->xcvr.xcvr_init(nxgep);
413159ac0c16Sdavemq 		if (status != NXGE_OK)
413259ac0c16Sdavemq 			goto fail;
413359ac0c16Sdavemq 		statsp->mac_stats.xcvr_inits++;
413459ac0c16Sdavemq 	}
413559ac0c16Sdavemq 
413659ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>",
413759ac0c16Sdavemq 	    portn));
41386f45ec7bSml29623 	return (NXGE_OK);
41396f45ec7bSml29623 
41406f45ec7bSml29623 fail:
41416f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
41426f45ec7bSml29623 	    "nxge_xcvr_init: failed to initialize transceiver for port<%d>",
41436f45ec7bSml29623 	    portn));
41446f45ec7bSml29623 	return (status);
41456f45ec7bSml29623 }
41466f45ec7bSml29623 
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 }
41656f45ec7bSml29623 
41666f45ec7bSml29623 /* Initialize the TxMAC sub-block */
41676f45ec7bSml29623 
41686f45ec7bSml29623 nxge_status_t
nxge_tx_mac_init(p_nxge_t nxgep)41696f45ec7bSml29623 nxge_tx_mac_init(p_nxge_t nxgep)
41706f45ec7bSml29623 {
41716f45ec7bSml29623 	npi_attr_t		ap;
41726f45ec7bSml29623 	uint8_t			portn;
41736f45ec7bSml29623 	nxge_port_mode_t	portmode;
41746f45ec7bSml29623 	nxge_port_t		portt;
41756f45ec7bSml29623 	npi_handle_t		handle;
41766f45ec7bSml29623 	npi_status_t		rs = NPI_SUCCESS;
41776f45ec7bSml29623 
41786f45ec7bSml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
41796f45ec7bSml29623 	portt    = nxgep->mac.porttype;
41806f45ec7bSml29623 	handle   = nxgep->npi_handle;
41816f45ec7bSml29623 	portmode = nxgep->mac.portmode;
41826f45ec7bSml29623 
41836f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>",
41846f45ec7bSml29623 	    portn));
41856f45ec7bSml29623 	/* Set Max and Min Frame Size */
41864202ea4bSsbehera 	/*
41871bd6825cSml29623 	 * Use maxframesize to configure the hardware maxframe size
418800161856Syc148097 	 * and minframesize to configure the hardware minframe size.
41894202ea4bSsbehera 	 */
41901bd6825cSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
41911bd6825cSml29623 	    "==> nxge_tx_mac_init: port<%d> "
41921bd6825cSml29623 	    "min framesize %d max framesize %d ",
41931bd6825cSml29623 	    nxgep->mac.minframesize,
41941bd6825cSml29623 	    nxgep->mac.maxframesize,
41951bd6825cSml29623 	    portn));
41966f45ec7bSml29623 
41971bd6825cSml29623 	SET_MAC_ATTR2(handle, ap, portn,
41981bd6825cSml29623 	    MAC_PORT_FRAME_SIZE,
41991bd6825cSml29623 	    nxgep->mac.minframesize,
42001bd6825cSml29623 	    nxgep->mac.maxframesize,
42011bd6825cSml29623 	    rs);
42026f45ec7bSml29623 	if (rs != NPI_SUCCESS)
42036f45ec7bSml29623 		goto fail;
42046f45ec7bSml29623 
42056f45ec7bSml29623 	if (portt == PORT_TYPE_XMAC) {
42066f45ec7bSml29623 		if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn,
42076f45ec7bSml29623 		    0)) != NPI_SUCCESS)
42086f45ec7bSml29623 			goto fail;
42096f45ec7bSml29623 		nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS;
42106f45ec7bSml29623 		if ((portmode == PORT_10G_FIBER) ||
42112e59129aSraghus 		    (portmode == PORT_10G_COPPER) ||
421200161856Syc148097 		    (portmode == PORT_10G_TN1010) ||
42131c7408c9Stc99174@train 		    (portmode == PORT_HSP_MODE) ||
42142e59129aSraghus 		    (portmode == PORT_10G_SERDES)) {
42156f45ec7bSml29623 			SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG,
42166f45ec7bSml29623 			    XGMII_IPG_12_15, rs);
42176f45ec7bSml29623 			if (rs != NPI_SUCCESS)
42186f45ec7bSml29623 				goto fail;
42196f45ec7bSml29623 			nxgep->mac.ipg[0] = XGMII_IPG_12_15;
42206f45ec7bSml29623 		} else {
42216f45ec7bSml29623 			SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG,
42226f45ec7bSml29623 			    MII_GMII_IPG_12, rs);
42236f45ec7bSml29623 			if (rs != NPI_SUCCESS)
42246f45ec7bSml29623 				goto fail;
42256f45ec7bSml29623 			nxgep->mac.ipg[0] = MII_GMII_IPG_12;
42266f45ec7bSml29623 		}
42276f45ec7bSml29623 		if ((rs = npi_xmac_tx_config(handle, INIT, portn,
42286f45ec7bSml29623 		    CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS)
42296f45ec7bSml29623 			goto fail;
42306f45ec7bSml29623 		nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX;
42316f45ec7bSml29623 		nxgep->mac.maxburstsize = 0;	/* not programmable */
42326f45ec7bSml29623 		nxgep->mac.ctrltype = 0;	/* not programmable */
42336f45ec7bSml29623 		nxgep->mac.pa_size = 0;		/* not programmable */
42346f45ec7bSml29623 
42356f45ec7bSml29623 		if ((rs = npi_xmac_zap_tx_counters(handle, portn))
42366f45ec7bSml29623 		    != NPI_SUCCESS)
42376f45ec7bSml29623 			goto fail;
42386f45ec7bSml29623 
42396f45ec7bSml29623 	} else {
42406f45ec7bSml29623 		if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn,
42416f45ec7bSml29623 		    0)) != NPI_SUCCESS)
42426f45ec7bSml29623 			goto fail;
42436f45ec7bSml29623 		nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS;
42446f45ec7bSml29623 
42456f45ec7bSml29623 		SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808,
42466f45ec7bSml29623 		    rs);
42476f45ec7bSml29623 		if (rs != NPI_SUCCESS)
42486f45ec7bSml29623 			goto fail;
42496f45ec7bSml29623 		nxgep->mac.ctrltype = 0x8808;
42506f45ec7bSml29623 
42516f45ec7bSml29623 		SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs);
42526f45ec7bSml29623 		if (rs != NPI_SUCCESS)
42536f45ec7bSml29623 			goto fail;
42546f45ec7bSml29623 		nxgep->mac.pa_size = 0x7;
42556f45ec7bSml29623 
42566f45ec7bSml29623 		if ((rs = npi_bmac_tx_config(handle, INIT, portn,
42576f45ec7bSml29623 		    CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS)
42586f45ec7bSml29623 			goto fail;
42596f45ec7bSml29623 		nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX;
42606f45ec7bSml29623 	}
42616f45ec7bSml29623 
42626f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>",
42636f45ec7bSml29623 	    portn));
42646f45ec7bSml29623 
42656f45ec7bSml29623 	return (NXGE_OK);
42666f45ec7bSml29623 fail:
42676f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
426852ccf843Smisaki 	    "nxge_tx_mac_init: failed to initialize port<%d> TXMAC", portn));
42696f45ec7bSml29623 
42706f45ec7bSml29623 	return (NXGE_ERROR | rs);
42716f45ec7bSml29623 }
42726f45ec7bSml29623 
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;
4282678453a8Sspeer 
42830dc2366fSVenugopal Iyer 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
42840dc2366fSVenugopal Iyer 	handle = nxgep->npi_handle;
42856f45ec7bSml29623 
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 	}
43020dc2366fSVenugopal Iyer 
43030dc2366fSVenugopal Iyer 	return (NPI_SUCCESS);
43040dc2366fSVenugopal Iyer }
43050dc2366fSVenugopal Iyer 
43060dc2366fSVenugopal Iyer /*
43070dc2366fSVenugopal Iyer  * Initialize the RxMAC sub-block
43080dc2366fSVenugopal Iyer  */
43096f45ec7bSml29623 nxge_status_t
nxge_rx_mac_init(p_nxge_t nxgep)43106f45ec7bSml29623 nxge_rx_mac_init(p_nxge_t nxgep)
43116f45ec7bSml29623 {
43126f45ec7bSml29623 	npi_attr_t		ap;
43136f45ec7bSml29623 	nxge_port_t		portt;
43146f45ec7bSml29623 	uint8_t			portn;
43156f45ec7bSml29623 	npi_handle_t		handle;
43166f45ec7bSml29623 	npi_status_t		rs = NPI_SUCCESS;
43176f45ec7bSml29623 	uint16_t		*addr16p;
43186f45ec7bSml29623 	uint16_t		addr0, addr1, addr2;
43196f45ec7bSml29623 	xmac_rx_config_t	xconfig;
43206f45ec7bSml29623 	bmac_rx_config_t	bconfig;
43216f45ec7bSml29623 
43226f45ec7bSml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
43236f45ec7bSml29623 
43246f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n",
43256f45ec7bSml29623 	    portn));
43266f45ec7bSml29623 	handle = nxgep->npi_handle;
43276f45ec7bSml29623 	portt = nxgep->mac.porttype;
43286f45ec7bSml29623 
43296f45ec7bSml29623 	addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet;
43306f45ec7bSml29623 	addr0 = ntohs(addr16p[2]);
43316f45ec7bSml29623 	addr1 = ntohs(addr16p[1]);
43326f45ec7bSml29623 	addr2 = ntohs(addr16p[0]);
43330dc2366fSVenugopal Iyer 	SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR,
43340dc2366fSVenugopal Iyer 	    addr0, addr1, addr2, rs);
43356f45ec7bSml29623 	if (rs != NPI_SUCCESS)
43366f45ec7bSml29623 		goto fail;
43376f45ec7bSml29623 	SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs);
43386f45ec7bSml29623 	if (rs != NPI_SUCCESS)
43396f45ec7bSml29623 		goto fail;
43406f45ec7bSml29623 	SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs);
43416f45ec7bSml29623 	if (rs != NPI_SUCCESS)
43426f45ec7bSml29623 		goto fail;
43436f45ec7bSml29623 
43440dc2366fSVenugopal Iyer 	rs = nxge_rx_mac_mcast_hash_table(nxgep);
43450dc2366fSVenugopal Iyer 	if (rs != NPI_SUCCESS)
43466f45ec7bSml29623 		goto fail;
43476f45ec7bSml29623 
43486f45ec7bSml29623 	if (portt == PORT_TYPE_XMAC) {
43496f45ec7bSml29623 		if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn,
43506f45ec7bSml29623 		    0)) != NPI_SUCCESS)
43516f45ec7bSml29623 			goto fail;
43526f45ec7bSml29623 		nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS;
43536f45ec7bSml29623 
43546f45ec7bSml29623 		(void) nxge_fflp_init_hostinfo(nxgep);
43556f45ec7bSml29623 
43566f45ec7bSml29623 		xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK |
43576f45ec7bSml29623 		    CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK &
43586f45ec7bSml29623 		    ~CFG_XMAC_RX_STRIP_CRC;
43596f45ec7bSml29623 
43606f45ec7bSml29623 		if (nxgep->filter.all_phys_cnt != 0)
43616f45ec7bSml29623 			xconfig |= CFG_XMAC_RX_PROMISCUOUS;
43626f45ec7bSml29623 		if (nxgep->filter.all_multicast_cnt != 0)
43636f45ec7bSml29623 			xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP;
43646f45ec7bSml29623 
43656f45ec7bSml29623 		xconfig |= CFG_XMAC_RX_HASH_FILTER;
43666f45ec7bSml29623 
43670dc2366fSVenugopal Iyer 		if ((rs = npi_xmac_rx_config(handle, INIT,
43680dc2366fSVenugopal Iyer 		    portn, xconfig)) != NPI_SUCCESS)
43696f45ec7bSml29623 			goto fail;
43706f45ec7bSml29623 		nxgep->mac.rx_config = xconfig;
43716f45ec7bSml29623 
43720dc2366fSVenugopal Iyer 		/*
43730dc2366fSVenugopal Iyer 		 * Comparison of mac unique address is always
43740dc2366fSVenugopal Iyer 		 * enabled on XMAC
43750dc2366fSVenugopal Iyer 		 */
43766f45ec7bSml29623 		if ((rs = npi_xmac_zap_rx_counters(handle, portn))
43776f45ec7bSml29623 		    != NPI_SUCCESS)
43786f45ec7bSml29623 			goto fail;
43796f45ec7bSml29623 	} else {
43806f45ec7bSml29623 		if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn,
43816f45ec7bSml29623 		    0) != NPI_SUCCESS)
43826f45ec7bSml29623 			goto fail;
43830dc2366fSVenugopal Iyer 
43846f45ec7bSml29623 		nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS;
43856f45ec7bSml29623 
43860dc2366fSVenugopal Iyer 		(void) nxge_fflp_init_hostinfo(nxgep);
43870dc2366fSVenugopal Iyer 
43886f45ec7bSml29623 		bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX &
43896f45ec7bSml29623 		    ~CFG_BMAC_RX_STRIP_CRC;
43906f45ec7bSml29623 
43916f45ec7bSml29623 		if (nxgep->filter.all_phys_cnt != 0)
43926f45ec7bSml29623 			bconfig |= CFG_BMAC_RX_PROMISCUOUS;
43936f45ec7bSml29623 		if (nxgep->filter.all_multicast_cnt != 0)
43946f45ec7bSml29623 			bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP;
43956f45ec7bSml29623 
43966f45ec7bSml29623 		bconfig |= CFG_BMAC_RX_HASH_FILTER;
43970dc2366fSVenugopal Iyer 		if ((rs = npi_bmac_rx_config(handle, INIT,
43980dc2366fSVenugopal Iyer 		    portn, bconfig)) != NPI_SUCCESS)
43996f45ec7bSml29623 			goto fail;
44006f45ec7bSml29623 		nxgep->mac.rx_config = bconfig;
44016f45ec7bSml29623 
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)
44076f45ec7bSml29623 			goto fail;
44086f45ec7bSml29623 	}
44096f45ec7bSml29623 
44106f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n",
44116f45ec7bSml29623 	    portn));
44126f45ec7bSml29623 
44136f45ec7bSml29623 	return (NXGE_OK);
44146f45ec7bSml29623 
44156f45ec7bSml29623 fail:
44166f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
441752ccf843Smisaki 	    "nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC", portn));
44186f45ec7bSml29623 
44196f45ec7bSml29623 	return (NXGE_ERROR | rs);
44206f45ec7bSml29623 }
44216f45ec7bSml29623 
44226f45ec7bSml29623 /* Enable TXMAC */
44236f45ec7bSml29623 
44246f45ec7bSml29623 nxge_status_t
nxge_tx_mac_enable(p_nxge_t nxgep)44256f45ec7bSml29623 nxge_tx_mac_enable(p_nxge_t nxgep)
44266f45ec7bSml29623 {
44276f45ec7bSml29623 	npi_handle_t	handle;
44286f45ec7bSml29623 	npi_status_t	rs = NPI_SUCCESS;
44296f45ec7bSml29623 	nxge_status_t	status = NXGE_OK;
44306f45ec7bSml29623 
44316f45ec7bSml29623 	handle = nxgep->npi_handle;
44326f45ec7bSml29623 
44336f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>",
44346f45ec7bSml29623 	    nxgep->mac.portnum));
44356f45ec7bSml29623 
44366f45ec7bSml29623 	if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
44376f45ec7bSml29623 		goto fail;
44386f45ec7bSml29623 
44396f45ec7bSml29623 	/* based on speed */
44406f45ec7bSml29623 	nxgep->msg_min = ETHERMIN;
44416f45ec7bSml29623 
44426f45ec7bSml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
44436f45ec7bSml29623 		if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
44446f45ec7bSml29623 		    CFG_XMAC_TX)) != NPI_SUCCESS)
44456f45ec7bSml29623 			goto fail;
44466f45ec7bSml29623 	} else {
44476f45ec7bSml29623 		if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
44486f45ec7bSml29623 		    CFG_BMAC_TX)) != NPI_SUCCESS)
44496f45ec7bSml29623 			goto fail;
44506f45ec7bSml29623 	}
44516f45ec7bSml29623 
44526f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>",
44536f45ec7bSml29623 	    nxgep->mac.portnum));
44546f45ec7bSml29623 
44556f45ec7bSml29623 	return (NXGE_OK);
44566f45ec7bSml29623 fail:
44576f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
44586f45ec7bSml29623 	    "nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC",
44596f45ec7bSml29623 	    nxgep->mac.portnum));
44606f45ec7bSml29623 	if (rs != NPI_SUCCESS)
44616f45ec7bSml29623 		return (NXGE_ERROR | rs);
44626f45ec7bSml29623 	else
44636f45ec7bSml29623 		return (status);
44646f45ec7bSml29623 }
44656f45ec7bSml29623 
44666f45ec7bSml29623 /* Disable TXMAC */
44676f45ec7bSml29623 
44686f45ec7bSml29623 nxge_status_t
nxge_tx_mac_disable(p_nxge_t nxgep)44696f45ec7bSml29623 nxge_tx_mac_disable(p_nxge_t nxgep)
44706f45ec7bSml29623 {
44716f45ec7bSml29623 	npi_handle_t	handle;
44726f45ec7bSml29623 	npi_status_t	rs = NPI_SUCCESS;
44736f45ec7bSml29623 
4474678453a8Sspeer 	if (isLDOMguest(nxgep))
4475678453a8Sspeer 		return (NXGE_OK);
4476678453a8Sspeer 
44776f45ec7bSml29623 	handle = nxgep->npi_handle;
44786f45ec7bSml29623 
44796f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>",
44806f45ec7bSml29623 	    nxgep->mac.portnum));
44816f45ec7bSml29623 
44826f45ec7bSml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
44836f45ec7bSml29623 		if ((rs = npi_xmac_tx_config(handle, DISABLE,
44846f45ec7bSml29623 		    nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS)
44856f45ec7bSml29623 			goto fail;
44866f45ec7bSml29623 	} else {
44876f45ec7bSml29623 		if ((rs = npi_bmac_tx_config(handle, DISABLE,
44886f45ec7bSml29623 		    nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS)
44896f45ec7bSml29623 			goto fail;
44906f45ec7bSml29623 	}
44916f45ec7bSml29623 
44926f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>",
44936f45ec7bSml29623 	    nxgep->mac.portnum));
44946f45ec7bSml29623 	return (NXGE_OK);
44956f45ec7bSml29623 fail:
44966f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
44976f45ec7bSml29623 	    "nxge_tx_mac_disable: Failed to disable port<%d> TxMAC",
44986f45ec7bSml29623 	    nxgep->mac.portnum));
44996f45ec7bSml29623 	return (NXGE_ERROR | rs);
45006f45ec7bSml29623 }
45016f45ec7bSml29623 
45026f45ec7bSml29623 /* Enable RXMAC */
45036f45ec7bSml29623 
45046f45ec7bSml29623 nxge_status_t
nxge_rx_mac_enable(p_nxge_t nxgep)45056f45ec7bSml29623 nxge_rx_mac_enable(p_nxge_t nxgep)
45066f45ec7bSml29623 {
45076f45ec7bSml29623 	npi_handle_t	handle;
45086f45ec7bSml29623 	uint8_t		portn;
45096f45ec7bSml29623 	npi_status_t	rs = NPI_SUCCESS;
45106f45ec7bSml29623 	nxge_status_t	status = NXGE_OK;
45116f45ec7bSml29623 
4512678453a8Sspeer 	/* This is a service-domain-only activity. */
4513678453a8Sspeer 	if (isLDOMguest(nxgep))
4514678453a8Sspeer 		return (status);
4515678453a8Sspeer 
45166f45ec7bSml29623 	handle = nxgep->npi_handle;
45176f45ec7bSml29623 	portn = nxgep->mac.portnum;
45186f45ec7bSml29623 
45196f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>",
45206f45ec7bSml29623 	    portn));
45216f45ec7bSml29623 
45226f45ec7bSml29623 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
45236f45ec7bSml29623 		goto fail;
45246f45ec7bSml29623 
45256f45ec7bSml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
45266f45ec7bSml29623 		if ((rs = npi_xmac_rx_config(handle, ENABLE, portn,
45276f45ec7bSml29623 		    CFG_XMAC_RX)) != NPI_SUCCESS)
45286f45ec7bSml29623 			goto fail;
45296f45ec7bSml29623 	} else {
45306f45ec7bSml29623 		if ((rs = npi_bmac_rx_config(handle, ENABLE, portn,
45316f45ec7bSml29623 		    CFG_BMAC_RX)) != NPI_SUCCESS)
45326f45ec7bSml29623 			goto fail;
45336f45ec7bSml29623 	}
45346f45ec7bSml29623 
4535678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4536678453a8Sspeer 	    "<== nxge_rx_mac_enable: port<%d>", portn));
45376f45ec7bSml29623 
45386f45ec7bSml29623 	return (NXGE_OK);
45396f45ec7bSml29623 fail:
45406f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4541678453a8Sspeer 	    "nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC", portn));
45426f45ec7bSml29623 
45436f45ec7bSml29623 	if (rs != NPI_SUCCESS)
45446f45ec7bSml29623 		return (NXGE_ERROR | rs);
45456f45ec7bSml29623 	else
45466f45ec7bSml29623 		return (status);
45476f45ec7bSml29623 }
45486f45ec7bSml29623 
45496f45ec7bSml29623 /* Disable RXMAC */
45506f45ec7bSml29623 
45516f45ec7bSml29623 nxge_status_t
nxge_rx_mac_disable(p_nxge_t nxgep)45526f45ec7bSml29623 nxge_rx_mac_disable(p_nxge_t nxgep)
45536f45ec7bSml29623 {
45546f45ec7bSml29623 	npi_handle_t	handle;
45556f45ec7bSml29623 	uint8_t		portn;
45566f45ec7bSml29623 	npi_status_t	rs = NPI_SUCCESS;
45576f45ec7bSml29623 
4558678453a8Sspeer 	/* If we are a guest domain driver, don't bother. */
4559678453a8Sspeer 	if (isLDOMguest(nxgep))
4560678453a8Sspeer 		return (NXGE_OK);
4561678453a8Sspeer 
45626f45ec7bSml29623 	handle = nxgep->npi_handle;
45636f45ec7bSml29623 	portn = nxgep->mac.portnum;
45646f45ec7bSml29623 
45656f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>",
45666f45ec7bSml29623 	    portn));
45676f45ec7bSml29623 
45686f45ec7bSml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
45696f45ec7bSml29623 		if ((rs = npi_xmac_rx_config(handle, DISABLE, portn,
45706f45ec7bSml29623 		    CFG_XMAC_RX)) != NPI_SUCCESS)
45716f45ec7bSml29623 			goto fail;
45726f45ec7bSml29623 	} else {
45736f45ec7bSml29623 		if ((rs = npi_bmac_rx_config(handle, DISABLE, portn,
45746f45ec7bSml29623 		    CFG_BMAC_RX)) != NPI_SUCCESS)
45756f45ec7bSml29623 			goto fail;
45766f45ec7bSml29623 	}
45776f45ec7bSml29623 
45786f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>",
45796f45ec7bSml29623 	    portn));
45806f45ec7bSml29623 	return (NXGE_OK);
45816f45ec7bSml29623 fail:
45826f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
458352ccf843Smisaki 	    "nxgep_rx_mac_disable: Failed to disable port<%d> RxMAC", portn));
45846f45ec7bSml29623 
45856f45ec7bSml29623 	return (NXGE_ERROR | rs);
45866f45ec7bSml29623 }
45876f45ec7bSml29623 
45886f45ec7bSml29623 /* Reset TXMAC */
45896f45ec7bSml29623 
45906f45ec7bSml29623 nxge_status_t
nxge_tx_mac_reset(p_nxge_t nxgep)45916f45ec7bSml29623 nxge_tx_mac_reset(p_nxge_t nxgep)
45926f45ec7bSml29623 {
45936f45ec7bSml29623 	npi_handle_t	handle;
45946f45ec7bSml29623 	uint8_t		portn;
45956f45ec7bSml29623 	npi_status_t	rs = NPI_SUCCESS;
45966f45ec7bSml29623 
45976f45ec7bSml29623 	handle = nxgep->npi_handle;
45986f45ec7bSml29623 	portn = nxgep->mac.portnum;
45996f45ec7bSml29623 
46006f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>",
46016f45ec7bSml29623 	    portn));
46026f45ec7bSml29623 
46036f45ec7bSml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
46046f45ec7bSml29623 		if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL))
46056f45ec7bSml29623 		    != NPI_SUCCESS)
46066f45ec7bSml29623 			goto fail;
46076f45ec7bSml29623 	} else {
46086f45ec7bSml29623 		if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET))
46096f45ec7bSml29623 		    != NPI_SUCCESS)
46106f45ec7bSml29623 			goto fail;
46116f45ec7bSml29623 	}
46126f45ec7bSml29623 
46136f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>",
46146f45ec7bSml29623 	    portn));
46156f45ec7bSml29623 
46166f45ec7bSml29623 	return (NXGE_OK);
46176f45ec7bSml29623 fail:
46186f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
461952ccf843Smisaki 	    "nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>", portn));
46206f45ec7bSml29623 
46216f45ec7bSml29623 	return (NXGE_ERROR | rs);
46226f45ec7bSml29623 }
46236f45ec7bSml29623 
46246f45ec7bSml29623 /* Reset RXMAC */
46256f45ec7bSml29623 
46266f45ec7bSml29623 nxge_status_t
nxge_rx_mac_reset(p_nxge_t nxgep)46276f45ec7bSml29623 nxge_rx_mac_reset(p_nxge_t nxgep)
46286f45ec7bSml29623 {
46296f45ec7bSml29623 	npi_handle_t	handle;
46306f45ec7bSml29623 	uint8_t		portn;
46316f45ec7bSml29623 	npi_status_t	rs = NPI_SUCCESS;
46326f45ec7bSml29623 
46336f45ec7bSml29623 	handle = nxgep->npi_handle;
46346f45ec7bSml29623 	portn = nxgep->mac.portnum;
46356f45ec7bSml29623 
46366f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>",
46376f45ec7bSml29623 	    portn));
46386f45ec7bSml29623 
46396f45ec7bSml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
46406f45ec7bSml29623 		if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL))
46416f45ec7bSml29623 		    != NPI_SUCCESS)
46426f45ec7bSml29623 			goto fail;
46436f45ec7bSml29623 	} else {
46446f45ec7bSml29623 		if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET))
46456f45ec7bSml29623 		    != NPI_SUCCESS)
46466f45ec7bSml29623 			goto fail;
46476f45ec7bSml29623 	}
46486f45ec7bSml29623 
46496f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>",
46506f45ec7bSml29623 	    portn));
46516f45ec7bSml29623 
46526f45ec7bSml29623 	return (NXGE_OK);
46536f45ec7bSml29623 fail:
46546f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
465552ccf843Smisaki 	    "nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>", portn));
46566f45ec7bSml29623 	return (NXGE_ERROR | rs);
46576f45ec7bSml29623 }
46586f45ec7bSml29623 
465959ac0c16Sdavemq /* 10G fiber link interrupt start routine */
46606f45ec7bSml29623 
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);
473759ac0c16Sdavemq }
473859ac0c16Sdavemq 
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 }
475459ac0c16Sdavemq 
475559ac0c16Sdavemq /* Enable/Disable Link Status change interrupt */
47566f45ec7bSml29623 
47576f45ec7bSml29623 nxge_status_t
nxge_link_intr(p_nxge_t nxgep,link_intr_enable_t enable)47586f45ec7bSml29623 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable)
47596f45ec7bSml29623 {
47606f45ec7bSml29623 	uint8_t		portn;
476159ac0c16Sdavemq 	nxge_status_t	status = NXGE_OK;
47626f45ec7bSml29623 
47636f45ec7bSml29623 	portn = nxgep->mac.portnum;
47646f45ec7bSml29623 
47656f45ec7bSml29623 	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);
47686f45ec7bSml29623 
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)
47746f45ec7bSml29623 		goto fail;
47756f45ec7bSml29623 
47766f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn));
47776f45ec7bSml29623 
47786f45ec7bSml29623 	return (NXGE_OK);
47796f45ec7bSml29623 fail:
47806f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
478152ccf843Smisaki 	    "nxge_link_intr: Failed to set port<%d> mif intr mode", portn));
47826f45ec7bSml29623 
478359ac0c16Sdavemq 	return (status);
47846f45ec7bSml29623 }
47856f45ec7bSml29623 
47866f45ec7bSml29623 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */
47876f45ec7bSml29623 
47886f45ec7bSml29623 nxge_status_t
nxge_mii_xcvr_init(p_nxge_t nxgep)47896f45ec7bSml29623 nxge_mii_xcvr_init(p_nxge_t nxgep)
47906f45ec7bSml29623 {
47916f45ec7bSml29623 	p_nxge_param_t	param_arr;
47926f45ec7bSml29623 	p_nxge_stats_t	statsp;
47936f45ec7bSml29623 	uint8_t		xcvr_portn;
47946f45ec7bSml29623 	p_mii_regs_t	mii_regs;
47956f45ec7bSml29623 	mii_bmcr_t	bmcr;
47966f45ec7bSml29623 	mii_bmsr_t	bmsr;
47976f45ec7bSml29623 	mii_anar_t	anar;
47986f45ec7bSml29623 	mii_gcr_t	gcr;
47996f45ec7bSml29623 	mii_esr_t	esr;
48006f45ec7bSml29623 	mii_aux_ctl_t	bcm5464r_aux;
48016f45ec7bSml29623 	int		status = NXGE_OK;
48026f45ec7bSml29623 
48036f45ec7bSml29623 	uint_t delay;
48046f45ec7bSml29623 
48056f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init"));
48066f45ec7bSml29623 
48076f45ec7bSml29623 	param_arr = nxgep->param_arr;
48086f45ec7bSml29623 	statsp = nxgep->statsp;
48096f45ec7bSml29623 	xcvr_portn = statsp->mac_stats.xcvr_portn;
48106f45ec7bSml29623 
48116f45ec7bSml29623 	mii_regs = NULL;
48126f45ec7bSml29623 
48136f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
48146f45ec7bSml29623 	    "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value));
48156f45ec7bSml29623 
48166f45ec7bSml29623 	/*
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 
4826d81011f0Ssbehera 	/*
48276f45ec7bSml29623 	 * Reset the transceiver.
48286f45ec7bSml29623 	 */
48296f45ec7bSml29623 	delay = 0;
48306f45ec7bSml29623 	bmcr.value = 0;
48316f45ec7bSml29623 	bmcr.bits.reset = 1;
48326f45ec7bSml29623 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
483352ccf843Smisaki 	    (uint8_t)(uint64_t)&mii_regs->bmcr,
483452ccf843Smisaki 	    bmcr.value)) != NXGE_OK)
48356f45ec7bSml29623 		goto fail;
48366f45ec7bSml29623 	do {
48376f45ec7bSml29623 		drv_usecwait(500);
48386f45ec7bSml29623 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
483952ccf843Smisaki 		    (uint8_t)(uint64_t)&mii_regs->bmcr,
484052ccf843Smisaki 		    &bmcr.value)) != NXGE_OK)
48416f45ec7bSml29623 			goto fail;
48426f45ec7bSml29623 		delay++;
48436f45ec7bSml29623 	} while ((bmcr.bits.reset) && (delay < 1000));
48446f45ec7bSml29623 	if (delay == 1000) {
48456f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed."));
48466f45ec7bSml29623 		goto fail;
48476f45ec7bSml29623 	}
48486f45ec7bSml29623 
48496f45ec7bSml29623 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
48506f45ec7bSml29623 	    (uint8_t)(uint64_t)(&mii_regs->bmsr),
48516f45ec7bSml29623 	    &bmsr.value)) != NXGE_OK)
48526f45ec7bSml29623 		goto fail;
48536f45ec7bSml29623 
48546f45ec7bSml29623 	param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able;
48556f45ec7bSml29623 	param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4;
48566f45ec7bSml29623 	param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx;
48576f45ec7bSml29623 	param_arr[param_anar_100hdx].value = 0;
48586f45ec7bSml29623 	param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx;
48596f45ec7bSml29623 	param_arr[param_anar_10hdx].value = 0;
48606f45ec7bSml29623 
48616f45ec7bSml29623 	/*
48626f45ec7bSml29623 	 * Initialize the xcvr statistics.
48636f45ec7bSml29623 	 */
48646f45ec7bSml29623 	statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able;
48656f45ec7bSml29623 	statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4;
48666f45ec7bSml29623 	statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx;
48676f45ec7bSml29623 	statsp->mac_stats.cap_100hdx = 0;
48686f45ec7bSml29623 	statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx;
48696f45ec7bSml29623 	statsp->mac_stats.cap_10hdx = 0;
48706f45ec7bSml29623 	statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value;
48716f45ec7bSml29623 	statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
48726f45ec7bSml29623 
48736f45ec7bSml29623 	/*
487400161856Syc148097 	 * Initialize the xcvr advertised capability statistics.
48756f45ec7bSml29623 	 */
48766f45ec7bSml29623 	statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value;
48776f45ec7bSml29623 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
48786f45ec7bSml29623 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
48796f45ec7bSml29623 	statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value;
48806f45ec7bSml29623 	statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value;
48816f45ec7bSml29623 	statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value;
48826f45ec7bSml29623 	statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value;
48836f45ec7bSml29623 	statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value;
48846f45ec7bSml29623 	statsp->mac_stats.adv_cap_asmpause =
48856f45ec7bSml29623 	    param_arr[param_anar_asmpause].value;
48866f45ec7bSml29623 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
48876f45ec7bSml29623 
48886f45ec7bSml29623 
48896f45ec7bSml29623 	/*
48906f45ec7bSml29623 	 * Check for extended status just in case we're
48916f45ec7bSml29623 	 * running a Gigibit phy.
48926f45ec7bSml29623 	 */
48936f45ec7bSml29623 	if (bmsr.bits.extend_status) {
48946f45ec7bSml29623 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
489552ccf843Smisaki 		    (uint8_t)(uint64_t)(&mii_regs->esr),
489652ccf843Smisaki 		    &esr.value)) != NXGE_OK)
48976f45ec7bSml29623 			goto fail;
489852ccf843Smisaki 		param_arr[param_anar_1000fdx].value &= esr.bits.link_1000fdx;
48996f45ec7bSml29623 		param_arr[param_anar_1000hdx].value = 0;
49006f45ec7bSml29623 
49016f45ec7bSml29623 		statsp->mac_stats.cap_1000fdx =
490252ccf843Smisaki 		    (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx);
49036f45ec7bSml29623 		statsp->mac_stats.cap_1000hdx = 0;
49046f45ec7bSml29623 	} else {
49056f45ec7bSml29623 		param_arr[param_anar_1000fdx].value = 0;
49066f45ec7bSml29623 		param_arr[param_anar_1000hdx].value = 0;
49076f45ec7bSml29623 	}
49086f45ec7bSml29623 
49096f45ec7bSml29623 	/*
49106f45ec7bSml29623 	 * Initialize 1G Statistics once the capability is established.
49116f45ec7bSml29623 	 */
49126f45ec7bSml29623 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
49136f45ec7bSml29623 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
49146f45ec7bSml29623 
49156f45ec7bSml29623 	/*
491600161856Syc148097 	 * Initialize the link statistics.
49176f45ec7bSml29623 	 */
49186f45ec7bSml29623 	statsp->mac_stats.link_T4 = 0;
49196f45ec7bSml29623 	statsp->mac_stats.link_asmpause = 0;
49206f45ec7bSml29623 	statsp->mac_stats.link_pause = 0;
49216f45ec7bSml29623 	statsp->mac_stats.link_speed = 0;
49226f45ec7bSml29623 	statsp->mac_stats.link_duplex = 0;
49236f45ec7bSml29623 	statsp->mac_stats.link_up = 0;
49246f45ec7bSml29623 
49256f45ec7bSml29623 	/*
49266f45ec7bSml29623 	 * Switch off Auto-negotiation, 100M and full duplex.
49276f45ec7bSml29623 	 */
49286f45ec7bSml29623 	bmcr.value = 0;
49296f45ec7bSml29623 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
493052ccf843Smisaki 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
493152ccf843Smisaki 	    bmcr.value)) != NXGE_OK)
49326f45ec7bSml29623 		goto fail;
49336f45ec7bSml29623 
49346f45ec7bSml29623 	if ((statsp->port_stats.lb_mode == nxge_lb_phy) ||
49356f45ec7bSml29623 	    (statsp->port_stats.lb_mode == nxge_lb_phy1000)) {
49366f45ec7bSml29623 		bmcr.bits.loopback = 1;
49376f45ec7bSml29623 		bmcr.bits.enable_autoneg = 0;
49386f45ec7bSml29623 		if (statsp->port_stats.lb_mode == nxge_lb_phy1000)
49396f45ec7bSml29623 			bmcr.bits.speed_1000_sel = 1;
49406f45ec7bSml29623 		bmcr.bits.duplex_mode = 1;
49416f45ec7bSml29623 		param_arr[param_autoneg].value = 0;
49426f45ec7bSml29623 	} else {
49436f45ec7bSml29623 		bmcr.bits.loopback = 0;
49446f45ec7bSml29623 	}
49456f45ec7bSml29623 
49466f45ec7bSml29623 	if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
49476f45ec7bSml29623 	    (statsp->port_stats.lb_mode == nxge_lb_ext100) ||
49486f45ec7bSml29623 	    (statsp->port_stats.lb_mode == nxge_lb_ext10)) {
49496f45ec7bSml29623 		param_arr[param_autoneg].value = 0;
49506f45ec7bSml29623 		bcm5464r_aux.value = 0;
49516f45ec7bSml29623 		bcm5464r_aux.bits.ext_lb = 1;
49526f45ec7bSml29623 		bcm5464r_aux.bits.write_1 = 1;
49536f45ec7bSml29623 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
495452ccf843Smisaki 		    BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK)
49556f45ec7bSml29623 			goto fail;
49566f45ec7bSml29623 	}
49576f45ec7bSml29623 
495800161856Syc148097 	/* If auto-negotiation is desired */
49596f45ec7bSml29623 	if (param_arr[param_autoneg].value) {
49606f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
49616f45ec7bSml29623 		    "Restarting Auto-negotiation."));
49626f45ec7bSml29623 		/*
49636f45ec7bSml29623 		 * Setup our Auto-negotiation advertisement register.
49646f45ec7bSml29623 		 */
49656f45ec7bSml29623 		anar.value = 0;
49666f45ec7bSml29623 		anar.bits.selector = 1;
49676f45ec7bSml29623 		anar.bits.cap_100T4 = param_arr[param_anar_100T4].value;
49686f45ec7bSml29623 		anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value;
49696f45ec7bSml29623 		anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value;
49706f45ec7bSml29623 		anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value;
49716f45ec7bSml29623 		anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value;
49726f45ec7bSml29623 		anar.bits.cap_asmpause = 0;
49736f45ec7bSml29623 		anar.bits.cap_pause = 0;
49746f45ec7bSml29623 		if (param_arr[param_anar_1000fdx].value ||
49756f45ec7bSml29623 		    param_arr[param_anar_100fdx].value ||
49766f45ec7bSml29623 		    param_arr[param_anar_10fdx].value) {
49776f45ec7bSml29623 			anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause;
49786f45ec7bSml29623 			anar.bits.cap_pause = statsp->mac_stats.cap_pause;
49796f45ec7bSml29623 		}
49806f45ec7bSml29623 
498100161856Syc148097 		/* Write to the auto-negotiation advertisement register */
49826f45ec7bSml29623 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
498352ccf843Smisaki 		    (uint8_t)(uint64_t)(&mii_regs->anar),
498452ccf843Smisaki 		    anar.value)) != NXGE_OK)
49856f45ec7bSml29623 			goto fail;
49866f45ec7bSml29623 		if (bmsr.bits.extend_status) {
49876f45ec7bSml29623 			gcr.value = 0;
49886f45ec7bSml29623 			gcr.bits.ms_mode_en =
49896f45ec7bSml29623 			    param_arr[param_master_cfg_enable].value;
49906f45ec7bSml29623 			gcr.bits.master =
49916f45ec7bSml29623 			    param_arr[param_master_cfg_value].value;
49926f45ec7bSml29623 			gcr.bits.link_1000fdx =
49936f45ec7bSml29623 			    param_arr[param_anar_1000fdx].value;
49946f45ec7bSml29623 			gcr.bits.link_1000hdx =
49956f45ec7bSml29623 			    param_arr[param_anar_1000hdx].value;
49966f45ec7bSml29623 			if ((status = nxge_mii_write(nxgep, xcvr_portn,
499752ccf843Smisaki 			    (uint8_t)(uint64_t)(&mii_regs->gcr),
499852ccf843Smisaki 			    gcr.value)) != NXGE_OK)
49996f45ec7bSml29623 				goto fail;
50006f45ec7bSml29623 		}
50016f45ec7bSml29623 
50026f45ec7bSml29623 		bmcr.bits.enable_autoneg = 1;
50036f45ec7bSml29623 		bmcr.bits.restart_autoneg = 1;
50046f45ec7bSml29623 
50056f45ec7bSml29623 	} else {
50066f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode."));
50076f45ec7bSml29623 		bmcr.bits.speed_1000_sel =
50086f45ec7bSml29623 		    param_arr[param_anar_1000fdx].value |
50096f45ec7bSml29623 		    param_arr[param_anar_1000hdx].value;
50106f45ec7bSml29623 		bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) &
50116f45ec7bSml29623 		    (param_arr[param_anar_100fdx].value |
50126f45ec7bSml29623 		    param_arr[param_anar_100hdx].value);
501300161856Syc148097 
501400161856Syc148097 		/* Force to 1G */
50156f45ec7bSml29623 		if (bmcr.bits.speed_1000_sel) {
50166f45ec7bSml29623 			statsp->mac_stats.link_speed = 1000;
50176f45ec7bSml29623 			gcr.value = 0;
50186f45ec7bSml29623 			gcr.bits.ms_mode_en =
50196f45ec7bSml29623 			    param_arr[param_master_cfg_enable].value;
50206f45ec7bSml29623 			gcr.bits.master =
50216f45ec7bSml29623 			    param_arr[param_master_cfg_value].value;
50226f45ec7bSml29623 			if ((status = nxge_mii_write(nxgep, xcvr_portn,
50236f45ec7bSml29623 			    (uint8_t)(uint64_t)(&mii_regs->gcr),
502452ccf843Smisaki 			    gcr.value)) != NXGE_OK)
50256f45ec7bSml29623 				goto fail;
50266f45ec7bSml29623 			if (param_arr[param_anar_1000fdx].value) {
50276f45ec7bSml29623 				bmcr.bits.duplex_mode = 1;
50286f45ec7bSml29623 				statsp->mac_stats.link_duplex = 2;
50296f45ec7bSml29623 			} else
50306f45ec7bSml29623 				statsp->mac_stats.link_duplex = 1;
503100161856Syc148097 
503200161856Syc148097 		/* Force to 100M */
50336f45ec7bSml29623 		} else if (bmcr.bits.speed_sel) {
50346f45ec7bSml29623 			statsp->mac_stats.link_speed = 100;
50356f45ec7bSml29623 			if (param_arr[param_anar_100fdx].value) {
50366f45ec7bSml29623 				bmcr.bits.duplex_mode = 1;
50376f45ec7bSml29623 				statsp->mac_stats.link_duplex = 2;
50386f45ec7bSml29623 			} else
50396f45ec7bSml29623 				statsp->mac_stats.link_duplex = 1;
504000161856Syc148097 
504100161856Syc148097 		/* Force to 10M */
50426f45ec7bSml29623 		} else {
50436f45ec7bSml29623 			statsp->mac_stats.link_speed = 10;
50446f45ec7bSml29623 			if (param_arr[param_anar_10fdx].value) {
50456f45ec7bSml29623 				bmcr.bits.duplex_mode = 1;
50466f45ec7bSml29623 				statsp->mac_stats.link_duplex = 2;
50476f45ec7bSml29623 			} else
50486f45ec7bSml29623 				statsp->mac_stats.link_duplex = 1;
50496f45ec7bSml29623 		}
50506f45ec7bSml29623 		if (statsp->mac_stats.link_duplex != 1) {
50516f45ec7bSml29623 			statsp->mac_stats.link_asmpause =
50526f45ec7bSml29623 			    statsp->mac_stats.cap_asmpause;
50536f45ec7bSml29623 			statsp->mac_stats.link_pause =
50546f45ec7bSml29623 			    statsp->mac_stats.cap_pause;
50556f45ec7bSml29623 		}
50566f45ec7bSml29623 
50576f45ec7bSml29623 		if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
50586f45ec7bSml29623 		    (statsp->port_stats.lb_mode == nxge_lb_ext100) ||
50596f45ec7bSml29623 		    (statsp->port_stats.lb_mode == nxge_lb_ext10)) {
50606f45ec7bSml29623 			if (statsp->port_stats.lb_mode == nxge_lb_ext1000) {
50616f45ec7bSml29623 				/* BCM5464R 1000mbps external loopback mode */
50626f45ec7bSml29623 				gcr.value = 0;
50636f45ec7bSml29623 				gcr.bits.ms_mode_en = 1;
50646f45ec7bSml29623 				gcr.bits.master = 1;
50656f45ec7bSml29623 				if ((status = nxge_mii_write(nxgep, xcvr_portn,
50666f45ec7bSml29623 				    (uint8_t)(uint64_t)(&mii_regs->gcr),
506752ccf843Smisaki 				    gcr.value)) != NXGE_OK)
50686f45ec7bSml29623 					goto fail;
50696f45ec7bSml29623 				bmcr.value = 0;
50706f45ec7bSml29623 				bmcr.bits.speed_1000_sel = 1;
50716f45ec7bSml29623 				statsp->mac_stats.link_speed = 1000;
50726f45ec7bSml29623 			} else if (statsp->port_stats.lb_mode
50736f45ec7bSml29623 			    == nxge_lb_ext100) {
50746f45ec7bSml29623 				/* BCM5464R 100mbps external loopback mode */
50756f45ec7bSml29623 				bmcr.value = 0;
50766f45ec7bSml29623 				bmcr.bits.speed_sel = 1;
50776f45ec7bSml29623 				bmcr.bits.duplex_mode = 1;
50786f45ec7bSml29623 				statsp->mac_stats.link_speed = 100;
50796f45ec7bSml29623 			} else if (statsp->port_stats.lb_mode
50806f45ec7bSml29623 			    == nxge_lb_ext10) {
50816f45ec7bSml29623 				/* BCM5464R 10mbps external loopback mode */
50826f45ec7bSml29623 				bmcr.value = 0;
50836f45ec7bSml29623 				bmcr.bits.duplex_mode = 1;
50846f45ec7bSml29623 				statsp->mac_stats.link_speed = 10;
50856f45ec7bSml29623 			}
50866f45ec7bSml29623 		}
50876f45ec7bSml29623 	}
50886f45ec7bSml29623 
50896f45ec7bSml29623 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
50906f45ec7bSml29623 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
50916f45ec7bSml29623 	    bmcr.value)) != NXGE_OK)
50926f45ec7bSml29623 		goto fail;
50936f45ec7bSml29623 
50946f45ec7bSml29623 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
509552ccf843Smisaki 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
509652ccf843Smisaki 	    &bmcr.value)) != NXGE_OK)
50976f45ec7bSml29623 		goto fail;
50986f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value));
50996f45ec7bSml29623 
51006f45ec7bSml29623 	/*
51016f45ec7bSml29623 	 * Initialize the xcvr status kept in the context structure.
51026f45ec7bSml29623 	 */
51036f45ec7bSml29623 	nxgep->soft_bmsr.value = 0;
51046f45ec7bSml29623 
51056f45ec7bSml29623 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
51066f45ec7bSml29623 	    (uint8_t)(uint64_t)(&mii_regs->bmsr),
51076f45ec7bSml29623 	    &nxgep->bmsr.value)) != NXGE_OK)
51086f45ec7bSml29623 		goto fail;
51096f45ec7bSml29623 
51106f45ec7bSml29623 	statsp->mac_stats.xcvr_inits++;
51116f45ec7bSml29623 	nxgep->bmsr.value = 0;
51126f45ec7bSml29623 
51136f45ec7bSml29623 fail:
51146f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
51156f45ec7bSml29623 	    "<== nxge_mii_xcvr_init status 0x%x", status));
51166f45ec7bSml29623 	return (status);
51176f45ec7bSml29623 }
51186f45ec7bSml29623 
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 
53346f45ec7bSml29623 /* Read from a MII compliant register */
53356f45ec7bSml29623 
53366f45ec7bSml29623 nxge_status_t
nxge_mii_read(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t xcvr_reg,uint16_t * value)53376f45ec7bSml29623 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
53386f45ec7bSml29623     uint16_t *value)
53396f45ec7bSml29623 {
53406f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
53416f45ec7bSml29623 
53426f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>"
53436f45ec7bSml29623 	    "xcvr_reg<%d>", xcvr_portn, xcvr_reg));
53446f45ec7bSml29623 
5345321febdeSsbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
53466f45ec7bSml29623 
5347d81011f0Ssbehera 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
5348d81011f0Ssbehera 	    (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) {
53496f45ec7bSml29623 		if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle,
53506f45ec7bSml29623 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
53516f45ec7bSml29623 			goto fail;
53522e59129aSraghus 	} else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
53532e59129aSraghus 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
53546f45ec7bSml29623 		if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle,
53556f45ec7bSml29623 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
53566f45ec7bSml29623 			goto fail;
53576f45ec7bSml29623 	} else
53586f45ec7bSml29623 		goto fail;
53596f45ec7bSml29623 
5360321febdeSsbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
53616f45ec7bSml29623 
53626f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>"
536352ccf843Smisaki 	    "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, *value));
53646f45ec7bSml29623 	return (NXGE_OK);
53656f45ec7bSml29623 fail:
5366321febdeSsbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
53676f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
536852ccf843Smisaki 	    "nxge_mii_read: Failed to read mii on xcvr %d", xcvr_portn));
53696f45ec7bSml29623 
53706f45ec7bSml29623 	return (NXGE_ERROR | rs);
53716f45ec7bSml29623 }
53726f45ec7bSml29623 
53736f45ec7bSml29623 /* Write to a MII compliant Register */
53746f45ec7bSml29623 
53756f45ec7bSml29623 nxge_status_t
nxge_mii_write(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t xcvr_reg,uint16_t value)53766f45ec7bSml29623 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
53776f45ec7bSml29623     uint16_t value)
53786f45ec7bSml29623 {
53796f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
53806f45ec7bSml29623 
53816f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>"
538252ccf843Smisaki 	    "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, value));
53836f45ec7bSml29623 
5384321febdeSsbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
53856f45ec7bSml29623 
5386d81011f0Ssbehera 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
5387d81011f0Ssbehera 	    (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) {
53886f45ec7bSml29623 		if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle,
53896f45ec7bSml29623 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
53906f45ec7bSml29623 			goto fail;
53912e59129aSraghus 	} else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
53922e59129aSraghus 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
53936f45ec7bSml29623 		if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle,
53946f45ec7bSml29623 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
53956f45ec7bSml29623 			goto fail;
53966f45ec7bSml29623 	} else
53976f45ec7bSml29623 		goto fail;
53986f45ec7bSml29623 
5399321febdeSsbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
54006f45ec7bSml29623 
54016f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>"
54026f45ec7bSml29623 	    "xcvr_reg<%d>", xcvr_portn, xcvr_reg));
54036f45ec7bSml29623 	return (NXGE_OK);
54046f45ec7bSml29623 fail:
5405321febdeSsbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
54066f45ec7bSml29623 
54076f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
540852ccf843Smisaki 	    "nxge_mii_write: Failed to write mii on xcvr %d", xcvr_portn));
54096f45ec7bSml29623 
54106f45ec7bSml29623 	return (NXGE_ERROR | rs);
54116f45ec7bSml29623 }
54126f45ec7bSml29623 
541300161856Syc148097 /*
541400161856Syc148097  * Perform write to Clause45 serdes / transceiver device
541500161856Syc148097  * Arguments:
541600161856Syc148097  *	xcvr_portn:	The IEEE 802.3 Clause45 PHYAD, it is the same as port
541700161856Syc148097  *			number if nxge_mdio_write is used for accessing the
541800161856Syc148097  *			internal LSIL serdes. Otherwise PHYAD is different
541900161856Syc148097  *			for different platforms.
542000161856Syc148097  *	device:		With each PHYAD, the driver can use MDIO to control
542100161856Syc148097  *			multiple devices inside the PHY, here "device" is an
542200161856Syc148097  *			MMD (MDIO managable device).
542300161856Syc148097  *	xcvr_reg:	Each device has multiple registers. xcvr_reg specifies
542400161856Syc148097  *			the register which the driver will write value to.
542500161856Syc148097  *	value:		The register value will be filled in.
542600161856Syc148097  */
54276f45ec7bSml29623 nxge_status_t
nxge_mdio_read(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t device,uint16_t xcvr_reg,uint16_t * value)54286f45ec7bSml29623 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
54296f45ec7bSml29623     uint16_t xcvr_reg, uint16_t *value)
54306f45ec7bSml29623 {
54316f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
54326f45ec7bSml29623 
54336f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>",
54346f45ec7bSml29623 	    xcvr_portn));
54356f45ec7bSml29623 
543653560810Ssbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
54376f45ec7bSml29623 
54386f45ec7bSml29623 	if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle,
54396f45ec7bSml29623 	    xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
54406f45ec7bSml29623 		goto fail;
54416f45ec7bSml29623 
544253560810Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
54436f45ec7bSml29623 
54446f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>",
54456f45ec7bSml29623 	    xcvr_portn));
54466f45ec7bSml29623 	return (NXGE_OK);
54476f45ec7bSml29623 fail:
544853560810Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
54496f45ec7bSml29623 
54506f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
545152ccf843Smisaki 	    "nxge_mdio_read: Failed to read mdio on xcvr %d", xcvr_portn));
54526f45ec7bSml29623 
54536f45ec7bSml29623 	return (NXGE_ERROR | rs);
54546f45ec7bSml29623 }
54556f45ec7bSml29623 
54566f45ec7bSml29623 /* Perform write to Clause45 serdes / transceiver device */
54576f45ec7bSml29623 
54586f45ec7bSml29623 nxge_status_t
nxge_mdio_write(p_nxge_t nxgep,uint8_t xcvr_portn,uint8_t device,uint16_t xcvr_reg,uint16_t value)54596f45ec7bSml29623 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
54606f45ec7bSml29623     uint16_t xcvr_reg, uint16_t value)
54616f45ec7bSml29623 {
54626f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
54636f45ec7bSml29623 
54646f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>",
54656f45ec7bSml29623 	    xcvr_portn));
54666f45ec7bSml29623 
546753560810Ssbehera 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
54686f45ec7bSml29623 
54696f45ec7bSml29623 	if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle,
54706f45ec7bSml29623 	    xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
54716f45ec7bSml29623 		goto fail;
54726f45ec7bSml29623 
547353560810Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
54746f45ec7bSml29623 
54756f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>",
54766f45ec7bSml29623 	    xcvr_portn));
54776f45ec7bSml29623 	return (NXGE_OK);
54786f45ec7bSml29623 fail:
547953560810Ssbehera 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
54806f45ec7bSml29623 
54816f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
548252ccf843Smisaki 	    "nxge_mdio_write: Failed to write mdio on xcvr %d", xcvr_portn));
54836f45ec7bSml29623 
54846f45ec7bSml29623 	return (NXGE_ERROR | rs);
54856f45ec7bSml29623 }
54866f45ec7bSml29623 
54876f45ec7bSml29623 
54886f45ec7bSml29623 /* Check MII to see if there is any link status change */
54896f45ec7bSml29623 
54906f45ec7bSml29623 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)54916f45ec7bSml29623 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints,
54926f45ec7bSml29623     nxge_link_state_t *link_up)
54936f45ec7bSml29623 {
54946f45ec7bSml29623 	p_nxge_param_t	param_arr;
54956f45ec7bSml29623 	p_nxge_stats_t	statsp;
54966f45ec7bSml29623 	p_mii_regs_t	mii_regs;
54976f45ec7bSml29623 	p_mii_bmsr_t	soft_bmsr;
54986f45ec7bSml29623 	mii_anar_t	anar;
54996f45ec7bSml29623 	mii_anlpar_t	anlpar;
55006f45ec7bSml29623 	mii_anar_t	an_common;
55016f45ec7bSml29623 	mii_aner_t	aner;
55026f45ec7bSml29623 	mii_gsr_t	gsr;
55036f45ec7bSml29623 	nxge_status_t	status = NXGE_OK;
55046f45ec7bSml29623 
55056f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check"));
55066f45ec7bSml29623 
55076f45ec7bSml29623 	mii_regs = NULL;
55086f45ec7bSml29623 	param_arr = nxgep->param_arr;
55096f45ec7bSml29623 	statsp = nxgep->statsp;
55106f45ec7bSml29623 	soft_bmsr = &nxgep->soft_bmsr;
55116f45ec7bSml29623 	*link_up = LINK_NO_CHANGE;
55126f45ec7bSml29623 
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 
55176f45ec7bSml29623 	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));
55216f45ec7bSml29623 		if (bmsr.bits.link_status) {
55226f45ec7bSml29623 			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));
55266f45ec7bSml29623 		} else {
5527774da109Stc99174@train 			/* Only status change will update *link_up */
5528774da109Stc99174@train 			if (statsp->mac_stats.link_up == 1) {
5529774da109Stc99174@train 				*link_up = LINK_IS_DOWN;
5530774da109Stc99174@train 				/* Will notify, turn off further msg */
5531774da109Stc99174@train 				nxgep->link_notify = B_FALSE;
5532774da109Stc99174@train 			}
55336f45ec7bSml29623 			statsp->mac_stats.link_up = 0;
55346f45ec7bSml29623 			soft_bmsr->bits.link_status = 0;
55356f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
55366f45ec7bSml29623 			    "Link down cable problem"));
55376f45ec7bSml29623 		}
55386f45ec7bSml29623 	}
55396f45ec7bSml29623 
5540d81011f0Ssbehera 	if (nxgep->mac.portmode == PORT_1G_COPPER &&
5541d81011f0Ssbehera 	    param_arr[param_autoneg].value) {
55426f45ec7bSml29623 		if (bmsr_ints.bits.auto_neg_complete) {
55436f45ec7bSml29623 			if (bmsr.bits.auto_neg_complete)
55446f45ec7bSml29623 				soft_bmsr->bits.auto_neg_complete = 1;
55456f45ec7bSml29623 			else
55466f45ec7bSml29623 				soft_bmsr->bits.auto_neg_complete = 0;
55476f45ec7bSml29623 		}
55486f45ec7bSml29623 		if (soft_bmsr->bits.link_status == 0) {
55496f45ec7bSml29623 			statsp->mac_stats.link_T4 = 0;
55506f45ec7bSml29623 			statsp->mac_stats.link_speed = 0;
55516f45ec7bSml29623 			statsp->mac_stats.link_duplex = 0;
55526f45ec7bSml29623 			statsp->mac_stats.link_asmpause = 0;
55536f45ec7bSml29623 			statsp->mac_stats.link_pause = 0;
55546f45ec7bSml29623 			statsp->mac_stats.lp_cap_autoneg = 0;
55556f45ec7bSml29623 			statsp->mac_stats.lp_cap_100T4 = 0;
55566f45ec7bSml29623 			statsp->mac_stats.lp_cap_1000fdx = 0;
55576f45ec7bSml29623 			statsp->mac_stats.lp_cap_1000hdx = 0;
55586f45ec7bSml29623 			statsp->mac_stats.lp_cap_100fdx = 0;
55596f45ec7bSml29623 			statsp->mac_stats.lp_cap_100hdx = 0;
55606f45ec7bSml29623 			statsp->mac_stats.lp_cap_10fdx = 0;
55616f45ec7bSml29623 			statsp->mac_stats.lp_cap_10hdx = 0;
55626f45ec7bSml29623 			statsp->mac_stats.lp_cap_10gfdx = 0;
55636f45ec7bSml29623 			statsp->mac_stats.lp_cap_10ghdx = 0;
55646f45ec7bSml29623 			statsp->mac_stats.lp_cap_asmpause = 0;
55656f45ec7bSml29623 			statsp->mac_stats.lp_cap_pause = 0;
55666f45ec7bSml29623 		}
55676f45ec7bSml29623 	} else
55686f45ec7bSml29623 		soft_bmsr->bits.auto_neg_complete = 1;
55696f45ec7bSml29623 
55706f45ec7bSml29623 	if ((bmsr_ints.bits.link_status ||
55716f45ec7bSml29623 	    bmsr_ints.bits.auto_neg_complete) &&
55726f45ec7bSml29623 	    soft_bmsr->bits.link_status &&
55736f45ec7bSml29623 	    soft_bmsr->bits.auto_neg_complete) {
5574774da109Stc99174@train 		if (statsp->mac_stats.link_up == 0) {
5575774da109Stc99174@train 			*link_up = LINK_IS_UP;
5576774da109Stc99174@train 			nxgep->link_notify = B_FALSE;
5577774da109Stc99174@train 		}
55786f45ec7bSml29623 		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) {
55886f45ec7bSml29623 			if ((status = nxge_mii_read(nxgep,
55896f45ec7bSml29623 			    statsp->mac_stats.xcvr_portn,
55906f45ec7bSml29623 			    (uint8_t)(uint64_t)(&mii_regs->anar),
55916f45ec7bSml29623 			    &anar.value)) != NXGE_OK)
55926f45ec7bSml29623 				goto fail;
55936f45ec7bSml29623 			if ((status = nxge_mii_read(nxgep,
55946f45ec7bSml29623 			    statsp->mac_stats.xcvr_portn,
55956f45ec7bSml29623 			    (uint8_t)(uint64_t)(&mii_regs->anlpar),
55966f45ec7bSml29623 			    &anlpar.value)) != NXGE_OK)
55976f45ec7bSml29623 				goto fail;
55986f45ec7bSml29623 			if ((status = nxge_mii_read(nxgep,
55996f45ec7bSml29623 			    statsp->mac_stats.xcvr_portn,
56006f45ec7bSml29623 			    (uint8_t)(uint64_t)(&mii_regs->aner),
56016f45ec7bSml29623 			    &aner.value)) != NXGE_OK)
56026f45ec7bSml29623 				goto fail;
56036f45ec7bSml29623 			statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able;
56046f45ec7bSml29623 			statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4;
56056f45ec7bSml29623 			statsp->mac_stats.lp_cap_100fdx =
56066f45ec7bSml29623 			    anlpar.bits.cap_100fdx;
56076f45ec7bSml29623 			statsp->mac_stats.lp_cap_100hdx =
56086f45ec7bSml29623 			    anlpar.bits.cap_100hdx;
56096f45ec7bSml29623 			statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx;
56106f45ec7bSml29623 			statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx;
56116f45ec7bSml29623 			statsp->mac_stats.lp_cap_asmpause =
56126f45ec7bSml29623 			    anlpar.bits.cap_asmpause;
56136f45ec7bSml29623 			statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause;
56146f45ec7bSml29623 			an_common.value = anar.value & anlpar.value;
56156f45ec7bSml29623 			if (param_arr[param_anar_1000fdx].value ||
56166f45ec7bSml29623 			    param_arr[param_anar_1000hdx].value) {
56176f45ec7bSml29623 				if ((status = nxge_mii_read(nxgep,
56186f45ec7bSml29623 				    statsp->mac_stats.xcvr_portn,
56196f45ec7bSml29623 				    (uint8_t)(uint64_t)(&mii_regs->gsr),
562052ccf843Smisaki 				    &gsr.value)) != NXGE_OK)
56216f45ec7bSml29623 					goto fail;
56226f45ec7bSml29623 				statsp->mac_stats.lp_cap_1000fdx =
56236f45ec7bSml29623 				    gsr.bits.link_1000fdx;
56246f45ec7bSml29623 				statsp->mac_stats.lp_cap_1000hdx =
56256f45ec7bSml29623 				    gsr.bits.link_1000hdx;
56266f45ec7bSml29623 				if (param_arr[param_anar_1000fdx].value &&
56276f45ec7bSml29623 				    gsr.bits.link_1000fdx) {
56286f45ec7bSml29623 					statsp->mac_stats.link_speed = 1000;
56296f45ec7bSml29623 					statsp->mac_stats.link_duplex = 2;
56306f45ec7bSml29623 				} else if (
56316f45ec7bSml29623 				    param_arr[param_anar_1000hdx].value &&
56326f45ec7bSml29623 				    gsr.bits.link_1000hdx) {
56336f45ec7bSml29623 					statsp->mac_stats.link_speed = 1000;
56346f45ec7bSml29623 					statsp->mac_stats.link_duplex = 1;
56356f45ec7bSml29623 				}
56366f45ec7bSml29623 			}
56376f45ec7bSml29623 			if ((an_common.value != 0) &&
56386f45ec7bSml29623 			    !(statsp->mac_stats.link_speed)) {
56396f45ec7bSml29623 				if (an_common.bits.cap_100T4) {
56406f45ec7bSml29623 					statsp->mac_stats.link_T4 = 1;
56416f45ec7bSml29623 					statsp->mac_stats.link_speed = 100;
56426f45ec7bSml29623 					statsp->mac_stats.link_duplex = 1;
56436f45ec7bSml29623 				} else if (an_common.bits.cap_100fdx) {
56446f45ec7bSml29623 					statsp->mac_stats.link_speed = 100;
56456f45ec7bSml29623 					statsp->mac_stats.link_duplex = 2;
56466f45ec7bSml29623 				} else if (an_common.bits.cap_100hdx) {
56476f45ec7bSml29623 					statsp->mac_stats.link_speed = 100;
56486f45ec7bSml29623 					statsp->mac_stats.link_duplex = 1;
56496f45ec7bSml29623 				} else if (an_common.bits.cap_10fdx) {
56506f45ec7bSml29623 					statsp->mac_stats.link_speed = 10;
56516f45ec7bSml29623 					statsp->mac_stats.link_duplex = 2;
56526f45ec7bSml29623 				} else if (an_common.bits.cap_10hdx) {
56536f45ec7bSml29623 					statsp->mac_stats.link_speed = 10;
56546f45ec7bSml29623 					statsp->mac_stats.link_duplex = 1;
56556f45ec7bSml29623 				} else {
56566f45ec7bSml29623 					goto fail;
56576f45ec7bSml29623 				}
56586f45ec7bSml29623 			}
56596f45ec7bSml29623 			if (statsp->mac_stats.link_duplex != 1) {
566052ccf843Smisaki 				int	link_pause;
566152ccf843Smisaki 				int	cp, lcp;
566252ccf843Smisaki 
56636f45ec7bSml29623 				statsp->mac_stats.link_asmpause =
56646f45ec7bSml29623 				    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;
56776f45ec7bSml29623 			}
5678d81011f0Ssbehera 		} else if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) {
5679d81011f0Ssbehera 			statsp->mac_stats.link_speed = 1000;
5680d81011f0Ssbehera 			statsp->mac_stats.link_duplex = 2;
56816f45ec7bSml29623 		}
56826f45ec7bSml29623 	}
5683774da109Stc99174@train 	/* Initial link_notify, delay link down msg */
5684774da109Stc99174@train 	if (nxgep->link_notify && nxgep->nxge_mac_state == NXGE_MAC_STARTED &&
5685774da109Stc99174@train 	    (statsp->mac_stats.link_up == 1 || nxgep->link_check_count > 3)) {
56866f45ec7bSml29623 		*link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP :
56876f45ec7bSml29623 		    LINK_IS_DOWN);
56886f45ec7bSml29623 		nxgep->link_notify = B_FALSE;
56896f45ec7bSml29623 	}
56906f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check"));
56916f45ec7bSml29623 	return (NXGE_OK);
56926f45ec7bSml29623 fail:
56936f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
56946f45ec7bSml29623 	    "nxge_mii_check: Unable to check MII"));
56956f45ec7bSml29623 	return (status);
56966f45ec7bSml29623 }
56976f45ec7bSml29623 
569800161856Syc148097 /*
569900161856Syc148097  * Check PCS to see if there is any link status change.
570000161856Syc148097  * This function is called by PORT_1G_SERDES only.
570100161856Syc148097  */
570200161856Syc148097 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) {
5715774da109Stc99174@train 		if ((nxgep->link_notify &&
5716774da109Stc99174@train 		    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 {
5725774da109Stc99174@train 		if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
5726774da109Stc99174@train 		    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 
57396f45ec7bSml29623 /* Add a multicast address entry into the HW hash table */
57406f45ec7bSml29623 
57416f45ec7bSml29623 nxge_status_t
nxge_add_mcast_addr(p_nxge_t nxgep,struct ether_addr * addrp)57426f45ec7bSml29623 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
57436f45ec7bSml29623 {
57446f45ec7bSml29623 	uint32_t mchash;
57456f45ec7bSml29623 	p_hash_filter_t hash_filter;
57466f45ec7bSml29623 	uint16_t hash_bit;
57476f45ec7bSml29623 	uint_t j;
57486f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
57490dc2366fSVenugopal Iyer 	npi_status_t rs;
57506f45ec7bSml29623 
57516f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr"));
57526f45ec7bSml29623 
57536f45ec7bSml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
57546f45ec7bSml29623 	mchash = crc32_mchash(addrp);
57556f45ec7bSml29623 	if (nxgep->hash_filter == NULL) {
57566f45ec7bSml29623 		NXGE_DEBUG_MSG((NULL, STR_CTL,
57576f45ec7bSml29623 		    "Allocating hash filter storage."));
57586f45ec7bSml29623 		nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t),
57596f45ec7bSml29623 		    KM_SLEEP);
57606f45ec7bSml29623 	}
57610dc2366fSVenugopal Iyer 
57626f45ec7bSml29623 	hash_filter = nxgep->hash_filter;
57636f45ec7bSml29623 	j = mchash / HASH_REG_WIDTH;
57646f45ec7bSml29623 	hash_bit = (1 << (mchash % HASH_REG_WIDTH));
57656f45ec7bSml29623 	hash_filter->hash_filter_regs[j] |= hash_bit;
57666f45ec7bSml29623 	hash_filter->hash_bit_ref_cnt[mchash]++;
57676f45ec7bSml29623 	if (hash_filter->hash_bit_ref_cnt[mchash] == 1) {
57686f45ec7bSml29623 		hash_filter->hash_ref_cnt++;
57696f45ec7bSml29623 	}
57700dc2366fSVenugopal Iyer 
57710dc2366fSVenugopal Iyer 	rs = nxge_rx_mac_mcast_hash_table(nxgep);
57720dc2366fSVenugopal Iyer 	if (rs != NPI_SUCCESS)
57736f45ec7bSml29623 		goto fail;
57746f45ec7bSml29623 
57756f45ec7bSml29623 	RW_EXIT(&nxgep->filter_lock);
57766f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr"));
57776f45ec7bSml29623 	return (NXGE_OK);
57786f45ec7bSml29623 fail:
57796f45ec7bSml29623 	RW_EXIT(&nxgep->filter_lock);
57806f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: "
57816f45ec7bSml29623 	    "Unable to add multicast address"));
57826f45ec7bSml29623 	return (status);
57836f45ec7bSml29623 }
57846f45ec7bSml29623 
57856f45ec7bSml29623 /* Remove a multicast address entry from the HW hash table */
57866f45ec7bSml29623 
57876f45ec7bSml29623 nxge_status_t
nxge_del_mcast_addr(p_nxge_t nxgep,struct ether_addr * addrp)57886f45ec7bSml29623 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
57896f45ec7bSml29623 {
57906f45ec7bSml29623 	uint32_t mchash;
57916f45ec7bSml29623 	p_hash_filter_t hash_filter;
57926f45ec7bSml29623 	uint16_t hash_bit;
57936f45ec7bSml29623 	uint_t j;
57946f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
57950dc2366fSVenugopal Iyer 	npi_status_t rs;
57966f45ec7bSml29623 
57976f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr"));
57986f45ec7bSml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
57996f45ec7bSml29623 	mchash = crc32_mchash(addrp);
58006f45ec7bSml29623 	if (nxgep->hash_filter == NULL) {
58016f45ec7bSml29623 		NXGE_DEBUG_MSG((NULL, STR_CTL,
58026f45ec7bSml29623 		    "Hash filter already de_allocated."));
58036f45ec7bSml29623 		RW_EXIT(&nxgep->filter_lock);
58046f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
58056f45ec7bSml29623 		return (NXGE_OK);
58066f45ec7bSml29623 	}
58076f45ec7bSml29623 	hash_filter = nxgep->hash_filter;
58086f45ec7bSml29623 	hash_filter->hash_bit_ref_cnt[mchash]--;
58096f45ec7bSml29623 	if (hash_filter->hash_bit_ref_cnt[mchash] == 0) {
58106f45ec7bSml29623 		j = mchash / HASH_REG_WIDTH;
58116f45ec7bSml29623 		hash_bit = (1 << (mchash % HASH_REG_WIDTH));
58126f45ec7bSml29623 		hash_filter->hash_filter_regs[j] &= ~hash_bit;
58136f45ec7bSml29623 		hash_filter->hash_ref_cnt--;
58146f45ec7bSml29623 	}
58150dc2366fSVenugopal Iyer 
58166f45ec7bSml29623 	if (hash_filter->hash_ref_cnt == 0) {
58176f45ec7bSml29623 		NXGE_DEBUG_MSG((NULL, STR_CTL,
58186f45ec7bSml29623 		    "De-allocating hash filter storage."));
58196f45ec7bSml29623 		KMEM_FREE(hash_filter, sizeof (hash_filter_t));
58206f45ec7bSml29623 		nxgep->hash_filter = NULL;
58216f45ec7bSml29623 	}
58226f45ec7bSml29623 
58230dc2366fSVenugopal Iyer 	rs = nxge_rx_mac_mcast_hash_table(nxgep);
58240dc2366fSVenugopal Iyer 	if (rs != NPI_SUCCESS)
58256f45ec7bSml29623 		goto fail;
58260dc2366fSVenugopal Iyer 
58276f45ec7bSml29623 	RW_EXIT(&nxgep->filter_lock);
58286f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
58296f45ec7bSml29623 
58306f45ec7bSml29623 	return (NXGE_OK);
58316f45ec7bSml29623 fail:
58326f45ec7bSml29623 	RW_EXIT(&nxgep->filter_lock);
58336f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: "
58346f45ec7bSml29623 	    "Unable to remove multicast address"));
58356f45ec7bSml29623 
58366f45ec7bSml29623 	return (status);
58376f45ec7bSml29623 }
58386f45ec7bSml29623 
58396f45ec7bSml29623 /* Set MAC address into MAC address HW registers */
58406f45ec7bSml29623 
58416f45ec7bSml29623 nxge_status_t
nxge_set_mac_addr(p_nxge_t nxgep,struct ether_addr * addrp)58426f45ec7bSml29623 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp)
58436f45ec7bSml29623 {
58446f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
58456f45ec7bSml29623 
58466f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr"));
58476f45ec7bSml29623 
58486f45ec7bSml29623 	MUTEX_ENTER(&nxgep->ouraddr_lock);
58496f45ec7bSml29623 	/*
58506f45ec7bSml29623 	 * Exit if the address is same as ouraddr or multicast or broadcast
58516f45ec7bSml29623 	 */
58526f45ec7bSml29623 	if (((addrp->ether_addr_octet[0] & 01) == 1) ||
58536f45ec7bSml29623 	    (ether_cmp(addrp, &etherbroadcastaddr) == 0) ||
58546f45ec7bSml29623 	    (ether_cmp(addrp, &nxgep->ouraddr) == 0)) {
58556f45ec7bSml29623 		goto nxge_set_mac_addr_exit;
58566f45ec7bSml29623 	}
58576f45ec7bSml29623 	nxgep->ouraddr = *addrp;
58586f45ec7bSml29623 	/*
58596f45ec7bSml29623 	 * Set new interface local address and re-init device.
58606f45ec7bSml29623 	 * This is destructive to any other streams attached
58616f45ec7bSml29623 	 * to this device.
58626f45ec7bSml29623 	 */
58636f45ec7bSml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
58646f45ec7bSml29623 	if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
58656f45ec7bSml29623 		goto fail;
58666f45ec7bSml29623 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
58676f45ec7bSml29623 		goto fail;
58686f45ec7bSml29623 
58696f45ec7bSml29623 	RW_EXIT(&nxgep->filter_lock);
58706f45ec7bSml29623 	MUTEX_EXIT(&nxgep->ouraddr_lock);
58716f45ec7bSml29623 	goto nxge_set_mac_addr_end;
58726f45ec7bSml29623 nxge_set_mac_addr_exit:
58736f45ec7bSml29623 	MUTEX_EXIT(&nxgep->ouraddr_lock);
58746f45ec7bSml29623 nxge_set_mac_addr_end:
58756f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr"));
58766f45ec7bSml29623 
58776f45ec7bSml29623 	return (NXGE_OK);
58786f45ec7bSml29623 fail:
58796f45ec7bSml29623 	MUTEX_EXIT(&nxgep->ouraddr_lock);
58806f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: "
58816f45ec7bSml29623 	    "Unable to set mac address"));
58826f45ec7bSml29623 	return (status);
58836f45ec7bSml29623 }
58846f45ec7bSml29623 
588598ecde52Stm144005 static
588698ecde52Stm144005 check_link_state_t
nxge_check_link_stop(nxge_t * nxge)588700161856Syc148097 nxge_check_link_stop(nxge_t *nxge)
588898ecde52Stm144005 {
588998ecde52Stm144005 	/* If the poll has been cancelled, return STOP. */
589098ecde52Stm144005 	MUTEX_ENTER(&nxge->poll_lock);
589198ecde52Stm144005 	if (nxge->suspended || nxge->poll_state == LINK_MONITOR_STOPPING) {
589298ecde52Stm144005 		nxge->poll_state = LINK_MONITOR_STOP;
589398ecde52Stm144005 		nxge->nxge_link_poll_timerid = 0;
589498ecde52Stm144005 		cv_broadcast(&nxge->poll_cv);
589598ecde52Stm144005 		MUTEX_EXIT(&nxge->poll_lock);
589698ecde52Stm144005 
589798ecde52Stm144005 		NXGE_DEBUG_MSG((nxge, MAC_CTL,
589898ecde52Stm144005 		    "nxge_check_%s_link(port<%d>) stopped.",
589998ecde52Stm144005 		    nxge->mac.portmode == PORT_10G_FIBER ? "10g" : "mii",
590098ecde52Stm144005 		    nxge->mac.portnum));
590198ecde52Stm144005 		return (CHECK_LINK_STOP);
590298ecde52Stm144005 	}
590398ecde52Stm144005 	MUTEX_EXIT(&nxge->poll_lock);
590498ecde52Stm144005 
590598ecde52Stm144005 	return (CHECK_LINK_RESCHEDULE);
590698ecde52Stm144005 }
590798ecde52Stm144005 
590800161856Syc148097 /*
590900161856Syc148097  * Check status of MII (MIF or PCS) link.
591000161856Syc148097  * This function is called once per second, that is because this function
591100161856Syc148097  * calls nxge_link_monitor with LINK_MONITOR_START, which starts a timer to
591200161856Syc148097  * call this function recursively.
591300161856Syc148097  */
591459ac0c16Sdavemq static nxge_status_t
nxge_check_mii_link(p_nxge_t nxgep)59156f45ec7bSml29623 nxge_check_mii_link(p_nxge_t nxgep)
59166f45ec7bSml29623 {
59176f45ec7bSml29623 	mii_bmsr_t bmsr_ints, bmsr_data;
59186f45ec7bSml29623 	mii_anlpar_t anlpar;
59196f45ec7bSml29623 	mii_gsr_t gsr;
59206f45ec7bSml29623 	p_mii_regs_t mii_regs;
59216f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
59226f45ec7bSml29623 	uint8_t portn;
59236f45ec7bSml29623 	nxge_link_state_t link_up;
59246f45ec7bSml29623 
592598ecde52Stm144005 	if (nxgep->nxge_magic != NXGE_MAGIC)
592698ecde52Stm144005 		return (NXGE_ERROR);
592798ecde52Stm144005 
592898ecde52Stm144005 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
592998ecde52Stm144005 		return (NXGE_OK);
593098ecde52Stm144005 
59316f45ec7bSml29623 	portn = nxgep->mac.portnum;
59326f45ec7bSml29623 
59336f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>",
59346f45ec7bSml29623 	    portn));
59356f45ec7bSml29623 
59366f45ec7bSml29623 	mii_regs = NULL;
59376f45ec7bSml29623 
59386f45ec7bSml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
59396f45ec7bSml29623 
59406f45ec7bSml29623 	if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10)
59416f45ec7bSml29623 		goto nxge_check_mii_link_exit;
59426f45ec7bSml29623 
59432e59129aSraghus 	switch (nxgep->mac.portmode) {
59442e59129aSraghus 	default:
5945d81011f0Ssbehera 		bmsr_data.value = 0;
59462e59129aSraghus 		if ((status = nxge_mii_read(nxgep,
59472e59129aSraghus 		    nxgep->statsp->mac_stats.xcvr_portn,
59486f45ec7bSml29623 		    (uint8_t)(uint64_t)(&mii_regs->bmsr),
59492e59129aSraghus 		    &bmsr_data.value)) != NXGE_OK) {
59506f45ec7bSml29623 			goto fail;
59512e59129aSraghus 		}
59526f45ec7bSml29623 
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 
59586f45ec7bSml29623 		if (nxgep->param_arr[param_autoneg].value) {
59596f45ec7bSml29623 			if ((status = nxge_mii_read(nxgep,
59606f45ec7bSml29623 			    nxgep->statsp->mac_stats.xcvr_portn,
59616f45ec7bSml29623 			    (uint8_t)(uint64_t)(&mii_regs->gsr),
59626f45ec7bSml29623 			    &gsr.value)) != NXGE_OK)
59636f45ec7bSml29623 				goto fail;
59646f45ec7bSml29623 			if ((status = nxge_mii_read(nxgep,
59656f45ec7bSml29623 			    nxgep->statsp->mac_stats.xcvr_portn,
59666f45ec7bSml29623 			    (uint8_t)(uint64_t)(&mii_regs->anlpar),
59676f45ec7bSml29623 			    &anlpar.value)) != NXGE_OK)
59686f45ec7bSml29623 				goto fail;
5969d81011f0Ssbehera 			if (nxgep->mac.portmode != PORT_1G_RGMII_FIBER) {
5970d81011f0Ssbehera 
59716f45ec7bSml29623 				if (nxgep->statsp->mac_stats.link_up &&
59726f45ec7bSml29623 				    ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^
59736f45ec7bSml29623 				    gsr.bits.link_1000fdx) ||
59746f45ec7bSml29623 				    (nxgep->statsp->mac_stats.lp_cap_1000hdx ^
59756f45ec7bSml29623 				    gsr.bits.link_1000hdx) ||
59766f45ec7bSml29623 				    (nxgep->statsp->mac_stats.lp_cap_100T4 ^
59776f45ec7bSml29623 				    anlpar.bits.cap_100T4) ||
59786f45ec7bSml29623 				    (nxgep->statsp->mac_stats.lp_cap_100fdx ^
59796f45ec7bSml29623 				    anlpar.bits.cap_100fdx) ||
59806f45ec7bSml29623 				    (nxgep->statsp->mac_stats.lp_cap_100hdx ^
59816f45ec7bSml29623 				    anlpar.bits.cap_100hdx) ||
59826f45ec7bSml29623 				    (nxgep->statsp->mac_stats.lp_cap_10fdx ^
59836f45ec7bSml29623 				    anlpar.bits.cap_10fdx) ||
59846f45ec7bSml29623 				    (nxgep->statsp->mac_stats.lp_cap_10hdx ^
59856f45ec7bSml29623 				    anlpar.bits.cap_10hdx))) {
59866f45ec7bSml29623 					bmsr_data.bits.link_status = 0;
59876f45ec7bSml29623 				}
59886f45ec7bSml29623 			}
5989d81011f0Ssbehera 		}
59906f45ec7bSml29623 
59916f45ec7bSml29623 		/* Workaround for link down issue */
59926f45ec7bSml29623 		if (bmsr_data.value == 0) {
59932e59129aSraghus 			cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n");
59946f45ec7bSml29623 			goto nxge_check_mii_link_exit;
59956f45ec7bSml29623 		}
59966f45ec7bSml29623 
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 
60026f45ec7bSml29623 		bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value;
60036f45ec7bSml29623 		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) {
60126f45ec7bSml29623 			goto fail;
60132e59129aSraghus 		}
60142e59129aSraghus 		break;
60152e59129aSraghus 
60162e59129aSraghus 	case PORT_1G_SERDES:
601700161856Syc148097 		/*
601800161856Syc148097 		 * Above default is for all cases except PORT_1G_SERDES.
601900161856Syc148097 		 * The default case gets information from the PHY, but a
602000161856Syc148097 		 * nxge whose portmode equals PORT_1G_SERDES does not
602100161856Syc148097 		 * have a PHY.
602200161856Syc148097 		 */
60232e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
60242e59129aSraghus 		    "==> nxge_check_mii_link port<%d> (SERDES)", portn));
602500161856Syc148097 		nxge_pcs_check(nxgep, portn, &link_up);
60262e59129aSraghus 		break;
60272e59129aSraghus 	}
60286f45ec7bSml29623 
60296f45ec7bSml29623 nxge_check_mii_link_exit:
60306f45ec7bSml29623 	RW_EXIT(&nxgep->filter_lock);
60316f45ec7bSml29623 	if (link_up == LINK_IS_UP) {
60326f45ec7bSml29623 		nxge_link_is_up(nxgep);
60336f45ec7bSml29623 	} else if (link_up == LINK_IS_DOWN) {
60346f45ec7bSml29623 		nxge_link_is_down(nxgep);
60356f45ec7bSml29623 	}
60366f45ec7bSml29623 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
60376f45ec7bSml29623 
60386f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>",
60396f45ec7bSml29623 	    portn));
60406f45ec7bSml29623 	return (NXGE_OK);
60416f45ec7bSml29623 
60426f45ec7bSml29623 fail:
60436f45ec7bSml29623 	RW_EXIT(&nxgep->filter_lock);
60446f45ec7bSml29623 
60456f45ec7bSml29623 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
60466f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
604752ccf843Smisaki 	    "nxge_check_mii_link: Failed to check link port<%d>", portn));
60486f45ec7bSml29623 	return (status);
60496f45ec7bSml29623 }
60506f45ec7bSml29623 
60516f45ec7bSml29623 /*ARGSUSED*/
605259ac0c16Sdavemq static nxge_status_t
nxge_check_10g_link(p_nxge_t nxgep)60536f45ec7bSml29623 nxge_check_10g_link(p_nxge_t nxgep)
60546f45ec7bSml29623 {
60556f45ec7bSml29623 	uint8_t		portn;
60566f45ec7bSml29623 	nxge_status_t	status = NXGE_OK;
6057763fcc44Ssbehera 	boolean_t	link_up;
60582e59129aSraghus 	uint32_t	val;
60592e59129aSraghus 	npi_status_t	rs;
60606f45ec7bSml29623 
606198ecde52Stm144005 	if (nxgep->nxge_magic != NXGE_MAGIC)
606298ecde52Stm144005 		return (NXGE_ERROR);
606398ecde52Stm144005 
606498ecde52Stm144005 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
606598ecde52Stm144005 		return (NXGE_OK);
606698ecde52Stm144005 
60676f45ec7bSml29623 	portn = nxgep->mac.portnum;
6068d81011f0Ssbehera 	val = 0;
6069d81011f0Ssbehera 	rs = NPI_SUCCESS;
60706f45ec7bSml29623 
60716f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>",
60726f45ec7bSml29623 	    portn));
60736f45ec7bSml29623 
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 
60851c7408c9Stc99174@train 			/* Check back-to-back XAUI connect to detect Opus NEM */
60861c7408c9Stc99174@train 			rs = npi_xmac_xpcs_read(nxgep->npi_handle,
60871c7408c9Stc99174@train 			    nxgep->mac.portnum, XPCS_REG_STATUS, &val);
60881c7408c9Stc99174@train 			if (rs != 0)
60891c7408c9Stc99174@train 				goto fail;
60901c7408c9Stc99174@train 
60911c7408c9Stc99174@train 			link_up = B_FALSE;
60921c7408c9Stc99174@train 			if (val & XPCS_STATUS_LANE_ALIGN) {
60931c7408c9Stc99174@train 				link_up = B_TRUE;
60941c7408c9Stc99174@train 			}
60951c7408c9Stc99174@train 
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 					}
61201c7408c9Stc99174@train 				} else if (link_up) { /* XAUI linkup, no PHY */
61211c7408c9Stc99174@train 					/*
61221c7408c9Stc99174@train 					 * This is the back-to-back XAUI
61231c7408c9Stc99174@train 					 * connect case for Opus NEM.
61241c7408c9Stc99174@train 					 */
61251c7408c9Stc99174@train 					nxgep->statsp->mac_stats.xcvr_inuse =
61261c7408c9Stc99174@train 					    XPCS_XCVR;
61271c7408c9Stc99174@train 					nxgep->mac.portmode = PORT_10G_SERDES;
61281c7408c9Stc99174@train 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61291c7408c9Stc99174@train 					    "HSP 10G Serdes DETECTED!!"));
61301c7408c9Stc99174@train 					break;
61312d17280bSsbehera 				}
61322d17280bSsbehera 
6133774da109Stc99174@train 				if (nxgep->link_notify &&
6134774da109Stc99174@train 				    nxgep->link_check_count > 3 &&
6135774da109Stc99174@train 				    nxgep->nxge_mac_state == NXGE_MAC_STARTED ||
6136774da109Stc99174@train 				    nxgep->statsp->mac_stats.link_up == 1) {
6137774da109Stc99174@train 					nxgep->statsp->mac_stats.link_up = 0;
6138774da109Stc99174@train 					nxgep->statsp->mac_stats.link_speed = 0;
6139774da109Stc99174@train 					nxgep->statsp->mac_stats.link_duplex =
6140774da109Stc99174@train 					    0;
6141774da109Stc99174@train 
6142774da109Stc99174@train 					nxge_link_is_down(nxgep);
6143774da109Stc99174@train 					nxgep->link_notify = B_FALSE;
6144774da109Stc99174@train 				}
6145774da109Stc99174@train 
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:
617000161856Syc148097 			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:
61766f45ec7bSml29623 			status = nxge_check_bcm8704_link(nxgep, &link_up);
617789282175SSantwona Behera 			break;
617852cdd236Ssbehera 		}
617989282175SSantwona Behera 
61806f45ec7bSml29623 		if (status != NXGE_OK)
61816f45ec7bSml29623 			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) {
61912e59129aSraghus 			link_up = B_TRUE;
61922e59129aSraghus 		}
6193763fcc44Ssbehera 
6194763fcc44Ssbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
6195763fcc44Ssbehera 		    "==> nxge_check_10g_link port<%d> "
6196763fcc44Ssbehera 		    "XPCS_REG_STATUS2 0x%x link_up %d",
6197763fcc44Ssbehera 		    portn, val, link_up));
6198763fcc44Ssbehera 
61992e59129aSraghus 		break;
62002e59129aSraghus 	}
62016f45ec7bSml29623 
62026f45ec7bSml29623 	if (link_up) {
6203774da109Stc99174@train 		if ((nxgep->link_notify &&
6204774da109Stc99174@train 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
62056f45ec7bSml29623 		    nxgep->statsp->mac_stats.link_up == 0) {
62066f45ec7bSml29623 			if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
62076f45ec7bSml29623 				goto fail;
62086f45ec7bSml29623 			nxgep->statsp->mac_stats.link_up = 1;
62096f45ec7bSml29623 			nxgep->statsp->mac_stats.link_speed = 10000;
62106f45ec7bSml29623 			nxgep->statsp->mac_stats.link_duplex = 2;
62116f45ec7bSml29623 
62126f45ec7bSml29623 			nxge_link_is_up(nxgep);
62136f45ec7bSml29623 			nxgep->link_notify = B_FALSE;
62146f45ec7bSml29623 		}
62156f45ec7bSml29623 	} else {
6216774da109Stc99174@train 		if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
6217774da109Stc99174@train 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
62186f45ec7bSml29623 		    nxgep->statsp->mac_stats.link_up == 1) {
62196f45ec7bSml29623 			if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
62206f45ec7bSml29623 				goto fail;
62216f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
62226f45ec7bSml29623 			    "Link down cable problem"));
62236f45ec7bSml29623 			nxgep->statsp->mac_stats.link_up = 0;
62246f45ec7bSml29623 			nxgep->statsp->mac_stats.link_speed = 0;
62256f45ec7bSml29623 			nxgep->statsp->mac_stats.link_duplex = 0;
62266f45ec7bSml29623 
62276f45ec7bSml29623 			nxge_link_is_down(nxgep);
62286f45ec7bSml29623 			nxgep->link_notify = B_FALSE;
62291c7408c9Stc99174@train 
62301c7408c9Stc99174@train 			if (nxgep->mac.portmode == PORT_10G_SERDES) {
62311c7408c9Stc99174@train 				/*
62321c7408c9Stc99174@train 				 * NEM was unplugged, set up xcvr table
62331c7408c9Stc99174@train 				 * to find another xcvr in the future.
62341c7408c9Stc99174@train 				 */
62351c7408c9Stc99174@train 				(void) nxge_xcvr_find(nxgep);
62361c7408c9Stc99174@train 			}
62376f45ec7bSml29623 		}
62386f45ec7bSml29623 	}
62396f45ec7bSml29623 
62402d17280bSsbehera start_link_check:
62416f45ec7bSml29623 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
62426f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>",
62436f45ec7bSml29623 	    portn));
62446f45ec7bSml29623 	return (NXGE_OK);
62456f45ec7bSml29623 
62466f45ec7bSml29623 fail:
624798ecde52Stm144005 	(void) nxge_check_link_stop(nxgep);
624898ecde52Stm144005 
62496f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
62506f45ec7bSml29623 	    "nxge_check_10g_link: Failed to check link port<%d>",
62516f45ec7bSml29623 	    portn));
62526f45ec7bSml29623 	return (status);
62536f45ec7bSml29623 }
62546f45ec7bSml29623 
62556f45ec7bSml29623 
62566f45ec7bSml29623 /* Declare link down */
62576f45ec7bSml29623 
62586f45ec7bSml29623 void
nxge_link_is_down(p_nxge_t nxgep)62596f45ec7bSml29623 nxge_link_is_down(p_nxge_t nxgep)
62606f45ec7bSml29623 {
626159ac0c16Sdavemq 	p_nxge_stats_t statsp;
626259ac0c16Sdavemq 	char link_stat_msg[64];
626359ac0c16Sdavemq 
62646f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down"));
62656f45ec7bSml29623 
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 
62746f45ec7bSml29623 	mac_link_update(nxgep->mach, LINK_STATE_DOWN);
62756f45ec7bSml29623 
62766f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down"));
62776f45ec7bSml29623 }
62786f45ec7bSml29623 
62796f45ec7bSml29623 /* Declare link up */
62806f45ec7bSml29623 
62816f45ec7bSml29623 void
nxge_link_is_up(p_nxge_t nxgep)62826f45ec7bSml29623 nxge_link_is_up(p_nxge_t nxgep)
62836f45ec7bSml29623 {
628459ac0c16Sdavemq 	p_nxge_stats_t statsp;
628559ac0c16Sdavemq 	char link_stat_msg[64];
62866f45ec7bSml29623 	uint32_t val;
62876f45ec7bSml29623 
62886f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up"));
62896f45ec7bSml29623 
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 
63026f45ec7bSml29623 
63036f45ec7bSml29623 	/* 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)) {
63076f45ec7bSml29623 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
63086f45ec7bSml29623 		    XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
63096f45ec7bSml29623 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
63106f45ec7bSml29623 		    XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
63116f45ec7bSml29623 	}
63126f45ec7bSml29623 
631300161856Syc148097 	/*
631400161856Syc148097 	 * If the driver was plumbed without a link (therefore auto-negotiation
631500161856Syc148097 	 * could not complete), the driver will detect a link up when a cable
631600161856Syc148097 	 * conneting to a link partner is plugged into the port. By the time
631700161856Syc148097 	 * link-up is detected, auto-negotiation should have completed (The
631800161856Syc148097 	 * TN1010 tries to contact a link partner every 8~24ms). Here we re-
631900161856Syc148097 	 * configure the Neptune/NIU according to the newly negotiated speed.
632000161856Syc148097 	 * This is necessary only for the TN1010 basad device because only the
632100161856Syc148097 	 * TN1010 supports dual speeds.
632200161856Syc148097 	 */
632300161856Syc148097 	if (nxgep->mac.portmode == PORT_1G_TN1010 ||
632400161856Syc148097 	    nxgep->mac.portmode == PORT_10G_TN1010) {
632500161856Syc148097 
632600161856Syc148097 		(void) nxge_set_tn1010_param(nxgep);
632700161856Syc148097 
632800161856Syc148097 		/*
632900161856Syc148097 		 * nxge_xcvr_find calls nxge_get_xcvr_type (which sets
633000161856Syc148097 		 * nxgep->portmode) and nxge_setup_xcvr_table (which sets
633100161856Syc148097 		 * the nxgep->xcvr to the proper nxge_xcvr_table_t struct).
633200161856Syc148097 		 */
633300161856Syc148097 		if (nxge_xcvr_find(nxgep) != NXGE_OK) {
633400161856Syc148097 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
633500161856Syc148097 			    "nxge_link_is_up: nxge_xcvr_find failed"));
633600161856Syc148097 		}
633700161856Syc148097 
633800161856Syc148097 		/* nxge_link_init calls nxge_xcvr_init and nxge_serdes_init */
633900161856Syc148097 		if (nxge_link_init(nxgep) != NXGE_OK) {
634000161856Syc148097 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
634100161856Syc148097 			    "nxge_link_is_up: nxge_link_init failed"));
634200161856Syc148097 		}
634300161856Syc148097 
634400161856Syc148097 		/*
634500161856Syc148097 		 * nxge_mac_init calls many subroutines including
634600161856Syc148097 		 * nxge_xif_init which sets XGMII or GMII mode
634700161856Syc148097 		 */
634800161856Syc148097 		if (nxge_mac_init(nxgep) != NXGE_OK) {
634900161856Syc148097 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
635000161856Syc148097 			    "nxge_link_is_up: nxge_mac_init failed"));
635100161856Syc148097 		}
635200161856Syc148097 	} else {
635300161856Syc148097 		(void) nxge_xif_init(nxgep);
635400161856Syc148097 	}
635500161856Syc148097 
635659ac0c16Sdavemq 	if (nxge_no_msg == B_FALSE) {
635759ac0c16Sdavemq 		NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
635859ac0c16Sdavemq 	}
635959ac0c16Sdavemq 
63606f45ec7bSml29623 	mac_link_update(nxgep->mach, LINK_STATE_UP);
63616f45ec7bSml29623 
63626f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up"));
63636f45ec7bSml29623 }
63646f45ec7bSml29623 
636500161856Syc148097 #ifdef NXGE_DEBUG
636600161856Syc148097 /* Dump all TN1010 Status registers */
636700161856Syc148097 static void
nxge_dump_tn1010_status_regs(p_nxge_t nxgep)636800161856Syc148097 nxge_dump_tn1010_status_regs(p_nxge_t nxgep)
636900161856Syc148097 {
637000161856Syc148097 	uint16_t val;
637100161856Syc148097 
637200161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
637300161856Syc148097 	    TN1010_PMA_PMD_DEV_ADDR, 1, &val);
637400161856Syc148097 	cmn_err(CE_NOTE, "PMA status1 = 0x%x", val);
637500161856Syc148097 
637600161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
637700161856Syc148097 	    TN1010_PMA_PMD_DEV_ADDR, 8, &val);
637800161856Syc148097 	cmn_err(CE_NOTE, "PMA status2 = 0x%x", val);
637900161856Syc148097 
638000161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
638100161856Syc148097 	    TN1010_PMA_PMD_DEV_ADDR, 129, &val);
638200161856Syc148097 	cmn_err(CE_NOTE, "10BASET-T status = 0x%x", val);
638300161856Syc148097 
638400161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
638500161856Syc148097 	    TN1010_PCS_DEV_ADDR, 1, &val);
638600161856Syc148097 	cmn_err(CE_NOTE, "PCS status1 = 0x%x", val);
638700161856Syc148097 
638800161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
638900161856Syc148097 	    TN1010_PCS_DEV_ADDR, 8, &val);
639000161856Syc148097 	cmn_err(CE_NOTE, "PCS status2 = 0x%x", val);
639100161856Syc148097 
639200161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
639300161856Syc148097 	    TN1010_PCS_DEV_ADDR, 32, &val);
639400161856Syc148097 	cmn_err(CE_NOTE, "10GBASE-R status1 = 0x%x", val);
639500161856Syc148097 
639600161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
639700161856Syc148097 	    TN1010_PCS_DEV_ADDR, 33, &val);
639800161856Syc148097 	cmn_err(CE_NOTE, "10GBASE-R Status2 = 0x%x", val);
639900161856Syc148097 
640000161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
640100161856Syc148097 	    TN1010_PHYXS_DEV_ADDR, 1, &val);
640200161856Syc148097 	cmn_err(CE_NOTE, "PHYXS status1 = 0x%x", val);
640300161856Syc148097 
640400161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
640500161856Syc148097 	    TN1010_PHYXS_DEV_ADDR, 8, &val);
640600161856Syc148097 	cmn_err(CE_NOTE, "PHYXS status2 = 0x%x", val);
640700161856Syc148097 
640800161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
640900161856Syc148097 	    TN1010_PHYXS_DEV_ADDR, 24, &val);
641000161856Syc148097 	cmn_err(CE_NOTE, "XGXS Lane status = 0x%x", val);
641100161856Syc148097 
641200161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
641300161856Syc148097 	    TN1010_AUTONEG_DEV_ADDR, 1, &val);
641400161856Syc148097 	cmn_err(CE_NOTE, "Autoneg status = 0x%x", val);
641500161856Syc148097 
641600161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
641700161856Syc148097 	    TN1010_AUTONEG_DEV_ADDR, 33, &val);
641800161856Syc148097 	cmn_err(CE_NOTE, "10Gbase-T An status = 0x%x", val);
641900161856Syc148097 
642000161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
642100161856Syc148097 	    TN1010_VENDOR_MMD1_DEV_ADDR, 1, &val);
642200161856Syc148097 	cmn_err(CE_NOTE, "TN1010 status = 0x%x", val);
642300161856Syc148097 
642400161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
642500161856Syc148097 	    TN1010_VENDOR_MMD1_DEV_ADDR, 8, &val);
642600161856Syc148097 	cmn_err(CE_NOTE, "Device status = 0x%x", val);
642700161856Syc148097 
642800161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
642900161856Syc148097 	    TN1010_VENDOR_MMD1_DEV_ADDR, 16, &val);
643000161856Syc148097 	cmn_err(CE_NOTE, "DDR status = 0x%x", val);
643100161856Syc148097 
643200161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
643300161856Syc148097 	    TN1010_VENDOR_MMD1_DEV_ADDR, 17, &val);
643400161856Syc148097 	cmn_err(CE_NOTE, "DDR fault status = 0x%x", val);
643500161856Syc148097 
643600161856Syc148097 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
643700161856Syc148097 	    TN1010_VENDOR_MMD1_DEV_ADDR, 11, &val);
643800161856Syc148097 	cmn_err(CE_NOTE, "Firmware Revision = 0x%x  Major = 0x%x Minor = 0x%x",
643900161856Syc148097 	    val,  (val & 0xFF00) >> 8, val & 0x00FF);
644000161856Syc148097 }
644100161856Syc148097 #endif
644200161856Syc148097 
64436f45ec7bSml29623 /*
64446f45ec7bSml29623  * Calculate the bit in the multicast address filter
64456f45ec7bSml29623  * that selects the given * address.
64466f45ec7bSml29623  * Note: For GEM, the last 8-bits are used.
64476f45ec7bSml29623  */
64486f45ec7bSml29623 uint32_t
crc32_mchash(p_ether_addr_t addr)64496f45ec7bSml29623 crc32_mchash(p_ether_addr_t addr)
64506f45ec7bSml29623 {
64516f45ec7bSml29623 	uint8_t *cp;
64526f45ec7bSml29623 	uint32_t crc;
64536f45ec7bSml29623 	uint32_t c;
64546f45ec7bSml29623 	int byte;
64556f45ec7bSml29623 	int bit;
64566f45ec7bSml29623 
64576f45ec7bSml29623 	cp = (uint8_t *)addr;
64586f45ec7bSml29623 	crc = (uint32_t)0xffffffff;
64596f45ec7bSml29623 	for (byte = 0; byte < 6; byte++) {
64606f45ec7bSml29623 		c = (uint32_t)cp[byte];
64616f45ec7bSml29623 		for (bit = 0; bit < 8; bit++) {
64626f45ec7bSml29623 			if ((c & 0x1) ^ (crc & 0x1))
64636f45ec7bSml29623 				crc = (crc >> 1)^0xedb88320;
64646f45ec7bSml29623 			else
64656f45ec7bSml29623 				crc = (crc >> 1);
64666f45ec7bSml29623 			c >>= 1;
64676f45ec7bSml29623 		}
64686f45ec7bSml29623 	}
64696f45ec7bSml29623 	return ((~crc) >> (32 - HASH_BITS));
64706f45ec7bSml29623 }
64716f45ec7bSml29623 
64726f45ec7bSml29623 /* Reset serdes */
64736f45ec7bSml29623 
64746f45ec7bSml29623 nxge_status_t
nxge_serdes_reset(p_nxge_t nxgep)64756f45ec7bSml29623 nxge_serdes_reset(p_nxge_t nxgep)
64766f45ec7bSml29623 {
64776f45ec7bSml29623 	npi_handle_t		handle;
64786f45ec7bSml29623 
64796f45ec7bSml29623 	handle = nxgep->npi_handle;
64806f45ec7bSml29623 
64816f45ec7bSml29623 	ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1);
64826f45ec7bSml29623 	drv_usecwait(500);
64836f45ec7bSml29623 	ESR_REG_WR(handle, ESR_CONFIG_REG, 0);
64846f45ec7bSml29623 
64856f45ec7bSml29623 	return (NXGE_OK);
64866f45ec7bSml29623 }
64876f45ec7bSml29623 
648800161856Syc148097 /*
648900161856Syc148097  * This function monitors link status using interrupt or polling.
649000161856Syc148097  * It calls nxgep->xcvr.check_link, a member function of
649100161856Syc148097  * nxge_xcvr_table_t. But nxgep->xcvr.check_link calls this
649200161856Syc148097  * function back, that is why the check_link routine is
649300161856Syc148097  * executed periodically.
649400161856Syc148097  */
64956f45ec7bSml29623 nxge_status_t
nxge_link_monitor(p_nxge_t nxgep,link_mon_enable_t enable)64966f45ec7bSml29623 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable)
64976f45ec7bSml29623 {
64986f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
64996f45ec7bSml29623 
6500678453a8Sspeer 	/* If we are a guest domain driver, don't bother. */
6501678453a8Sspeer 	if (isLDOMguest(nxgep))
6502678453a8Sspeer 		return (status);
6503678453a8Sspeer 
65046f45ec7bSml29623 	/*
650598ecde52Stm144005 	 * Return immediately if this is an imaginary XMAC port.
650698ecde52Stm144005 	 * (At least, we don't have 4-port XMAC cards yet.)
65076f45ec7bSml29623 	 */
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))
65126f45ec7bSml29623 		return (NXGE_OK);
65136f45ec7bSml29623 
65146f45ec7bSml29623 	if (nxgep->statsp == NULL) {
65156f45ec7bSml29623 		/* stats has not been allocated. */
65166f45ec7bSml29623 		return (NXGE_OK);
65176f45ec7bSml29623 	}
6518321febdeSsbehera 	/* Don't check link if we're in internal loopback mode */
6519321febdeSsbehera 	if (nxgep->statsp->port_stats.lb_mode >= nxge_lb_serdes10g)
65206f45ec7bSml29623 		return (NXGE_OK);
65216f45ec7bSml29623 
65226f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
65236f45ec7bSml29623 	    "==> nxge_link_monitor port<%d> enable=%d",
65246f45ec7bSml29623 	    nxgep->mac.portnum, enable));
65256f45ec7bSml29623 	if (enable == LINK_MONITOR_START) {
65266f45ec7bSml29623 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
65276f45ec7bSml29623 			if ((status = nxge_link_intr(nxgep, LINK_INTR_START))
65286f45ec7bSml29623 			    != NXGE_OK)
65296f45ec7bSml29623 				goto fail;
65306f45ec7bSml29623 		} else {
653198ecde52Stm144005 			timeout_id_t timerid;
653200161856Syc148097 			/*
653300161856Syc148097 			 * check_link_stop means "Stop the link check", so
653400161856Syc148097 			 * we return without starting the timer.
653500161856Syc148097 			 */
653698ecde52Stm144005 			if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
653798ecde52Stm144005 				return (NXGE_OK);
653898ecde52Stm144005 
653900161856Syc148097 			/*
654000161856Syc148097 			 * Otherwise fire the timer for the nxge to check
654100161856Syc148097 			 * the link using the check_link function
654200161856Syc148097 			 * of the nxge_xcvr_table and pass "nxgep" as the
654300161856Syc148097 			 * argument to the check_link function.
654400161856Syc148097 			 */
654559ac0c16Sdavemq 			if (nxgep->xcvr.check_link) {
654691f84442SToomas Soome 				timerid = timeout((fptrv_t)(uintptr_t)
654791f84442SToomas Soome 				    (nxgep->xcvr.check_link),
65486f45ec7bSml29623 				    nxgep,
654998ecde52Stm144005 				    drv_usectohz(LINK_MONITOR_PERIOD));
655098ecde52Stm144005 				MUTEX_ENTER(&nxgep->poll_lock);
655198ecde52Stm144005 				nxgep->nxge_link_poll_timerid = timerid;
655298ecde52Stm144005 				MUTEX_EXIT(&nxgep->poll_lock);
6553774da109Stc99174@train 				nxgep->link_check_count ++;
655459ac0c16Sdavemq 			} else {
655559ac0c16Sdavemq 				return (NXGE_ERROR);
655659ac0c16Sdavemq 			}
65576f45ec7bSml29623 		}
65586f45ec7bSml29623 	} else {
65596f45ec7bSml29623 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
65606f45ec7bSml29623 			if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP))
65616f45ec7bSml29623 			    != NXGE_OK)
65626f45ec7bSml29623 				goto fail;
65636f45ec7bSml29623 		} else {
656498ecde52Stm144005 			clock_t rv;
656598ecde52Stm144005 
656698ecde52Stm144005 			MUTEX_ENTER(&nxgep->poll_lock);
656798ecde52Stm144005 
656898ecde52Stm144005 			/* If <timerid> == 0, the link monitor has */
656998ecde52Stm144005 			/* never been started, or just now stopped. */
657098ecde52Stm144005 			if (nxgep->nxge_link_poll_timerid == 0) {
657198ecde52Stm144005 				MUTEX_EXIT(&nxgep->poll_lock);
657298ecde52Stm144005 				return (NXGE_OK);
657398ecde52Stm144005 			}
657498ecde52Stm144005 
657598ecde52Stm144005 			nxgep->poll_state = LINK_MONITOR_STOPPING;
6576d3d50737SRafael Vanoni 			rv = cv_reltimedwait(&nxgep->poll_cv, &nxgep->poll_lock,
657798ecde52Stm144005 			    drv_usectohz(LM_WAIT_MULTIPLIER *
6578d3d50737SRafael Vanoni 			    LINK_MONITOR_PERIOD), TR_CLOCK_TICK);
657998ecde52Stm144005 			if (rv == -1) {
658098ecde52Stm144005 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
658198ecde52Stm144005 				    "==> stopping port %d: "
658298ecde52Stm144005 				    "cv_timedwait(%d) timed out",
658398ecde52Stm144005 				    nxgep->mac.portnum, nxgep->poll_state));
658498ecde52Stm144005 				nxgep->poll_state = LINK_MONITOR_STOP;
65856f45ec7bSml29623 				nxgep->nxge_link_poll_timerid = 0;
65866f45ec7bSml29623 			}
658798ecde52Stm144005 
658898ecde52Stm144005 			MUTEX_EXIT(&nxgep->poll_lock);
65896f45ec7bSml29623 		}
65906f45ec7bSml29623 	}
65916f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
65926f45ec7bSml29623 	    "<== nxge_link_monitor port<%d> enable=%d",
65936f45ec7bSml29623 	    nxgep->mac.portnum, enable));
6594678453a8Sspeer 
65956f45ec7bSml29623 	return (NXGE_OK);
65966f45ec7bSml29623 fail:
65976f45ec7bSml29623 	return (status);
659800161856Syc148097 
65996f45ec7bSml29623 }
66006f45ec7bSml29623 
660100161856Syc148097 nxge_status_t
nxge_check_tn1010_link(p_nxge_t nxgep)660200161856Syc148097 nxge_check_tn1010_link(p_nxge_t nxgep)
660300161856Syc148097 {
660400161856Syc148097 	nxge_status_t	status = NXGE_OK;
660500161856Syc148097 	nxge_link_state_t link_up;
660600161856Syc148097 
660700161856Syc148097 	if (nxgep->nxge_magic != NXGE_MAGIC) {
660800161856Syc148097 		/* magic is 0 if driver is not attached */
660900161856Syc148097 		return (NXGE_ERROR);
661000161856Syc148097 	}
661100161856Syc148097 
661200161856Syc148097 	/* Link has been stopped, no need to continue */
661300161856Syc148097 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) {
661400161856Syc148097 		return (NXGE_OK);
661500161856Syc148097 	}
661600161856Syc148097 
661700161856Syc148097 	if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10)
661800161856Syc148097 		goto nxge_check_tn1010_link_exit;
661900161856Syc148097 
662000161856Syc148097 	if ((status = nxge_tn1010_check(nxgep, &link_up)) != NXGE_OK)
662100161856Syc148097 		goto fail;
662200161856Syc148097 
662300161856Syc148097 nxge_check_tn1010_link_exit:
662400161856Syc148097 	if (link_up == LINK_IS_UP)
662500161856Syc148097 		nxge_link_is_up(nxgep);
662600161856Syc148097 	else if (link_up == LINK_IS_DOWN)
662700161856Syc148097 		nxge_link_is_down(nxgep);
662800161856Syc148097 
662900161856Syc148097 	/*
663000161856Syc148097 	 * nxge_link_monitor will call (nxgep->xcvr.check_link)
663100161856Syc148097 	 * which could be THIS function.
663200161856Syc148097 	 */
663300161856Syc148097 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
663400161856Syc148097 
663500161856Syc148097 	return (NXGE_OK);
663600161856Syc148097 
663700161856Syc148097 fail:
663800161856Syc148097 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
663900161856Syc148097 
664000161856Syc148097 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
664100161856Syc148097 	    "nxge_check_tn1010_link: Failed to check link"));
664200161856Syc148097 	return (status);
664300161856Syc148097 }
664400161856Syc148097 
664500161856Syc148097 
664600161856Syc148097 /*
664700161856Syc148097  * Fill variable "link_up" with either LINK_IS_UP or LINK_IS_DOWN.
664800161856Syc148097  */
664900161856Syc148097 static nxge_status_t
nxge_tn1010_check(p_nxge_t nxgep,nxge_link_state_t * link_up)665000161856Syc148097 nxge_tn1010_check(p_nxge_t nxgep, nxge_link_state_t *link_up)
665100161856Syc148097 {
665200161856Syc148097 	nxge_status_t	status = NXGE_OK;
665300161856Syc148097 	p_nxge_stats_t	statsp;
665400161856Syc148097 	uint8_t		phy_port_addr, portn;
665500161856Syc148097 	uint16_t	val;
665600161856Syc148097 
665700161856Syc148097 	*link_up = LINK_NO_CHANGE;
665800161856Syc148097 
665900161856Syc148097 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
666000161856Syc148097 	phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
666100161856Syc148097 	statsp = nxgep->statsp;
666200161856Syc148097 
666300161856Syc148097 	/* Check if link is up */
666400161856Syc148097 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
666500161856Syc148097 	    TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val))
666600161856Syc148097 	    != NXGE_OK) {
666700161856Syc148097 		goto fail;
666800161856Syc148097 	}
666900161856Syc148097 	/*
667000161856Syc148097 	 * nxge_link_is_up has called nxge_set_tn1010_param and set
667100161856Syc148097 	 * portmode and link_speed
667200161856Syc148097 	 */
667300161856Syc148097 	if (val & TN1010_AN_LINK_STAT_BIT) {
6674774da109Stc99174@train 		if ((nxgep->link_notify &&
6675774da109Stc99174@train 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
667600161856Syc148097 		    nxgep->statsp->mac_stats.link_up == 0) {
667700161856Syc148097 			statsp->mac_stats.link_up = 1;
667800161856Syc148097 			statsp->mac_stats.link_duplex = 2;
667900161856Syc148097 			*link_up = LINK_IS_UP;
668000161856Syc148097 			nxgep->link_notify = B_FALSE;
668100161856Syc148097 		}
668200161856Syc148097 	} else {
6683774da109Stc99174@train 		if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
6684774da109Stc99174@train 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
668500161856Syc148097 		    nxgep->statsp->mac_stats.link_up == 1) {
668600161856Syc148097 			statsp->mac_stats.link_up = 0;
668700161856Syc148097 			statsp->mac_stats.link_speed = 0;
668800161856Syc148097 			statsp->mac_stats.link_duplex = 0;
668900161856Syc148097 			*link_up = LINK_IS_DOWN;
669000161856Syc148097 			nxgep->link_notify = B_FALSE;
669100161856Syc148097 		}
669200161856Syc148097 	}
669300161856Syc148097 	return (NXGE_OK);
669400161856Syc148097 
669500161856Syc148097 fail:
669600161856Syc148097 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
669700161856Syc148097 	    "nxge_tn1010_check: Unable to check TN1010"));
669800161856Syc148097 	return (status);
669900161856Syc148097 }
670000161856Syc148097 
670100161856Syc148097 
67026f45ec7bSml29623 /* Set promiscous mode */
67036f45ec7bSml29623 
67046f45ec7bSml29623 nxge_status_t
nxge_set_promisc(p_nxge_t nxgep,boolean_t on)67056f45ec7bSml29623 nxge_set_promisc(p_nxge_t nxgep, boolean_t on)
67066f45ec7bSml29623 {
67076f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
67086f45ec7bSml29623 
670959ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on));
67106f45ec7bSml29623 
67116f45ec7bSml29623 	nxgep->filter.all_phys_cnt = ((on) ? 1 : 0);
67126f45ec7bSml29623 
67136f45ec7bSml29623 	RW_ENTER_WRITER(&nxgep->filter_lock);
67146f45ec7bSml29623 
67156f45ec7bSml29623 	if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) {
67166f45ec7bSml29623 		goto fail;
67176f45ec7bSml29623 	}
67186f45ec7bSml29623 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) {
67196f45ec7bSml29623 		goto fail;
67206f45ec7bSml29623 	}
67216f45ec7bSml29623 
67226f45ec7bSml29623 	RW_EXIT(&nxgep->filter_lock);
67236f45ec7bSml29623 
67246f45ec7bSml29623 	if (on)
67256f45ec7bSml29623 		nxgep->statsp->mac_stats.promisc = B_TRUE;
67266f45ec7bSml29623 	else
67276f45ec7bSml29623 		nxgep->statsp->mac_stats.promisc = B_FALSE;
67286f45ec7bSml29623 
67296f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc"));
67306f45ec7bSml29623 
67316f45ec7bSml29623 	return (NXGE_OK);
67326f45ec7bSml29623 fail:
67336f45ec7bSml29623 	RW_EXIT(&nxgep->filter_lock);
67346f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: "
67356f45ec7bSml29623 	    "Unable to set promisc (%d)", on));
67366f45ec7bSml29623 
67376f45ec7bSml29623 	return (status);
67386f45ec7bSml29623 }
67396f45ec7bSml29623 
67406f45ec7bSml29623 /*ARGSUSED*/
67416f45ec7bSml29623 uint_t
nxge_mif_intr(void * arg1,void * arg2)67426f45ec7bSml29623 nxge_mif_intr(void *arg1, void *arg2)
67436f45ec7bSml29623 {
67446f45ec7bSml29623 #ifdef	NXGE_DEBUG
67456f45ec7bSml29623 	p_nxge_t		nxgep = (p_nxge_t)arg2;
67466f45ec7bSml29623 #endif
67476f45ec7bSml29623 #if NXGE_MIF
67486f45ec7bSml29623 	p_nxge_ldv_t		ldvp = (p_nxge_ldv_t)arg1;
67496f45ec7bSml29623 	uint32_t		status;
67506f45ec7bSml29623 	npi_handle_t		handle;
67516f45ec7bSml29623 	uint8_t			portn;
67526f45ec7bSml29623 	p_nxge_stats_t		statsp;
67536f45ec7bSml29623 #endif
67546f45ec7bSml29623 
67556f45ec7bSml29623 #ifdef	NXGE_MIF
67566f45ec7bSml29623 	if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
67576f45ec7bSml29623 		nxgep = ldvp->nxgep;
67586f45ec7bSml29623 	}
67596f45ec7bSml29623 	nxgep = ldvp->nxgep;
67606f45ec7bSml29623 #endif
67616f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr"));
67626f45ec7bSml29623 
67636f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
67646f45ec7bSml29623 	return (DDI_INTR_CLAIMED);
67656f45ec7bSml29623 
67666f45ec7bSml29623 mif_intr_fail:
67676f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
67686f45ec7bSml29623 	return (DDI_INTR_UNCLAIMED);
67696f45ec7bSml29623 }
67706f45ec7bSml29623 
67716f45ec7bSml29623 /*ARGSUSED*/
67726f45ec7bSml29623 uint_t
nxge_mac_intr(void * arg1,void * arg2)67736f45ec7bSml29623 nxge_mac_intr(void *arg1, void *arg2)
67746f45ec7bSml29623 {
67756f45ec7bSml29623 	p_nxge_t		nxgep = (p_nxge_t)arg2;
67766f45ec7bSml29623 	p_nxge_ldv_t		ldvp = (p_nxge_ldv_t)arg1;
67776f45ec7bSml29623 	p_nxge_ldg_t		ldgp;
67786f45ec7bSml29623 	uint32_t		status;
67796f45ec7bSml29623 	npi_handle_t		handle;
67806f45ec7bSml29623 	uint8_t			portn;
67816f45ec7bSml29623 	p_nxge_stats_t		statsp;
67826f45ec7bSml29623 	npi_status_t		rs = NPI_SUCCESS;
67836f45ec7bSml29623 
67846f45ec7bSml29623 	if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
67856f45ec7bSml29623 		nxgep = ldvp->nxgep;
67866f45ec7bSml29623 	}
67876f45ec7bSml29623 
67886f45ec7bSml29623 	ldgp = ldvp->ldgp;
67896f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: "
67906f45ec7bSml29623 	    "group %d", ldgp->ldg));
67916f45ec7bSml29623 
67926f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
67936f45ec7bSml29623 	/*
67946f45ec7bSml29623 	 * This interrupt handler is for a specific
67956f45ec7bSml29623 	 * mac port.
67966f45ec7bSml29623 	 */
67976f45ec7bSml29623 	statsp = (p_nxge_stats_t)nxgep->statsp;
67986f45ec7bSml29623 	portn = nxgep->mac.portnum;
67996f45ec7bSml29623 
68006f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
68016f45ec7bSml29623 	    "==> nxge_mac_intr: reading mac stats: port<%d>", portn));
68026f45ec7bSml29623 
68036f45ec7bSml29623 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
68046f45ec7bSml29623 		rs = npi_xmac_tx_get_istatus(handle, portn,
68056f45ec7bSml29623 		    (xmac_tx_iconfig_t *)&status);
68066f45ec7bSml29623 		if (rs != NPI_SUCCESS)
68076f45ec7bSml29623 			goto npi_fail;
68086f45ec7bSml29623 		if (status & ICFG_XMAC_TX_ALL) {
68096f45ec7bSml29623 			if (status & ICFG_XMAC_TX_UNDERRUN) {
68106f45ec7bSml29623 				statsp->xmac_stats.tx_underflow_err++;
6811b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
68126f45ec7bSml29623 				    NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
68136f45ec7bSml29623 			}
68146f45ec7bSml29623 			if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) {
68156f45ec7bSml29623 				statsp->xmac_stats.tx_maxpktsize_err++;
6816f6485eecSyc148097 				/*
6817f6485eecSyc148097 				 * Do not send FMA ereport because this
6818f6485eecSyc148097 				 * error does not indicate HW failure.
6819f6485eecSyc148097 				 */
68206f45ec7bSml29623 			}
68216f45ec7bSml29623 			if (status & ICFG_XMAC_TX_OVERFLOW) {
68226f45ec7bSml29623 				statsp->xmac_stats.tx_overflow_err++;
6823b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
68246f45ec7bSml29623 				    NXGE_FM_EREPORT_TXMAC_OVERFLOW);
68256f45ec7bSml29623 			}
68266f45ec7bSml29623 			if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) {
68276f45ec7bSml29623 				statsp->xmac_stats.tx_fifo_xfr_err++;
6828b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
68296f45ec7bSml29623 				    NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR);
68306f45ec7bSml29623 			}
68316f45ec7bSml29623 			if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) {
68326f45ec7bSml29623 				statsp->xmac_stats.tx_byte_cnt +=
68336f45ec7bSml29623 				    XTXMAC_BYTE_CNT_MASK;
68346f45ec7bSml29623 			}
68356f45ec7bSml29623 			if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) {
68366f45ec7bSml29623 				statsp->xmac_stats.tx_frame_cnt +=
68376f45ec7bSml29623 				    XTXMAC_FRM_CNT_MASK;
68386f45ec7bSml29623 			}
68396f45ec7bSml29623 		}
68406f45ec7bSml29623 
68416f45ec7bSml29623 		rs = npi_xmac_rx_get_istatus(handle, portn,
68426f45ec7bSml29623 		    (xmac_rx_iconfig_t *)&status);
68436f45ec7bSml29623 		if (rs != NPI_SUCCESS)
68446f45ec7bSml29623 			goto npi_fail;
68456f45ec7bSml29623 		if (status & ICFG_XMAC_RX_ALL) {
68466f45ec7bSml29623 			if (status & ICFG_XMAC_RX_OVERFLOW)
68476f45ec7bSml29623 				statsp->xmac_stats.rx_overflow_err++;
68486f45ec7bSml29623 			if (status & ICFG_XMAC_RX_UNDERFLOW) {
68496f45ec7bSml29623 				statsp->xmac_stats.rx_underflow_err++;
6850b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
68516f45ec7bSml29623 				    NXGE_FM_EREPORT_RXMAC_UNDERFLOW);
68526f45ec7bSml29623 			}
6853f6485eecSyc148097 			/*
6854f6485eecSyc148097 			 * Do not send FMA ereport for the following 3 errors
6855f6485eecSyc148097 			 * because they do not indicate HW failures.
6856f6485eecSyc148097 			 */
68576f45ec7bSml29623 			if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) {
68586f45ec7bSml29623 				statsp->xmac_stats.rx_crc_err_cnt +=
68596f45ec7bSml29623 				    XRXMAC_CRC_ER_CNT_MASK;
68606f45ec7bSml29623 			}
68616f45ec7bSml29623 			if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) {
68626f45ec7bSml29623 				statsp->xmac_stats.rx_len_err_cnt +=
68636f45ec7bSml29623 				    MAC_LEN_ER_CNT_MASK;
68646f45ec7bSml29623 			}
68656f45ec7bSml29623 			if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) {
68666f45ec7bSml29623 				statsp->xmac_stats.rx_viol_err_cnt +=
68676f45ec7bSml29623 				    XRXMAC_CD_VIO_CNT_MASK;
68686f45ec7bSml29623 			}
68696f45ec7bSml29623 			if (status & ICFG_XMAC_RX_OCT_CNT_EXP) {
68706f45ec7bSml29623 				statsp->xmac_stats.rx_byte_cnt +=
68716f45ec7bSml29623 				    XRXMAC_BT_CNT_MASK;
68726f45ec7bSml29623 			}
68736f45ec7bSml29623 			if (status & ICFG_XMAC_RX_HST_CNT1_EXP) {
68746f45ec7bSml29623 				statsp->xmac_stats.rx_hist1_cnt +=
68756f45ec7bSml29623 				    XRXMAC_HIST_CNT1_MASK;
68766f45ec7bSml29623 			}
68776f45ec7bSml29623 			if (status & ICFG_XMAC_RX_HST_CNT2_EXP) {
68786f45ec7bSml29623 				statsp->xmac_stats.rx_hist2_cnt +=
68796f45ec7bSml29623 				    XRXMAC_HIST_CNT2_MASK;
68806f45ec7bSml29623 			}
68816f45ec7bSml29623 			if (status & ICFG_XMAC_RX_HST_CNT3_EXP) {
68826f45ec7bSml29623 				statsp->xmac_stats.rx_hist3_cnt +=
68836f45ec7bSml29623 				    XRXMAC_HIST_CNT3_MASK;
68846f45ec7bSml29623 			}
68856f45ec7bSml29623 			if (status & ICFG_XMAC_RX_HST_CNT4_EXP) {
68866f45ec7bSml29623 				statsp->xmac_stats.rx_hist4_cnt +=
68876f45ec7bSml29623 				    XRXMAC_HIST_CNT4_MASK;
68886f45ec7bSml29623 			}
68896f45ec7bSml29623 			if (status & ICFG_XMAC_RX_HST_CNT5_EXP) {
68906f45ec7bSml29623 				statsp->xmac_stats.rx_hist5_cnt +=
68916f45ec7bSml29623 				    XRXMAC_HIST_CNT5_MASK;
68926f45ec7bSml29623 			}
68936f45ec7bSml29623 			if (status & ICFG_XMAC_RX_HST_CNT6_EXP) {
68946f45ec7bSml29623 				statsp->xmac_stats.rx_hist6_cnt +=
68956f45ec7bSml29623 				    XRXMAC_HIST_CNT6_MASK;
68966f45ec7bSml29623 			}
68976f45ec7bSml29623 			if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) {
68986f45ec7bSml29623 				statsp->xmac_stats.rx_broadcast_cnt +=
68996f45ec7bSml29623 				    XRXMAC_BC_FRM_CNT_MASK;
69006f45ec7bSml29623 			}
69016f45ec7bSml29623 			if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) {
69026f45ec7bSml29623 				statsp->xmac_stats.rx_mult_cnt +=
69036f45ec7bSml29623 				    XRXMAC_MC_FRM_CNT_MASK;
69046f45ec7bSml29623 			}
6905f6485eecSyc148097 			/*
6906f6485eecSyc148097 			 * Do not send FMA ereport for the following 3 errors
6907f6485eecSyc148097 			 * because they do not indicate HW failures.
6908f6485eecSyc148097 			 */
69096f45ec7bSml29623 			if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) {
69106f45ec7bSml29623 				statsp->xmac_stats.rx_frag_cnt +=
69116f45ec7bSml29623 				    XRXMAC_FRAG_CNT_MASK;
69126f45ec7bSml29623 			}
69136f45ec7bSml29623 			if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) {
69146f45ec7bSml29623 				statsp->xmac_stats.rx_frame_align_err_cnt +=
69156f45ec7bSml29623 				    XRXMAC_AL_ER_CNT_MASK;
69166f45ec7bSml29623 			}
69176f45ec7bSml29623 			if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) {
69186f45ec7bSml29623 				statsp->xmac_stats.rx_linkfault_err_cnt +=
69196f45ec7bSml29623 				    XMAC_LINK_FLT_CNT_MASK;
69206f45ec7bSml29623 			}
69216f45ec7bSml29623 			if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) {
69226f45ec7bSml29623 				statsp->xmac_stats.rx_remotefault_err++;
69236f45ec7bSml29623 			}
69246f45ec7bSml29623 			if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) {
69256f45ec7bSml29623 				statsp->xmac_stats.rx_localfault_err++;
69266f45ec7bSml29623 			}
69276f45ec7bSml29623 		}
69286f45ec7bSml29623 
69296f45ec7bSml29623 		rs = npi_xmac_ctl_get_istatus(handle, portn,
69306f45ec7bSml29623 		    (xmac_ctl_iconfig_t *)&status);
69316f45ec7bSml29623 		if (rs != NPI_SUCCESS)
69326f45ec7bSml29623 			goto npi_fail;
69336f45ec7bSml29623 		if (status & ICFG_XMAC_CTRL_ALL) {
69346f45ec7bSml29623 			if (status & ICFG_XMAC_CTRL_PAUSE_RCVD)
69356f45ec7bSml29623 				statsp->xmac_stats.rx_pause_cnt++;
69366f45ec7bSml29623 			if (status & ICFG_XMAC_CTRL_PAUSE_STATE)
69376f45ec7bSml29623 				statsp->xmac_stats.tx_pause_state++;
69386f45ec7bSml29623 			if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE)
69396f45ec7bSml29623 				statsp->xmac_stats.tx_nopause_state++;
69406f45ec7bSml29623 		}
69416f45ec7bSml29623 	} else if (nxgep->mac.porttype == PORT_TYPE_BMAC) {
69426f45ec7bSml29623 		rs = npi_bmac_tx_get_istatus(handle, portn,
69436f45ec7bSml29623 		    (bmac_tx_iconfig_t *)&status);
69446f45ec7bSml29623 		if (rs != NPI_SUCCESS)
69456f45ec7bSml29623 			goto npi_fail;
69466f45ec7bSml29623 		if (status & ICFG_BMAC_TX_ALL) {
69476f45ec7bSml29623 			if (status & ICFG_BMAC_TX_UNDERFLOW) {
69486f45ec7bSml29623 				statsp->bmac_stats.tx_underrun_err++;
6949b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
69506f45ec7bSml29623 				    NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
69516f45ec7bSml29623 			}
69526f45ec7bSml29623 			if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) {
69536f45ec7bSml29623 				statsp->bmac_stats.tx_max_pkt_err++;
6954b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
69556f45ec7bSml29623 				    NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR);
69566f45ec7bSml29623 			}
69576f45ec7bSml29623 			if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) {
69586f45ec7bSml29623 				statsp->bmac_stats.tx_byte_cnt +=
69596f45ec7bSml29623 				    BTXMAC_BYTE_CNT_MASK;
69606f45ec7bSml29623 			}
69616f45ec7bSml29623 			if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) {
69626f45ec7bSml29623 				statsp->bmac_stats.tx_frame_cnt +=
69636f45ec7bSml29623 				    BTXMAC_FRM_CNT_MASK;
69646f45ec7bSml29623 			}
69656f45ec7bSml29623 		}
69666f45ec7bSml29623 
69676f45ec7bSml29623 		rs = npi_bmac_rx_get_istatus(handle, portn,
69686f45ec7bSml29623 		    (bmac_rx_iconfig_t *)&status);
69696f45ec7bSml29623 		if (rs != NPI_SUCCESS)
69706f45ec7bSml29623 			goto npi_fail;
69716f45ec7bSml29623 		if (status & ICFG_BMAC_RX_ALL) {
69726f45ec7bSml29623 			if (status & ICFG_BMAC_RX_OVERFLOW) {
69736f45ec7bSml29623 				statsp->bmac_stats.rx_overflow_err++;
69746f45ec7bSml29623 			}
69756f45ec7bSml29623 			if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) {
69766f45ec7bSml29623 				statsp->bmac_stats.rx_frame_cnt +=
69776f45ec7bSml29623 				    RXMAC_FRM_CNT_MASK;
69786f45ec7bSml29623 			}
69796f45ec7bSml29623 			if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) {
69806f45ec7bSml29623 				statsp->bmac_stats.rx_crc_err_cnt +=
69816f45ec7bSml29623 				    BMAC_CRC_ER_CNT_MASK;
6982b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
69836f45ec7bSml29623 				    NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP);
69846f45ec7bSml29623 			}
69856f45ec7bSml29623 			if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) {
69866f45ec7bSml29623 				statsp->bmac_stats.rx_len_err_cnt +=
69876f45ec7bSml29623 				    MAC_LEN_ER_CNT_MASK;
6988b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
69896f45ec7bSml29623 				    NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP);
69906f45ec7bSml29623 			}
69914df3b64dSToomas Soome 			if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP) {
69926f45ec7bSml29623 				statsp->bmac_stats.rx_viol_err_cnt +=
69936f45ec7bSml29623 				    BMAC_CD_VIO_CNT_MASK;
6994b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
69956f45ec7bSml29623 				    NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP);
69966f45ec7bSml29623 			}
69976f45ec7bSml29623 			if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) {
69986f45ec7bSml29623 				statsp->bmac_stats.rx_byte_cnt +=
69996f45ec7bSml29623 				    BRXMAC_BYTE_CNT_MASK;
70006f45ec7bSml29623 			}
70016f45ec7bSml29623 			if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) {
70026f45ec7bSml29623 				statsp->bmac_stats.rx_align_err_cnt +=
70036f45ec7bSml29623 				    BMAC_AL_ER_CNT_MASK;
7004b37cc459SToomas Soome 				NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
70056f45ec7bSml29623 				    NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP);
70066f45ec7bSml29623 			}
70076f45ec7bSml29623 
70086f45ec7bSml29623 			rs = npi_bmac_ctl_get_istatus(handle, portn,
70096f45ec7bSml29623 			    (bmac_ctl_iconfig_t *)&status);
70106f45ec7bSml29623 			if (rs != NPI_SUCCESS)
70116f45ec7bSml29623 				goto npi_fail;
70126f45ec7bSml29623 
70136f45ec7bSml29623 			if (status & ICFG_BMAC_CTL_ALL) {
70146f45ec7bSml29623 				if (status & ICFG_BMAC_CTL_RCVPAUSE)
70156f45ec7bSml29623 					statsp->bmac_stats.rx_pause_cnt++;
70166f45ec7bSml29623 				if (status & ICFG_BMAC_CTL_INPAUSE_ST)
70176f45ec7bSml29623 					statsp->bmac_stats.tx_pause_state++;
70186f45ec7bSml29623 				if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST)
70196f45ec7bSml29623 					statsp->bmac_stats.tx_nopause_state++;
70206f45ec7bSml29623 			}
70216f45ec7bSml29623 		}
70224df3b64dSToomas Soome 	}
70236f45ec7bSml29623 
70246f45ec7bSml29623 	if (ldgp->nldvs == 1) {
70256f45ec7bSml29623 		(void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg,
70266f45ec7bSml29623 		    B_TRUE, ldgp->ldg_timer);
70276f45ec7bSml29623 	}
70286f45ec7bSml29623 
70296f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
70306f45ec7bSml29623 	return (DDI_INTR_CLAIMED);
70316f45ec7bSml29623 
70326f45ec7bSml29623 npi_fail:
70336f45ec7bSml29623 	NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
70346f45ec7bSml29623 	return (DDI_INTR_UNCLAIMED);
70356f45ec7bSml29623 }
70366f45ec7bSml29623 
70376f45ec7bSml29623 nxge_status_t
nxge_check_bcm8704_link(p_nxge_t nxgep,boolean_t * link_up)70386f45ec7bSml29623 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up)
70396f45ec7bSml29623 {
70406f45ec7bSml29623 	uint8_t		phy_port_addr;
70416f45ec7bSml29623 	nxge_status_t	status = NXGE_OK;
70426f45ec7bSml29623 	boolean_t	rx_sig_ok;
70436f45ec7bSml29623 	boolean_t	pcs_blk_lock;
70446f45ec7bSml29623 	boolean_t	link_align;
70456f45ec7bSml29623 	uint16_t	val1, val2, val3;
70466f45ec7bSml29623 #ifdef	NXGE_DEBUG_SYMBOL_ERR
70476f45ec7bSml29623 	uint16_t	val_debug;
70484df55fdeSJanie Lu 	uint32_t	val;
70496f45ec7bSml29623 #endif
70506f45ec7bSml29623 
70516f45ec7bSml29623 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
70526f45ec7bSml29623 
70536f45ec7bSml29623 #ifdef	NXGE_DEBUG_SYMBOL_ERR
70546f45ec7bSml29623 	/* Check Device 3 Register Device 3 0xC809 */
70556f45ec7bSml29623 	(void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug);
70566f45ec7bSml29623 	if ((val_debug & ~0x200) != 0) {
70576f45ec7bSml29623 		cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n",
70586f45ec7bSml29623 		    nxgep->mac.portnum, val_debug);
70596f45ec7bSml29623 		(void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18,
70606f45ec7bSml29623 		    &val_debug);
70616f45ec7bSml29623 		cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n",
70626f45ec7bSml29623 		    nxgep->mac.portnum, val_debug);
70636f45ec7bSml29623 	}
70646f45ec7bSml29623 
70656f45ec7bSml29623 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
70666f45ec7bSml29623 	    XPCS_REG_DESCWERR_COUNTER, &val);
70676f45ec7bSml29623 	if (val != 0)
70686f45ec7bSml29623 		cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val);
70696f45ec7bSml29623 
70706f45ec7bSml29623 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
70716f45ec7bSml29623 	    XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
70726f45ec7bSml29623 	if (val != 0)
70736f45ec7bSml29623 		cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val);
70746f45ec7bSml29623 
70756f45ec7bSml29623 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
70766f45ec7bSml29623 	    XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
70776f45ec7bSml29623 	if (val != 0)
70786f45ec7bSml29623 		cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val);
70796f45ec7bSml29623 #endif
70806f45ec7bSml29623 
70816f45ec7bSml29623 	/* Check from BCM8704 if 10G link is up or down */
70826f45ec7bSml29623 
70836f45ec7bSml29623 	/* 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);
70866f45ec7bSml29623 	if (status != NXGE_OK)
70876f45ec7bSml29623 		goto fail;
70886f45ec7bSml29623 	rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE);
70896f45ec7bSml29623 
70906f45ec7bSml29623 	/* 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)
70936f45ec7bSml29623 		goto fail;
70946f45ec7bSml29623 	pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE);
70956f45ec7bSml29623 
70966f45ec7bSml29623 	/* 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);
70996f45ec7bSml29623 	if (status != NXGE_OK)
71006f45ec7bSml29623 		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 |
71066f45ec7bSml29623 		    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 
71206f45ec7bSml29623 #ifdef	NXGE_DEBUG_ALIGN_ERR
71216f45ec7bSml29623 	/* Temp workaround for link down issue */
71226f45ec7bSml29623 	if (pcs_blk_lock == B_FALSE) {
71236f45ec7bSml29623 		if (val2 != 0x4) {
71246f45ec7bSml29623 			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);
71276f45ec7bSml29623 		}
71286f45ec7bSml29623 	}
71296f45ec7bSml29623 
71306f45ec7bSml29623 	if (link_align == B_FALSE) {
71316f45ec7bSml29623 		if (val3 != 0x140f) {
71326f45ec7bSml29623 			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);
71356f45ec7bSml29623 		}
71366f45ec7bSml29623 	}
71376f45ec7bSml29623 
71386f45ec7bSml29623 	if (rx_sig_ok == B_FALSE) {
71396f45ec7bSml29623 		if ((val2 == 0) || (val3 == 0)) {
71406f45ec7bSml29623 			rx_sig_ok = B_TRUE;
71416f45ec7bSml29623 			cmn_err(CE_NOTE,
71426f45ec7bSml29623 			    "!LINK DEBUG: port %d Dev3 or Dev4 read zero\n",
71436f45ec7bSml29623 			    nxgep->mac.portnum);
71446f45ec7bSml29623 		}
71456f45ec7bSml29623 	}
71466f45ec7bSml29623 #endif
71476f45ec7bSml29623 
71486f45ec7bSml29623 	*link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) &&
71496f45ec7bSml29623 	    (link_align == B_TRUE)) ? B_TRUE : B_FALSE;
71506f45ec7bSml29623 
71516f45ec7bSml29623 	return (NXGE_OK);
71526f45ec7bSml29623 fail:
71536f45ec7bSml29623 	return (status);
71546f45ec7bSml29623 }
71556f45ec7bSml29623 
715652cdd236Ssbehera static nxge_status_t
nxge_check_mrvl88x2011_link(p_nxge_t nxgep,boolean_t * link_up)715700161856Syc148097 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 
73426f45ec7bSml29623 nxge_status_t
nxge_10g_link_led_on(p_nxge_t nxgep)73436f45ec7bSml29623 nxge_10g_link_led_on(p_nxge_t nxgep)
73446f45ec7bSml29623 {
73456f45ec7bSml29623 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE)
73466f45ec7bSml29623 	    != NPI_SUCCESS)
73476f45ec7bSml29623 		return (NXGE_ERROR);
73486f45ec7bSml29623 	else
73496f45ec7bSml29623 		return (NXGE_OK);
73506f45ec7bSml29623 }
73516f45ec7bSml29623 
73526f45ec7bSml29623 nxge_status_t
nxge_10g_link_led_off(p_nxge_t nxgep)73536f45ec7bSml29623 nxge_10g_link_led_off(p_nxge_t nxgep)
73546f45ec7bSml29623 {
73556f45ec7bSml29623 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE)
73566f45ec7bSml29623 	    != NPI_SUCCESS)
73576f45ec7bSml29623 		return (NXGE_ERROR);
73586f45ec7bSml29623 	else
73596f45ec7bSml29623 		return (NXGE_OK);
73606f45ec7bSml29623 }
736156d930aeSspeer 
73622d17280bSsbehera 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;
738389282175SSantwona Behera 		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 
743989282175SSantwona Behera 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:
747800161856Syc148097 		for (i = 0; i < NUM_CLAUSE_45_IDS; i++) {
747900161856Syc148097 			if (((nxge_supported_cl45_ids[i] & BCM_PHY_ID_MASK) ==
748000161856Syc148097 			    (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:
748900161856Syc148097 		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;
749459ac0c16Sdavemq 			}
749559ac0c16Sdavemq 		}
749659ac0c16Sdavemq 		break;
749759ac0c16Sdavemq 	default:
749859ac0c16Sdavemq 		break;
749959ac0c16Sdavemq 	}
750059ac0c16Sdavemq 
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 
751900161856Syc148097 	/* 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.
759600161856Syc148097  *
759700161856Syc148097  * This function sets hw_p->xcvr_addr[i] for future MDIO access and set
759800161856Syc148097  * hw_p->niu_type for each nxge instance to figure out nxgep->mac.portmode
759900161856Syc148097  * in case the portmode information is not available via OBP, nxge.conf,
760000161856Syc148097  * 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;
761700161856Syc148097 	uint8_t		num_xaui;
761859ac0c16Sdavemq 	nxge_status_t	status = NXGE_OK;
761959ac0c16Sdavemq 
762059ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: "));
762159ac0c16Sdavemq 	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;
763359ac0c16Sdavemq 	/*
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.
763659ac0c16Sdavemq 	 */
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) {
764600161856Syc148097 				if ((pma_pmd_dev_id & TN1010_DEV_ID_MASK)
764700161856Syc148097 				    == TN1010_DEV_ID) {
764800161856Syc148097 					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;
765300161856Syc148097 				} else {
765400161856Syc148097 					port_pma_pmd_dev_id[j] =
765500161856Syc148097 					    pma_pmd_dev_id & BCM_PHY_ID_MASK;
765600161856Syc148097 				}
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) {
767100161856Syc148097 				if ((pcs_dev_id & TN1010_DEV_ID_MASK)
767200161856Syc148097 				    == TN1010_DEV_ID) {
767300161856Syc148097 					port_pcs_dev_id[j - 1] =
767400161856Syc148097 					    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;
767900161856Syc148097 				} else {
768000161856Syc148097 					port_pcs_dev_id[j - 1] =
768100161856Syc148097 					    pcs_dev_id &
768230505775Ssbehera 					    BCM_PHY_ID_MASK;
768300161856Syc148097 				}
768459a835ddSjoycey 			} else {
768559a835ddSjoycey 				if (j < NXGE_PORTS_NEPTUNE) {
768600161856Syc148097 					if ((pcs_dev_id & TN1010_DEV_ID_MASK)
768700161856Syc148097 					    == TN1010_DEV_ID) {
768800161856Syc148097 						port_pcs_dev_id[j] =
768900161856Syc148097 						    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;
769500161856Syc148097 					} else {
769600161856Syc148097 						port_pcs_dev_id[j] =
769700161856Syc148097 						    pcs_dev_id &
769859a835ddSjoycey 						    BCM_PHY_ID_MASK;
769900161856Syc148097 					}
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) {
771800161856Syc148097 				if ((phy_id & TN1010_DEV_ID_MASK)
771900161856Syc148097 				    == TN1010_DEV_ID) {
772000161856Syc148097 					port_phy_id[l] = TN1010_DEV_ID;
772100161856Syc148097 				} else {
772200161856Syc148097 					port_phy_id[l]
772300161856Syc148097 					    = phy_id & BCM_PHY_ID_MASK;
772400161856Syc148097 				}
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];
775359a835ddSjoycey 
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;
776259a835ddSjoycey 					hw_p->niu_type = NEPTUNE_2_10GF_2_1GRF;
776359a835ddSjoycey 
776459a835ddSjoycey 					hw_p->xcvr_addr[0] = port_fd_arr[0];
776559a835ddSjoycey 					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 				}
777123b952a3SSantwona Behera 
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,
777759ac0c16Sdavemq 				    "Unsupported neptune type 1"));
777859ac0c16Sdavemq 				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:
778800161856Syc148097 			/*
778900161856Syc148097 			 * 2 10G: 2XGF NIC, Marvell, Goa, Huron with 2 XAUI
779000161856Syc148097 			 * cards, etc.
779100161856Syc148097 			 */
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]) {
781000161856Syc148097 				case NEPTUNE_CLAUSE45_PORT_ADDR_BASE:
781152cdd236Ssbehera 					/*
781252cdd236Ssbehera 					 * The Marvell case also falls into
781352cdd236Ssbehera 					 * this case as
781452cdd236Ssbehera 					 * MRVL88X2011_NEPTUNE_PORT_ADDR_BASE
781500161856Syc148097 					 * == 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;
782200161856Syc148097 				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 				}
784000161856Syc148097 
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 
785800161856Syc148097 			/* Both XAUI slots have copper XAUI cards */
785900161856Syc148097 			} else if ((((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
786000161856Syc148097 			    == TN1010_DEV_ID) &&
786100161856Syc148097 			    ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
786200161856Syc148097 			    == TN1010_DEV_ID)) ||
786300161856Syc148097 			    (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
786400161856Syc148097 			    == TN1010_DEV_ID) &&
786500161856Syc148097 			    ((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK)
786600161856Syc148097 			    == TN1010_DEV_ID))) {
786700161856Syc148097 				hw_p->niu_type = NEPTUNE_2_TN1010;
786800161856Syc148097 				hw_p->xcvr_addr[0] = port_fd_arr[0];
786900161856Syc148097 				hw_p->xcvr_addr[1] = port_fd_arr[1];
787000161856Syc148097 
787100161856Syc148097 			/* Slot0 has fiber XAUI, slot1 has copper XAUI */
787200161856Syc148097 			} else if ((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
787300161856Syc148097 			    (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
787400161856Syc148097 			    == TN1010_DEV_ID) ||
787500161856Syc148097 			    (port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY &&
787600161856Syc148097 			    (port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK) ==
787700161856Syc148097 			    TN1010_DEV_ID)) {
787800161856Syc148097 				hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010;
787900161856Syc148097 				hw_p->xcvr_addr[0] = port_fd_arr[0];
788000161856Syc148097 				hw_p->xcvr_addr[1] = port_fd_arr[1];
788100161856Syc148097 
788200161856Syc148097 			/* Slot0 has copper XAUI, slot1 has fiber XAUI */
788300161856Syc148097 			} else if ((port_pcs_dev_id[1] == PHY_BCM8704_FAMILY &&
788400161856Syc148097 			    (port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
788500161856Syc148097 			    == TN1010_DEV_ID) ||
788600161856Syc148097 			    (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY &&
788700161856Syc148097 			    (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
788800161856Syc148097 			    == TN1010_DEV_ID)) {
788900161856Syc148097 				hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF;
789000161856Syc148097 				hw_p->xcvr_addr[0] = port_fd_arr[0];
789100161856Syc148097 				hw_p->xcvr_addr[1] = port_fd_arr[1];
789200161856Syc148097 
789359ac0c16Sdavemq 			} else {
789459ac0c16Sdavemq 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
789559ac0c16Sdavemq 				    "Unsupported neptune type 2"));
789659ac0c16Sdavemq 				goto error_exit;
789759ac0c16Sdavemq 			}
789859ac0c16Sdavemq 			break;
789900161856Syc148097 
790059ac0c16Sdavemq 		case 4:
790100161856Syc148097 			if (nxge_get_num_of_xaui(
790200161856Syc148097 			    port_pma_pmd_dev_id, port_pcs_dev_id,
790300161856Syc148097 			    port_phy_id, &num_xaui) == NXGE_ERROR) {
790400161856Syc148097 				goto error_exit;
790500161856Syc148097 			}
790600161856Syc148097 			if (num_xaui != 2)
790700161856Syc148097 				goto error_exit;
790859ac0c16Sdavemq 
790959ac0c16Sdavemq 			/*
791000161856Syc148097 			 *  Maramba with 2 XAUIs (either fiber or copper)
791100161856Syc148097 			 *
791259ac0c16Sdavemq 			 * Check the first phy port address against
791359ac0c16Sdavemq 			 * the known phy start addresses to determine
791459ac0c16Sdavemq 			 * the platform type.
791559ac0c16Sdavemq 			 */
79162d17280bSsbehera 			switch (phy_fd_arr[0]) {
791700161856Syc148097 			case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE:
791859ac0c16Sdavemq 				hw_p->platform_type =
791959ac0c16Sdavemq 				    P_NEPTUNE_MARAMBA_P0;
79202d17280bSsbehera 				break;
792100161856Syc148097 			case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
792259ac0c16Sdavemq 				hw_p->platform_type =
792359ac0c16Sdavemq 				    P_NEPTUNE_MARAMBA_P1;
79242d17280bSsbehera 				break;
79252d17280bSsbehera 			default:
792659ac0c16Sdavemq 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
792759ac0c16Sdavemq 				    "Unknown port %d...Cannot "
792859ac0c16Sdavemq 				    "determine platform type", i));
79292e59129aSraghus 				goto error_exit;
793059ac0c16Sdavemq 			}
79312d17280bSsbehera 
79322d17280bSsbehera 			hw_p->xcvr_addr[0] = port_fd_arr[0];
79332d17280bSsbehera 			hw_p->xcvr_addr[1] = port_fd_arr[1];
79342d17280bSsbehera 			hw_p->xcvr_addr[2] = phy_fd_arr[2];
79352d17280bSsbehera 			hw_p->xcvr_addr[3] = phy_fd_arr[3];
79362d17280bSsbehera 
793700161856Syc148097 			/* slot0 has fiber XAUI, slot1 has Cu XAUI */
793800161856Syc148097 			if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
793900161856Syc148097 			    (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
794000161856Syc148097 			    == TN1010_DEV_ID) {
794100161856Syc148097 				hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010_2_1GC;
794200161856Syc148097 
794300161856Syc148097 			/* slot0 has Cu XAUI, slot1 has fiber XAUI */
794400161856Syc148097 			} else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
794500161856Syc148097 			    == TN1010_DEV_ID) &&
794600161856Syc148097 			    port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) {
794700161856Syc148097 				hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF_2_1GC;
794800161856Syc148097 
794900161856Syc148097 			/* Both slots have fiber XAUI */
795000161856Syc148097 			} else if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
795100161856Syc148097 			    port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) {
795200161856Syc148097 				hw_p->niu_type = NEPTUNE_2_10GF_2_1GC;
795300161856Syc148097 
795400161856Syc148097 			/* Both slots have copper XAUI */
795500161856Syc148097 			} else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
795600161856Syc148097 			    == TN1010_DEV_ID) &&
795700161856Syc148097 			    (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
795800161856Syc148097 			    == TN1010_DEV_ID) {
795900161856Syc148097 				hw_p->niu_type = NEPTUNE_2_TN1010_2_1GC;
796000161856Syc148097 
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;
797300161856Syc148097 	case 1:		/* Only one clause45 port */
797400161856Syc148097 		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 			 */
798159ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
798259ac0c16Sdavemq 			    "Unsupported neptune type 7"));
798359ac0c16Sdavemq 			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;
800200161856Syc148097 		case 0:	/* N2 with 1 XAUI (fiber or copper) */
800300161856Syc148097 			/* 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]) {
801400161856Syc148097 				case N2_CLAUSE45_PORT_ADDR_BASE:
801500161856Syc148097 				case (N2_CLAUSE45_PORT_ADDR_BASE + 1):
801600161856Syc148097 				case ALT_GOA_CLAUSE45_PORT1_ADDR:
801700161856Syc148097 					/*
801800161856Syc148097 					 * If hw_p->platform_type ==
801900161856Syc148097 					 * P_NEPTUNE_NIU, then portmode
802000161856Syc148097 					 * is already known, so there is
802100161856Syc148097 					 * no need to figure out hw_p->
802200161856Syc148097 					 * platform_type because
802300161856Syc148097 					 * platform_type is only for
802400161856Syc148097 					 * figuring out portmode.
802500161856Syc148097 					 */
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,
803659ac0c16Sdavemq 					    "Unsupported neptune type 10"));
803759ac0c16Sdavemq 					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] ==
805200161856Syc148097 				    ALT_GOA_CLAUSE45_PORT1_ADDR) {
8053321febdeSsbehera 					hw_p->xcvr_addr[1] = port_fd_arr[0];
8054321febdeSsbehera 				} else {
80554202ea4bSsbehera 					hw_p->xcvr_addr[nxgep->function_num] =
80564202ea4bSsbehera 					    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]));
811400161856Syc148097 
811500161856Syc148097 			/* A 10G copper XAUI in either slot0 or slot1 */
811600161856Syc148097 			} else if ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
811700161856Syc148097 			    == TN1010_DEV_ID ||
811800161856Syc148097 			    (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
811900161856Syc148097 			    == TN1010_DEV_ID) {
812000161856Syc148097 				switch (port_fd_arr[0]) {
812100161856Syc148097 				/* The XAUI is in slot0 */
812200161856Syc148097 				case N2_CLAUSE45_PORT_ADDR_BASE:
812300161856Syc148097 					hw_p->niu_type = NEPTUNE_1_TN1010;
812400161856Syc148097 					break;
812500161856Syc148097 
812600161856Syc148097 				/* The XAUI is in slot1 */
812700161856Syc148097 				case (N2_CLAUSE45_PORT_ADDR_BASE + 1):
812800161856Syc148097 					hw_p->niu_type
812900161856Syc148097 					    = NEPTUNE_1_NONE_1_TN1010;
813000161856Syc148097 					break;
813100161856Syc148097 				default:
813200161856Syc148097 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
813300161856Syc148097 					    "Unsupported XAUI port address"));
813400161856Syc148097 					goto error_exit;
813500161856Syc148097 				}
813600161856Syc148097 				hw_p->xcvr_addr[nxgep->function_num]
813700161856Syc148097 				    = port_fd_arr[0];
813800161856Syc148097 
81392d17280bSsbehera 			} else {
81402d17280bSsbehera 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
814100161856Syc148097 				    "Unsupported PHY type"));
81422d17280bSsbehera 				goto error_exit;
81432d17280bSsbehera 			}
81442d17280bSsbehera 			break;
814500161856Syc148097 		case 4: /* Maramba always have 4 clause 45 ports */
814659ac0c16Sdavemq 
814700161856Syc148097 			/* Maramba with 1 XAUI */
814852ccf843Smisaki 			if ((port_pcs_dev_id[0] != PHY_BCM8704_FAMILY) &&
814952ccf843Smisaki 			    (port_pma_pmd_dev_id[0] != PHY_BCM8704_FAMILY) &&
815000161856Syc148097 			    ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
815152ccf843Smisaki 			    != TN1010_DEV_ID) &&
815200161856Syc148097 			    ((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 			}
815852ccf843Smisaki 
815959ac0c16Sdavemq 			/*
816059ac0c16Sdavemq 			 * Check the first phy port address against
816159ac0c16Sdavemq 			 * the known phy start addresses to determine
816259ac0c16Sdavemq 			 * the platform type.
816359ac0c16Sdavemq 			 */
81642d17280bSsbehera 			switch (phy_fd_arr[0]) {
816500161856Syc148097 			case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE:
816659ac0c16Sdavemq 				hw_p->platform_type =
816759ac0c16Sdavemq 				    P_NEPTUNE_MARAMBA_P0;
81682d17280bSsbehera 				break;
816900161856Syc148097 			case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
817059ac0c16Sdavemq 				hw_p->platform_type =
817159ac0c16Sdavemq 				    P_NEPTUNE_MARAMBA_P1;
81722d17280bSsbehera 				break;
81732d17280bSsbehera 			default:
817459ac0c16Sdavemq 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
817559ac0c16Sdavemq 				    "Unknown port %d...Cannot "
81762d17280bSsbehera 				    "determine platform type 10 - 2",
81772d17280bSsbehera 				    i));
81782e59129aSraghus 				goto error_exit;
81792e59129aSraghus 			}
81802e59129aSraghus 
81812d17280bSsbehera 			/*
818200161856Syc148097 			 * Check the clause45 address to determine
81832d17280bSsbehera 			 * if XAUI is in port 0 or port 1.
81842d17280bSsbehera 			 */
81852d17280bSsbehera 			switch (port_fd_arr[0]) {
818600161856Syc148097 			case MARAMBA_CLAUSE45_PORT_ADDR_BASE:
818700161856Syc148097 				if (port_pcs_dev_id[0]
818800161856Syc148097 				    == PHY_BCM8704_FAMILY ||
818900161856Syc148097 				    port_pma_pmd_dev_id[0]
819000161856Syc148097 				    == PHY_BCM8704_FAMILY) {
819100161856Syc148097 					hw_p->niu_type
819200161856Syc148097 					    = NEPTUNE_1_10GF_3_1GC;
819300161856Syc148097 				} else {
819400161856Syc148097 					hw_p->niu_type
819500161856Syc148097 					    = NEPTUNE_1_TN1010_3_1GC;
819600161856Syc148097 				}
81972d17280bSsbehera 				hw_p->xcvr_addr[0] = port_fd_arr[0];
81982d17280bSsbehera 				for (i = 1; i < NXGE_MAX_PORTS; i++) {
81992d17280bSsbehera 					hw_p->xcvr_addr[i] =
82002d17280bSsbehera 					    phy_fd_arr[i];
82012d17280bSsbehera 				}
82022d17280bSsbehera 				break;
820300161856Syc148097 			case (MARAMBA_CLAUSE45_PORT_ADDR_BASE + 1):
820400161856Syc148097 				if (port_pcs_dev_id[0]
820500161856Syc148097 				    == PHY_BCM8704_FAMILY ||
820600161856Syc148097 				    port_pma_pmd_dev_id[0]
820700161856Syc148097 				    == PHY_BCM8704_FAMILY) {
82082e59129aSraghus 					hw_p->niu_type =
82092e59129aSraghus 					    NEPTUNE_1_1GC_1_10GF_2_1GC;
821000161856Syc148097 				} else {
821100161856Syc148097 					hw_p->niu_type =
821200161856Syc148097 					    NEPTUNE_1_1GC_1_TN1010_2_1GC;
821300161856Syc148097 				}
82142d17280bSsbehera 				hw_p->xcvr_addr[0] = phy_fd_arr[0];
82152d17280bSsbehera 				hw_p->xcvr_addr[1] = port_fd_arr[0];
82162d17280bSsbehera 				hw_p->xcvr_addr[2] = phy_fd_arr[2];
82172d17280bSsbehera 				hw_p->xcvr_addr[3] = phy_fd_arr[3];
82182d17280bSsbehera 				break;
82192d17280bSsbehera 			default:
82202e59129aSraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
82212e59129aSraghus 				    "Unsupported neptune type 11"));
82222e59129aSraghus 				goto error_exit;
822359ac0c16Sdavemq 			}
822459ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
822500161856Syc148097 			    "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;
823300161856Syc148097 	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]) {
824700161856Syc148097 				case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
824859ac0c16Sdavemq 					hw_p->platform_type =
824959ac0c16Sdavemq 					    P_NEPTUNE_MARAMBA_P1;
82502d17280bSsbehera 					break;
825100161856Syc148097 				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,
828659ac0c16Sdavemq 				    "Unsupported neptune type 16"));
828759ac0c16Sdavemq 				goto error_exit;
828859a835ddSjoycey 			}
828959a835ddSjoycey 			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:
830659ac0c16Sdavemq 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
830759ac0c16Sdavemq 		    "Unsupported neptune type 19"));
830859ac0c16Sdavemq 		goto error_exit;
830959ac0c16Sdavemq 	}
831059ac0c16Sdavemq 
831159ac0c16Sdavemq scan_exit:
831259ac0c16Sdavemq 
831359ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, "
831459ac0c16Sdavemq 	    "niu type [0x%x]\n", hw_p->niu_type));
831559ac0c16Sdavemq 	return (status);
831659ac0c16Sdavemq 
831759ac0c16Sdavemq error_exit:
831859ac0c16Sdavemq 	return (NXGE_ERROR);
831959ac0c16Sdavemq }
832059ac0c16Sdavemq 
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:
834400161856Syc148097 		xcvr_portn = MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE;
8345*e3d11eeeSToomas Soome 		break;
8346*e3d11eeeSToomas Soome 	case P_NEPTUNE_MARAMBA_P0:
834700161856Syc148097 		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 
84431bd6825cSml29623 nxge_status_t
nxge_mac_set_framesize(p_nxge_t nxgep)84441bd6825cSml29623 nxge_mac_set_framesize(p_nxge_t nxgep)
84451bd6825cSml29623 {
84461bd6825cSml29623 	npi_attr_t		ap;
84471bd6825cSml29623 	uint8_t			portn;
84481bd6825cSml29623 	npi_handle_t		handle;
84491bd6825cSml29623 	npi_status_t		rs = NPI_SUCCESS;
84501bd6825cSml29623 
84511bd6825cSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_set_framesize"));
84521bd6825cSml29623 
84531bd6825cSml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
84541bd6825cSml29623 	handle = nxgep->npi_handle;
84551bd6825cSml29623 
84561bd6825cSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84571bd6825cSml29623 	    "==> nxge_mac_sec_framesize: port<%d> "
84581bd6825cSml29623 	    "min framesize %d max framesize %d ",
84591bd6825cSml29623 	    portn,
84601bd6825cSml29623 	    nxgep->mac.minframesize,
84611bd6825cSml29623 	    nxgep->mac.maxframesize));
84621bd6825cSml29623 
84631bd6825cSml29623 	SET_MAC_ATTR2(handle, ap, portn,
84641bd6825cSml29623 	    MAC_PORT_FRAME_SIZE,
84651bd6825cSml29623 	    nxgep->mac.minframesize,
84661bd6825cSml29623 	    nxgep->mac.maxframesize,
84671bd6825cSml29623 	    rs);
84681bd6825cSml29623 	if (rs != NPI_SUCCESS) {
84691bd6825cSml29623 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84701bd6825cSml29623 		    "<== nxge_mac_set_framesize: failed to configure "
84711bd6825cSml29623 		    "max/min frame size port %d", portn));
84721bd6825cSml29623 
84731bd6825cSml29623 		return (NXGE_ERROR | rs);
84741bd6825cSml29623 	}
84751bd6825cSml29623 
84761bd6825cSml29623 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
84771bd6825cSml29623 	    "<== nxge_mac_set_framesize: port<%d>", portn));
84781bd6825cSml29623 
84791bd6825cSml29623 	return (NXGE_OK);
84801bd6825cSml29623 }
84811bd6825cSml29623 
848200161856Syc148097 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)848300161856Syc148097 nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id,
848400161856Syc148097     uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui)
848500161856Syc148097 {
848600161856Syc148097 	uint8_t i;
848700161856Syc148097 
848800161856Syc148097 	for (i = 0; i < 4; i++) {
848900161856Syc148097 		if (port_phy_id[i] != PHY_BCM5464R_FAMILY)
849000161856Syc148097 			return (NXGE_ERROR);
849100161856Syc148097 	}
849200161856Syc148097 
849300161856Syc148097 	*num_xaui = 0;
849400161856Syc148097 	if ((port_pma_pmd_dev_id[0]  == PHY_BCM8704_FAMILY &&
849500161856Syc148097 	    port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) ||
849600161856Syc148097 	    (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
849700161856Syc148097 	    == TN1010_DEV_ID) &&
849800161856Syc148097 	    ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
849900161856Syc148097 	    == TN1010_DEV_ID))) {
850000161856Syc148097 		(*num_xaui) ++;
850100161856Syc148097 	}
850200161856Syc148097 	if ((port_pma_pmd_dev_id[1]  == PHY_BCM8704_FAMILY &&
850300161856Syc148097 	    port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) ||
850400161856Syc148097 	    (((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK)
850500161856Syc148097 	    == TN1010_DEV_ID) &&
850600161856Syc148097 	    ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
850700161856Syc148097 	    == TN1010_DEV_ID))) {
850800161856Syc148097 		(*num_xaui) ++;
850900161856Syc148097 	}
851000161856Syc148097 	return (NXGE_OK);
851100161856Syc148097 }
851200161856Syc148097 
851300161856Syc148097 /*
851400161856Syc148097  * Instruction from Teranetics:  Once you detect link is up, go
851500161856Syc148097  * read Reg 30.1.4 for link speed: '1' for 1G and '0' for 10G. You
851600161856Syc148097  * may want to qualify it by first checking Register 30.1.7:6 and
851700161856Syc148097  * making sure it reads "01" (Auto-Neg Complete).
851800161856Syc148097  *
851900161856Syc148097  * If this function is called when the link is down or before auto-
852000161856Syc148097  * negotiation has completed, then the speed of the PHY is not certain.
852100161856Syc148097  * In such cases, this function returns 1G as the default speed with
852200161856Syc148097  * NXGE_OK status instead of NXGE_ERROR.  It is OK to initialize the
852300161856Syc148097  * driver based on a default speed because this function will be called
852400161856Syc148097  * again when the link comes up.  Returning NXGE_ERROR, which may
852500161856Syc148097  * cause brutal chain reaction in caller functions, is not necessary.
852600161856Syc148097  */
852700161856Syc148097 static nxge_status_t
nxge_get_tn1010_speed(p_nxge_t nxgep,uint16_t * speed)852800161856Syc148097 nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed)
852900161856Syc148097 {
853000161856Syc148097 	uint8_t		phy_port_addr, autoneg_stat, link_up;
853100161856Syc148097 	nxge_status_t	status = NXGE_OK;
853200161856Syc148097 	uint16_t	val;
853300161856Syc148097 	uint8_t		portn = NXGE_GET_PORT_NUM(nxgep->function_num);
853400161856Syc148097 
853500161856Syc148097 	/* Set default speed to 10G */
853600161856Syc148097 	*speed = TN1010_SPEED_10G;
853700161856Syc148097 
853800161856Syc148097 	/* Set Clause 45 */
853900161856Syc148097 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
854000161856Syc148097 
854100161856Syc148097 	phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
854200161856Syc148097 
854300161856Syc148097 	/* Check Device 1 Register 0xA bit0 for link up status */
854400161856Syc148097 	status = nxge_mdio_read(nxgep, phy_port_addr,
854500161856Syc148097 	    TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val);
854600161856Syc148097 	if (status != NXGE_OK)
854700161856Syc148097 		goto fail;
854800161856Syc148097 
854900161856Syc148097 	link_up = ((val & TN1010_AN_LINK_STAT_BIT)
855000161856Syc148097 	    ? B_TRUE : B_FALSE);
855100161856Syc148097 	if (link_up == B_FALSE) {
855200161856Syc148097 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
855300161856Syc148097 		    "nxge_get_tn1010_speed: link is down"));
855400161856Syc148097 		goto nxge_get_tn1010_speed_exit;
855500161856Syc148097 	}
855600161856Syc148097 
855700161856Syc148097 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
855800161856Syc148097 	    TN1010_VENDOR_MMD1_DEV_ADDR, TN1010_VENDOR_MMD1_STATUS_REG,
855900161856Syc148097 	    &val)) != NXGE_OK) {
856000161856Syc148097 		goto fail;
856100161856Syc148097 	}
856200161856Syc148097 	autoneg_stat = (val & TN1010_VENDOR_MMD1_AN_STAT_BITS) >>
856300161856Syc148097 	    TN1010_VENDOR_MMD1_AN_STAT_SHIFT;
856400161856Syc148097 
856500161856Syc148097 	/*
856600161856Syc148097 	 * Return NXGE_OK even when we can not get a settled speed. In
856700161856Syc148097 	 * such case, the speed reported should not be trusted but that
856800161856Syc148097 	 * is OK, we will call this function periodically and will get
856900161856Syc148097 	 * the correct speed after the link is up.
857000161856Syc148097 	 */
857100161856Syc148097 	switch (autoneg_stat) {
857200161856Syc148097 	case TN1010_AN_IN_PROG:
857300161856Syc148097 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
857400161856Syc148097 		    "nxge_get_tn1010_speed: Auto-negotiation in progress"));
857500161856Syc148097 		break;
857600161856Syc148097 	case TN1010_AN_COMPLETE:
857700161856Syc148097 		if ((status = nxge_mdio_read(nxgep, phy_port_addr,
857800161856Syc148097 		    TN1010_VENDOR_MMD1_DEV_ADDR,
857900161856Syc148097 		    TN1010_VENDOR_MMD1_STATUS_REG,
858000161856Syc148097 		    &val)) != NXGE_OK) {
858100161856Syc148097 			goto fail;
858200161856Syc148097 		}
858300161856Syc148097 		*speed = (val & TN1010_VENDOR_MMD1_AN_SPEED_BIT) >>
858400161856Syc148097 		    TN1010_VENDOR_MMD1_AN_SPEED_SHIFT;
858500161856Syc148097 		break;
858600161856Syc148097 	case TN1010_AN_RSVD:
858700161856Syc148097 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
858800161856Syc148097 		    "nxge_get_tn1010_speed: Autoneg status undefined"));
858900161856Syc148097 		break;
859000161856Syc148097 	case TN1010_AN_FAILED:
859100161856Syc148097 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
859200161856Syc148097 		    "nxge_get_tn1010_speed: Auto-negotiation failed"));
859300161856Syc148097 		break;
859400161856Syc148097 	default:
859500161856Syc148097 		break;
859600161856Syc148097 	}
859700161856Syc148097 nxge_get_tn1010_speed_exit:
859800161856Syc148097 	return (NXGE_OK);
859900161856Syc148097 fail:
860000161856Syc148097 	return (status);
860100161856Syc148097 }
860200161856Syc148097 
860300161856Syc148097 
860400161856Syc148097 /*
860500161856Syc148097  * Teranetics TN1010 PHY chip supports both 1G and 10G modes, this function
860600161856Syc148097  * figures out the speed of the PHY determined by the autonegotiation
860700161856Syc148097  * process and sets the following 3 parameters,
860800161856Syc148097  *	nxgep->mac.portmode
860900161856Syc148097  *	nxgep->statsp->mac_stats.link_speed
861000161856Syc148097  *	nxgep->statsp->mac_stats.xcvr_inuse
861100161856Syc148097  */
861200161856Syc148097 static nxge_status_t
nxge_set_tn1010_param(p_nxge_t nxgep)861300161856Syc148097 nxge_set_tn1010_param(p_nxge_t nxgep)
861400161856Syc148097 {
861500161856Syc148097 	uint16_t speed;
861600161856Syc148097 
861700161856Syc148097 	if (nxge_get_tn1010_speed(nxgep,  &speed) != NXGE_OK) {
861800161856Syc148097 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
861900161856Syc148097 		    "nxge_set_tn1010_param: "
862000161856Syc148097 		    "Failed to get TN1010 speed"));
862100161856Syc148097 		return (NXGE_ERROR);
862200161856Syc148097 	}
862300161856Syc148097 	if (speed == TN1010_SPEED_1G) {
862400161856Syc148097 		nxgep->mac.portmode = PORT_1G_TN1010;
862500161856Syc148097 		nxgep->statsp->mac_stats.link_speed = 1000;
862600161856Syc148097 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
862700161856Syc148097 	} else {
862800161856Syc148097 		nxgep->mac.portmode = PORT_10G_TN1010;
862900161856Syc148097 		nxgep->statsp->mac_stats.link_speed = 10000;
863000161856Syc148097 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
863100161856Syc148097 	}
863200161856Syc148097 	return (NXGE_OK);
863300161856Syc148097 }
863400161856Syc148097 
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