xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_mac.c (revision 86ef0a63)
144961713Sgirish /*
244961713Sgirish  * CDDL HEADER START
344961713Sgirish  *
444961713Sgirish  * The contents of this file are subject to the terms of the
544961713Sgirish  * Common Development and Distribution License (the "License").
644961713Sgirish  * You may not use this file except in compliance with the License.
744961713Sgirish  *
844961713Sgirish  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
944961713Sgirish  * or http://www.opensolaris.org/os/licensing.
1044961713Sgirish  * See the License for the specific language governing permissions
1144961713Sgirish  * and limitations under the License.
1244961713Sgirish  *
1344961713Sgirish  * When distributing Covered Code, include this CDDL HEADER in each
1444961713Sgirish  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1544961713Sgirish  * If applicable, add the following below this CDDL HEADER, with the
1644961713Sgirish  * fields enclosed by brackets "[]" replaced with your own identifying
1744961713Sgirish  * information: Portions Copyright [yyyy] [name of copyright owner]
1844961713Sgirish  *
1944961713Sgirish  * CDDL HEADER END
2044961713Sgirish  */
2144961713Sgirish /*
2289282175SSantwona Behera  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
2344961713Sgirish  */
2444961713Sgirish 
2544961713Sgirish #include <sys/nxge/nxge_impl.h>
2644961713Sgirish #include <sys/nxge/nxge_mac.h>
27678453a8Sspeer #include <sys/nxge/nxge_hio.h>
2844961713Sgirish 
2998ecde52Stm #define	LINK_MONITOR_PERIOD	(1000 * 1000)
3098ecde52Stm #define	LM_WAIT_MULTIPLIER	8
3198ecde52Stm 
32321febdeSsbehera #define	SERDES_RDY_WT_INTERVAL	50
33321febdeSsbehera #define	MAX_SERDES_RDY_RETRIES	10
34321febdeSsbehera 
3500161856Syc #define	TN1010_SPEED_1G		1
3600161856Syc #define	TN1010_SPEED_10G	0
3700161856Syc #define	TN1010_AN_IN_PROG	0	/* Auto negotiation in progress */
3800161856Syc #define	TN1010_AN_COMPLETE	1
3900161856Syc #define	TN1010_AN_RSVD		2
4000161856Syc #define	TN1010_AN_FAILED	3
4100161856Syc 
4244961713Sgirish extern uint32_t nxge_no_link_notify;
4359ac0c16Sdavemq extern boolean_t nxge_no_msg;
4444961713Sgirish extern uint32_t nxge_lb_dbg;
454202ea4bSsbehera extern uint32_t nxge_jumbo_mtu;
4644961713Sgirish 
4798ecde52Stm typedef enum {
4898ecde52Stm 	CHECK_LINK_RESCHEDULE,
4998ecde52Stm 	CHECK_LINK_STOP
5098ecde52Stm } check_link_state_t;
5198ecde52Stm 
5298ecde52Stm static check_link_state_t nxge_check_link_stop(nxge_t *);
5398ecde52Stm 
5444961713Sgirish /*
5544961713Sgirish  * Ethernet broadcast address definition.
5644961713Sgirish  */
5744961713Sgirish static ether_addr_st etherbroadcastaddr =
5844961713Sgirish 				{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
5959ac0c16Sdavemq /*
6059ac0c16Sdavemq  * Ethernet zero address definition.
6159ac0c16Sdavemq  */
6256d930aeSspeer static ether_addr_st etherzeroaddr =
6356d930aeSspeer 				{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
6459ac0c16Sdavemq /*
6559ac0c16Sdavemq  * Supported chip types
6659ac0c16Sdavemq  */
6752cdd236Ssbehera static uint32_t nxge_supported_cl45_ids[] = {
6852cdd236Ssbehera 	BCM8704_DEV_ID,
6952cdd236Ssbehera 	MARVELL_88X_201X_DEV_ID,
7000161856Syc 	BCM8706_DEV_ID,
7100161856Syc 	TN1010_DEV_ID
7252cdd236Ssbehera };
7352cdd236Ssbehera 
74b1000363Sml static uint32_t nxge_supported_cl22_ids[] = {
75b1000363Sml     BCM5464R_PHY_ID,
76b1000363Sml     BCM5482_PHY_ID
77b1000363Sml };
7859ac0c16Sdavemq 
7959ac0c16Sdavemq #define	NUM_CLAUSE_45_IDS	(sizeof (nxge_supported_cl45_ids) /	\
8059ac0c16Sdavemq 				sizeof (uint32_t))
8159ac0c16Sdavemq #define	NUM_CLAUSE_22_IDS	(sizeof (nxge_supported_cl22_ids) /	\
8259ac0c16Sdavemq 				sizeof (uint32_t))
8359ac0c16Sdavemq /*
8459ac0c16Sdavemq  * static functions
8559ac0c16Sdavemq  */
862e59129aSraghus static uint32_t nxge_get_cl45_pma_pmd_id(p_nxge_t, int);
872e59129aSraghus static uint32_t nxge_get_cl45_pcs_id(p_nxge_t, int);
882e59129aSraghus static uint32_t nxge_get_cl22_phy_id(p_nxge_t, int);
8959ac0c16Sdavemq static boolean_t nxge_is_supported_phy(uint32_t, uint8_t);
9089282175SSantwona Behera static boolean_t nxge_hswap_phy_present(p_nxge_t, uint8_t);
912d17280bSsbehera static boolean_t nxge_is_phy_present(p_nxge_t, int, uint32_t, uint32_t);
9259ac0c16Sdavemq static nxge_status_t nxge_n2_serdes_init(p_nxge_t);
934df55fdeSJanie Lu static nxge_status_t nxge_n2_kt_serdes_init(p_nxge_t);
9459ac0c16Sdavemq static nxge_status_t nxge_neptune_10G_serdes_init(p_nxge_t);
9559ac0c16Sdavemq static nxge_status_t nxge_1G_serdes_init(p_nxge_t);
9659ac0c16Sdavemq static nxge_status_t nxge_10G_link_intr_stop(p_nxge_t);
9759ac0c16Sdavemq static nxge_status_t nxge_10G_link_intr_start(p_nxge_t);
9859ac0c16Sdavemq static nxge_status_t nxge_1G_copper_link_intr_stop(p_nxge_t);
9959ac0c16Sdavemq static nxge_status_t nxge_1G_copper_link_intr_start(p_nxge_t);
10059ac0c16Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_stop(p_nxge_t);
10159ac0c16Sdavemq static nxge_status_t nxge_1G_fiber_link_intr_start(p_nxge_t);
10259ac0c16Sdavemq static nxge_status_t nxge_check_mii_link(p_nxge_t);
10359ac0c16Sdavemq static nxge_status_t nxge_check_10g_link(p_nxge_t);
10459ac0c16Sdavemq static nxge_status_t nxge_10G_xcvr_init(p_nxge_t);
1052d17280bSsbehera static nxge_status_t nxge_BCM8704_xcvr_init(p_nxge_t);
1062d17280bSsbehera static nxge_status_t nxge_BCM8706_xcvr_init(p_nxge_t);
10759ac0c16Sdavemq static nxge_status_t nxge_1G_xcvr_init(p_nxge_t);
10859ac0c16Sdavemq static void nxge_bcm5464_link_led_off(p_nxge_t);
10900161856Syc static nxge_status_t nxge_check_mrvl88x2011_link(p_nxge_t, boolean_t *);
11052cdd236Ssbehera static nxge_status_t nxge_mrvl88x2011_xcvr_init(p_nxge_t);
11189282175SSantwona Behera static nxge_status_t nxge_check_nlp2020_link(p_nxge_t, boolean_t *);
11289282175SSantwona Behera static nxge_status_t nxge_nlp2020_xcvr_init(p_nxge_t);
11389282175SSantwona Behera static int nxge_nlp2020_i2c_read(p_nxge_t, uint8_t, uint16_t, uint16_t,
11489282175SSantwona Behera 	    uint8_t *);
11589282175SSantwona Behera static boolean_t nxge_is_nlp2020_phy(p_nxge_t);
11689282175SSantwona Behera static uint8_t nxge_get_nlp2020_connector_type(p_nxge_t);
11789282175SSantwona Behera static nxge_status_t nxge_set_nlp2020_param(p_nxge_t);
11800161856Syc static nxge_status_t nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id,
11900161856Syc 	uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui);
12000161856Syc static nxge_status_t nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed);
12100161856Syc static nxge_status_t nxge_set_tn1010_param(p_nxge_t nxgep);
12200161856Syc static nxge_status_t nxge_tn1010_check(p_nxge_t nxgep,
12300161856Syc 	nxge_link_state_t *link_up);
12400161856Syc static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep);
12500161856Syc static nxge_status_t nxge_tn1010_xcvr_init(p_nxge_t nxgep);
12600161856Syc 
12700161856Syc nxge_status_t nxge_mac_init(p_nxge_t);
12800161856Syc static nxge_status_t nxge_mii_get_link_mode(p_nxge_t);
12900161856Syc 
13000161856Syc #ifdef NXGE_DEBUG
13100161856Syc static void nxge_mii_dump(p_nxge_t);
13200161856Syc static nxge_status_t nxge_tn1010_reset(p_nxge_t nxgep);
13300161856Syc static void nxge_dump_tn1010_status_regs(p_nxge_t nxgep);
13400161856Syc #endif
13559ac0c16Sdavemq 
13659ac0c16Sdavemq /*
13759ac0c16Sdavemq  * xcvr tables for supported transceivers
13859ac0c16Sdavemq  */
13959ac0c16Sdavemq 
14000161856Syc /*
14100161856Syc  * nxge_n2_10G_table is for 10G fiber or serdes on N2-NIU systems.
14200161856Syc  * The Teranetics TN1010 based copper XAUI card can also be used
14300161856Syc  * on N2-NIU systems in 10G mode, but it uses its own table
14400161856Syc  * nxge_n2_10G_tn1010_table below.
14500161856Syc  */
1462e59129aSraghus static nxge_xcvr_table_t nxge_n2_10G_table = {
14759ac0c16Sdavemq 	nxge_n2_serdes_init,
14859ac0c16Sdavemq 	nxge_10G_xcvr_init,
14959ac0c16Sdavemq 	nxge_10G_link_intr_stop,
15059ac0c16Sdavemq 	nxge_10G_link_intr_start,
15159ac0c16Sdavemq 	nxge_check_10g_link,
1522d17280bSsbehera 	PCS_XCVR
15359ac0c16Sdavemq };
15459ac0c16Sdavemq 
15500161856Syc /*
15600161856Syc  * For the Teranetics TN1010 based copper XAUI card
15700161856Syc  */
15800161856Syc static nxge_xcvr_table_t nxge_n2_10G_tn1010_table = {
15900161856Syc 	nxge_n2_serdes_init,		/* Handle both 1G and 10G */
16000161856Syc 	nxge_tn1010_xcvr_init,		/* Handle both 1G and 10G */
16100161856Syc 	nxge_10G_link_intr_stop,
16200161856Syc 	nxge_10G_link_intr_start,
16300161856Syc 	nxge_check_tn1010_link,		/* Will figure out speed */
16400161856Syc 	XPCS_XCVR
16500161856Syc };
16600161856Syc 
1672e59129aSraghus static nxge_xcvr_table_t nxge_n2_1G_table = {
1682e59129aSraghus 	nxge_n2_serdes_init,
1692e59129aSraghus 	nxge_1G_xcvr_init,
1702e59129aSraghus 	nxge_1G_fiber_link_intr_stop,
1712e59129aSraghus 	nxge_1G_fiber_link_intr_start,
1722e59129aSraghus 	nxge_check_mii_link,
1732d17280bSsbehera 	PCS_XCVR
1742e59129aSraghus };
1752e59129aSraghus 
17600161856Syc static nxge_xcvr_table_t nxge_n2_1G_tn1010_table = {
17700161856Syc 	nxge_n2_serdes_init,
17800161856Syc 	nxge_tn1010_xcvr_init,
17900161856Syc 	nxge_1G_fiber_link_intr_stop,	/* TN1010 is a Cu PHY, but it uses */
18000161856Syc 	nxge_1G_fiber_link_intr_start,	/* PCS for 1G, so call fiber func */
18100161856Syc 	nxge_check_tn1010_link,
18200161856Syc 	PCS_XCVR
18300161856Syc };
18400161856Syc 
18500161856Syc static nxge_xcvr_table_t nxge_10G_tn1010_table = {
18600161856Syc 	nxge_neptune_10G_serdes_init,
18700161856Syc 	nxge_tn1010_xcvr_init,
18800161856Syc 	nxge_10G_link_intr_stop,
18900161856Syc 	nxge_10G_link_intr_start,
19000161856Syc 	nxge_check_tn1010_link,
19100161856Syc 	XPCS_XCVR
19200161856Syc };
19300161856Syc 
19400161856Syc static nxge_xcvr_table_t nxge_1G_tn1010_table = {
19500161856Syc 	nxge_1G_serdes_init,
19600161856Syc 	nxge_tn1010_xcvr_init,
19700161856Syc 	nxge_1G_fiber_link_intr_stop,
19800161856Syc 	nxge_1G_fiber_link_intr_start,
19900161856Syc 	nxge_check_tn1010_link,
20000161856Syc 	PCS_XCVR
20100161856Syc };
20200161856Syc 
20359ac0c16Sdavemq static nxge_xcvr_table_t nxge_10G_fiber_table = {
20459ac0c16Sdavemq 	nxge_neptune_10G_serdes_init,
20559ac0c16Sdavemq 	nxge_10G_xcvr_init,
20659ac0c16Sdavemq 	nxge_10G_link_intr_stop,
20759ac0c16Sdavemq 	nxge_10G_link_intr_start,
20859ac0c16Sdavemq 	nxge_check_10g_link,
2092d17280bSsbehera 	PCS_XCVR
21059ac0c16Sdavemq };
21159ac0c16Sdavemq 
21259ac0c16Sdavemq static nxge_xcvr_table_t nxge_1G_copper_table = {
21359ac0c16Sdavemq 	NULL,
21459ac0c16Sdavemq 	nxge_1G_xcvr_init,
21559ac0c16Sdavemq 	nxge_1G_copper_link_intr_stop,
21659ac0c16Sdavemq 	nxge_1G_copper_link_intr_start,
21759ac0c16Sdavemq 	nxge_check_mii_link,
2182d17280bSsbehera 	INT_MII_XCVR
21959ac0c16Sdavemq };
22059ac0c16Sdavemq 
22100161856Syc /* This table is for Neptune portmode == PORT_1G_SERDES cases */
22259ac0c16Sdavemq static nxge_xcvr_table_t nxge_1G_fiber_table = {
22359ac0c16Sdavemq 	nxge_1G_serdes_init,
22459ac0c16Sdavemq 	nxge_1G_xcvr_init,
22559ac0c16Sdavemq 	nxge_1G_fiber_link_intr_stop,
22659ac0c16Sdavemq 	nxge_1G_fiber_link_intr_start,
22759ac0c16Sdavemq 	nxge_check_mii_link,
2282d17280bSsbehera 	PCS_XCVR
22959ac0c16Sdavemq };
23059ac0c16Sdavemq 
23159ac0c16Sdavemq static nxge_xcvr_table_t nxge_10G_copper_table = {
23259ac0c16Sdavemq 	nxge_neptune_10G_serdes_init,
23359ac0c16Sdavemq 	NULL,
23459ac0c16Sdavemq 	NULL,
23559ac0c16Sdavemq 	NULL,
2362e59129aSraghus 	NULL,
2372d17280bSsbehera 	PCS_XCVR
23859ac0c16Sdavemq };
23944961713Sgirish 
24000161856Syc /*
24100161856Syc  * NXGE_PORT_TN1010 is defined as,
24200161856Syc  *      NXGE_PORT_SPD_NONE | (NXGE_PHY_TN1010 << NXGE_PHY_SHIFT)
24300161856Syc  *	= 0 | 5 << 16 = 0x50000
24400161856Syc  *
24500161856Syc  * So NEPTUNE_2_TN1010 =
24600161856Syc  *      (NXGE_PORT_TN1010 |
24700161856Syc  *      (NXGE_PORT_TN1010 << 4) |
24800161856Syc  *      (NXGE_PORT_NONE << 8) |
24900161856Syc  *      (NXGE_PORT_NONE << 12)),
25000161856Syc  *      = 0x50000 | (0x50000 << 4)
25100161856Syc  *	= 0x550000
25200161856Syc  *
25300161856Syc  * This function partitions nxgep->nxge_hw_p->niu_type (which may have
25400161856Syc  * value NEPTUNE_2_TN1010) and checks if a port has type = NXGE_PORT_TN1010
25500161856Syc  * = 0x50000
25600161856Syc  */
nxge_is_tn1010_phy(p_nxge_t nxgep)25700161856Syc static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep)
25800161856Syc {
25900161856Syc 	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
26000161856Syc 
26100161856Syc 	if (((nxgep->nxge_hw_p->niu_type >> (NXGE_PORT_TYPE_SHIFT * portn))
26200161856Syc 	    & NXGE_PHY_MASK) == NXGE_PORT_TN1010) {
26300161856Syc 		return (B_TRUE);
26400161856Syc 	} else {
26500161856Syc 		return (B_FALSE);
26600161856Syc 	}
26700161856Syc }
26844961713Sgirish 
269d81011f0Ssbehera 
27000161856Syc /*
27100161856Syc  * Figure out nxgep->mac.portmode from nxge.conf, OBP's device properties,
27200161856Syc  * serial EEPROM or VPD if possible.  Note that not all systems could get
27300161856Syc  * the portmode information by calling this function.  For example, the
27400161856Syc  * Maramba system figures out the portmode information by calling function
27500161856Syc  * nxge_setup_xcvr_table.
27600161856Syc  */
2772e59129aSraghus nxge_status_t
nxge_get_xcvr_type(p_nxge_t nxgep)2782e59129aSraghus nxge_get_xcvr_type(p_nxge_t nxgep)
2792e59129aSraghus {
2802e59129aSraghus 	nxge_status_t status = NXGE_OK;
2812e59129aSraghus 	char *phy_type;
2822e59129aSraghus 	char *prop_val;
28300161856Syc 	uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num);
2841c7408c9Stc 	uint32_t	val;
2851c7408c9Stc 	npi_status_t	rs;
2861c7408c9Stc 
2871c7408c9Stc 	/* For Opus NEM, skip xcvr checking if 10G Serdes link is up */
2881c7408c9Stc 	if (nxgep->mac.portmode == PORT_10G_SERDES &&
2891c7408c9Stc 	    nxgep->statsp->mac_stats.link_up) {
2901c7408c9Stc 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
2911c7408c9Stc 		return (status);
2921c7408c9Stc 	}
2932e59129aSraghus 
2942e59129aSraghus 	nxgep->mac.portmode = 0;
2952d17280bSsbehera 	nxgep->xcvr_addr = 0;
2962e59129aSraghus 
2972d17280bSsbehera 	/*
2982d17280bSsbehera 	 * First check for hot swappable phy property.
2992d17280bSsbehera 	 */
3002d17280bSsbehera 	if (nxgep->hot_swappable_phy == B_TRUE) {
3012d17280bSsbehera 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
3022d17280bSsbehera 		nxgep->mac.portmode = PORT_HSP_MODE;
3032d17280bSsbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Other: Hot Swappable"));
3042d17280bSsbehera 	} else if (ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip,
3052d17280bSsbehera 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
3062d17280bSsbehera 	    "hot-swappable-phy") == 1) {
3072d17280bSsbehera 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
3082d17280bSsbehera 		nxgep->mac.portmode = PORT_HSP_MODE;
3092d17280bSsbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, ".conf: Hot Swappable"));
3102d17280bSsbehera 	} else if (nxgep->niu_type == N2_NIU &&
3112d17280bSsbehera 	    ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip, 0,
3122d17280bSsbehera 	    "hot-swappable-phy") == 1) {
3132d17280bSsbehera 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
3142d17280bSsbehera 		nxgep->mac.portmode = PORT_HSP_MODE;
3152d17280bSsbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "OBP: Hot Swappable"));
3162d17280bSsbehera 	}
3172d17280bSsbehera 
3182d17280bSsbehera 	/*
3192d17280bSsbehera 	 * MDIO polling support for Monza RTM card, Goa NEM card
3202d17280bSsbehera 	 */
3212d17280bSsbehera 	if (nxgep->mac.portmode == PORT_HSP_MODE) {
3222d17280bSsbehera 		nxgep->hot_swappable_phy = B_TRUE;
323ef523517SMichael Speer 		if (portn > 1) {
324ef523517SMichael Speer 			return (NXGE_ERROR);
325ef523517SMichael Speer 		}
326ef523517SMichael Speer 
32789282175SSantwona Behera 		if (nxge_hswap_phy_present(nxgep, portn))
3282d17280bSsbehera 			goto found_phy;
3292d17280bSsbehera 
3302d17280bSsbehera 		nxgep->phy_absent = B_TRUE;
3311c7408c9Stc 
3321c7408c9Stc 		/* Check Serdes link to detect Opus NEM */
3331c7408c9Stc 		rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
3341c7408c9Stc 		    XPCS_REG_STATUS, &val);
3351c7408c9Stc 
3361c7408c9Stc 		if (rs == 0 && val & XPCS_STATUS_LANE_ALIGN) {
3371c7408c9Stc 			nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3381c7408c9Stc 			nxgep->mac.portmode = PORT_10G_SERDES;
3391c7408c9Stc 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3401c7408c9Stc 			    "HSP 10G Serdes FOUND!!"));
3411c7408c9Stc 		}
3422d17280bSsbehera 		goto check_phy_done;
3432d17280bSsbehera found_phy:
3442d17280bSsbehera 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3452d17280bSsbehera 		nxgep->mac.portmode = PORT_10G_FIBER;
3462d17280bSsbehera 		nxgep->phy_absent = B_FALSE;
3472d17280bSsbehera 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Fiber Xcvr "
3482d17280bSsbehera 		    "found for hot swappable phy"));
3492d17280bSsbehera check_phy_done:
3502d17280bSsbehera 		return (status);
3512d17280bSsbehera 	}
3522d17280bSsbehera 
35300161856Syc 	/* Get phy-type property (May have been set by nxge.conf) */
3542e59129aSraghus 	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip,
3552e59129aSraghus 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
3562e59129aSraghus 	    "phy-type", &prop_val)) == DDI_PROP_SUCCESS) {
3572e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3582e59129aSraghus 		    "found  conf file: phy-type %s", prop_val));
3592e59129aSraghus 		if (strcmp("xgsd", prop_val) == 0) {
3602e59129aSraghus 			nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3612e59129aSraghus 			nxgep->mac.portmode = PORT_10G_SERDES;
3622e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3632e59129aSraghus 			    "found: 10G Serdes"));
3642e59129aSraghus 		} else if (strcmp("gsd", prop_val) == 0) {
3652e59129aSraghus 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
3662e59129aSraghus 			nxgep->mac.portmode = PORT_1G_SERDES;
3672e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Serdes"));
3682e59129aSraghus 		} else if (strcmp("mif", prop_val) == 0) {
3692e59129aSraghus 			nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
3702e59129aSraghus 			nxgep->mac.portmode = PORT_1G_COPPER;
3712e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr"));
3722e59129aSraghus 		} else if (strcmp("pcs", prop_val) == 0) {
3732e59129aSraghus 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
3742e59129aSraghus 			nxgep->mac.portmode = PORT_1G_FIBER;
3752e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G FIBER Xcvr"));
376321febdeSsbehera 		} else if (strcmp("xgf", prop_val) == 0) {
37700161856Syc 			/*
37800161856Syc 			 * Before OBP supports new phy-type property
37900161856Syc 			 * value "xgc", the 10G copper XAUI may carry
38000161856Syc 			 * "xgf" instead of "xgc". If the OBP is
38100161856Syc 			 * upgraded to a newer version which supports
38200161856Syc 			 * "xgc", then the TN1010 related code in this
38300161856Syc 			 * "xgf" case will not be used anymore.
38400161856Syc 			 */
38500161856Syc 			if (nxge_is_tn1010_phy(nxgep)) {
38600161856Syc 				if ((status = nxge_set_tn1010_param(nxgep))
38700161856Syc 				    != NXGE_OK) {
38800161856Syc 					return (status);
38900161856Syc 				}
39000161856Syc 				NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
39100161856Syc 			} else {  /* For Fiber XAUI */
39200161856Syc 				nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
39300161856Syc 				nxgep->mac.portmode = PORT_10G_FIBER;
39400161856Syc 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
39500161856Syc 				    "10G Fiber Xcvr"));
39600161856Syc 			}
39700161856Syc 		} else if (strcmp("xgc", prop_val) == 0) {
39800161856Syc 			if ((status = nxge_set_tn1010_param(nxgep)) != NXGE_OK)
39900161856Syc 				return (status);
40000161856Syc 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
4012e59129aSraghus 		}
4022e59129aSraghus 
4032e59129aSraghus 		(void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip,
4042e59129aSraghus 		    "phy-type", prop_val);
4052e59129aSraghus 		ddi_prop_free(prop_val);
4062e59129aSraghus 
4072e59129aSraghus 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
4082e59129aSraghus 		    "Got phy type [0x%x] from conf file",
4092e59129aSraghus 		    nxgep->mac.portmode));
4102e59129aSraghus 
4112e59129aSraghus 		return (NXGE_OK);
4122e59129aSraghus 	}
4132d17280bSsbehera 
4142d17280bSsbehera 	/* Get phy-type property from OBP */
4152e59129aSraghus 	if (nxgep->niu_type == N2_NIU) {
4162e59129aSraghus 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0,
4172e59129aSraghus 		    "phy-type", &prop_val) == DDI_PROP_SUCCESS) {
4182e59129aSraghus 			if (strcmp("xgf", prop_val) == 0) {
41900161856Syc 				/*
42000161856Syc 				 * Before OBP supports new phy-type property
42100161856Syc 				 * value "xgc", the 10G copper XAUI may carry
42200161856Syc 				 * "xgf" instead of "xgc". If the OBP is
42300161856Syc 				 * upgraded to a newer version which supports
42400161856Syc 				 * "xgc", then the TN1010 related code in this
42500161856Syc 				 * "xgf" case will not be used anymore.
42600161856Syc 				 */
42700161856Syc 				if (nxge_is_tn1010_phy(nxgep)) {
42800161856Syc 					if ((status =
42900161856Syc 					    nxge_set_tn1010_param(nxgep))
43000161856Syc 					    != NXGE_OK) {
43100161856Syc 						return (status);
43200161856Syc 					}
43300161856Syc 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
43400161856Syc 					    "TN1010 Xcvr"));
43589282175SSantwona Behera 				} else if (nxge_is_nlp2020_phy(nxgep)) {
43689282175SSantwona Behera 					if ((status =
43789282175SSantwona Behera 					    nxge_set_nlp2020_param(nxgep))
43889282175SSantwona Behera 					    != NXGE_OK) {
43989282175SSantwona Behera 						return (status);
44089282175SSantwona Behera 					}
44189282175SSantwona Behera 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
44289282175SSantwona Behera 					    "NLP2020 Xcvr"));
44389282175SSantwona Behera 				} else { /* For Fiber XAUI */
44400161856Syc 					nxgep->statsp->mac_stats.xcvr_inuse
44500161856Syc 					    = XPCS_XCVR;
44600161856Syc 					nxgep->mac.portmode = PORT_10G_FIBER;
44700161856Syc 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
44800161856Syc 					    "10G Fiber Xcvr"));
44900161856Syc 				}
4502e59129aSraghus 			} else if (strcmp("mif", prop_val) == 0) {
4512e59129aSraghus 				nxgep->statsp->mac_stats.xcvr_inuse =
4522e59129aSraghus 				    INT_MII_XCVR;
4532e59129aSraghus 				nxgep->mac.portmode = PORT_1G_COPPER;
4542e59129aSraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4552e59129aSraghus 				    "1G Copper Xcvr"));
4562e59129aSraghus 			} else if (strcmp("pcs", prop_val) == 0) {
4572e59129aSraghus 				nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
4582e59129aSraghus 				nxgep->mac.portmode = PORT_1G_FIBER;
4592e59129aSraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4602e59129aSraghus 				    "1G Fiber Xcvr"));
4612e59129aSraghus 			} else if (strcmp("xgc", prop_val) == 0) {
46200161856Syc 				status = nxge_set_tn1010_param(nxgep);
46300161856Syc 				if (status != NXGE_OK)
46400161856Syc 					return (status);
46500161856Syc 				NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
4662e59129aSraghus 			} else if (strcmp("xgsd", prop_val) == 0) {
4672e59129aSraghus 				nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
4682e59129aSraghus 				nxgep->mac.portmode = PORT_10G_SERDES;
4692e59129aSraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4702e59129aSraghus 				    "OBP: 10G Serdes"));
4712e59129aSraghus 			} else if (strcmp("gsd", prop_val) == 0) {
4722e59129aSraghus 				nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
4732e59129aSraghus 				nxgep->mac.portmode = PORT_1G_SERDES;
4742e59129aSraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4752e59129aSraghus 				    "OBP: 1G Serdes"));
4762e59129aSraghus 			} else {
4772e59129aSraghus 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4782e59129aSraghus 				    "Unknown phy-type: %s", prop_val));
4792e59129aSraghus 				ddi_prop_free(prop_val);
4802e59129aSraghus 				return (NXGE_ERROR);
4812e59129aSraghus 			}
4822e59129aSraghus 			status = NXGE_OK;
4832e59129aSraghus 			(void) ddi_prop_update_string(DDI_DEV_T_NONE,
4842e59129aSraghus 			    nxgep->dip, "phy-type", prop_val);
4852e59129aSraghus 			ddi_prop_free(prop_val);
4862e59129aSraghus 
4872e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
4882e59129aSraghus 			    "Got phy type [0x%x] from OBP",
4892e59129aSraghus 			    nxgep->mac.portmode));
4902e59129aSraghus 
4912e59129aSraghus 			return (status);
4922e59129aSraghus 		} else {
4932e59129aSraghus 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4942e59129aSraghus 			    "Exiting...phy-type property not found"));
4952e59129aSraghus 			return (NXGE_ERROR);
4962e59129aSraghus 		}
4972e59129aSraghus 	}
4982e59129aSraghus 
4992e59129aSraghus 
5002e59129aSraghus 	if (!nxgep->vpd_info.present) {
5012e59129aSraghus 		return (NXGE_OK);
5022e59129aSraghus 	}
5032e59129aSraghus 
5042e59129aSraghus 	if (!nxgep->vpd_info.ver_valid) {
5052e59129aSraghus 		goto read_seeprom;
5062e59129aSraghus 	}
5072e59129aSraghus 
5082e59129aSraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5092e59129aSraghus 	    "Reading phy type from expansion ROM"));
5102e59129aSraghus 	/*
5112e59129aSraghus 	 * Try to read the phy type from the vpd data read off the
5122e59129aSraghus 	 * expansion ROM.
5132e59129aSraghus 	 */
5142e59129aSraghus 	phy_type = nxgep->vpd_info.phy_type;
5152e59129aSraghus 
516d81011f0Ssbehera 	if (strncmp(phy_type, "mif", 3) == 0) {
5172e59129aSraghus 		nxgep->mac.portmode = PORT_1G_COPPER;
5182e59129aSraghus 		nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
519d81011f0Ssbehera 	} else if (strncmp(phy_type, "xgf", 3) == 0) {
5202e59129aSraghus 		nxgep->mac.portmode = PORT_10G_FIBER;
5212e59129aSraghus 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
522d81011f0Ssbehera 	} else if (strncmp(phy_type, "pcs", 3) == 0) {
5232e59129aSraghus 		nxgep->mac.portmode = PORT_1G_FIBER;
5242e59129aSraghus 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
525d81011f0Ssbehera 	} else if (strncmp(phy_type, "xgc", 3) == 0) {
52600161856Syc 		status = nxge_set_tn1010_param(nxgep);
52700161856Syc 		if (status != NXGE_OK) {
52800161856Syc 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
52900161856Syc 			    "nxge_get_xcvr_type: Failed to set TN1010 param"));
53000161856Syc 			goto read_seeprom;
53100161856Syc 		}
532d81011f0Ssbehera 	} else if (strncmp(phy_type, "xgsd", 4) == 0) {
533d81011f0Ssbehera 		nxgep->mac.portmode = PORT_10G_SERDES;
534d81011f0Ssbehera 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
535d81011f0Ssbehera 	} else if (strncmp(phy_type, "gsd", 3) == 0) {
536d81011f0Ssbehera 		nxgep->mac.portmode = PORT_1G_SERDES;
537d81011f0Ssbehera 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
5382e59129aSraghus 	} else {
539d81011f0Ssbehera 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5402e59129aSraghus 		    "nxge_get_xcvr_type: Unknown phy type [%c%c%c] in EEPROM",
5412e59129aSraghus 		    phy_type[0], phy_type[1], phy_type[2]));
5422e59129aSraghus 		goto read_seeprom;
5432e59129aSraghus 	}
5442e59129aSraghus 
5452e59129aSraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
5462e59129aSraghus 	    "Got phy type [0x%x] from VPD", nxgep->mac.portmode));
5472e59129aSraghus 
5482e59129aSraghus 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type"));
5492e59129aSraghus 	return (status);
5502e59129aSraghus 
5512e59129aSraghus read_seeprom:
5522e59129aSraghus 	/*
5532e59129aSraghus 	 * read the phy type from the SEEPROM - NCR registers
5542e59129aSraghus 	 */
5552e59129aSraghus 	status = nxge_espc_phy_type_get(nxgep);
5562e59129aSraghus 	if (status != NXGE_OK) {
5572e59129aSraghus 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5582e59129aSraghus 		    "Failed to get phy type"));
5592e59129aSraghus 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version "
5602e59129aSraghus 		    "[%s] invalid...please update", nxgep->vpd_info.ver));
5612e59129aSraghus 	}
5622e59129aSraghus 
5632e59129aSraghus 	return (status);
5642e59129aSraghus 
5652e59129aSraghus }
5662e59129aSraghus 
56759ac0c16Sdavemq /* Set up the PHY specific values. */
56859ac0c16Sdavemq 
56959ac0c16Sdavemq nxge_status_t
nxge_setup_xcvr_table(p_nxge_t nxgep)57059ac0c16Sdavemq nxge_setup_xcvr_table(p_nxge_t nxgep)
57159ac0c16Sdavemq {
57259ac0c16Sdavemq 	nxge_status_t	status = NXGE_OK;
57359ac0c16Sdavemq 	uint32_t	port_type;
57459ac0c16Sdavemq 	uint8_t		portn = NXGE_GET_PORT_NUM(nxgep->function_num);
5752e59129aSraghus 	uint32_t	pcs_id = 0;
5762e59129aSraghus 	uint32_t	pma_pmd_id = 0;
5772e59129aSraghus 	uint32_t	phy_id = 0;
5782d17280bSsbehera 	uint16_t	chip_id = 0;
57959ac0c16Sdavemq 
58059ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_setup_xcvr_table: port<%d>",
58159ac0c16Sdavemq 	    portn));
58259ac0c16Sdavemq 
5832e59129aSraghus 	switch (nxgep->niu_type) {
5842e59129aSraghus 	case N2_NIU:
5852e59129aSraghus 		switch (nxgep->mac.portmode) {
5862e59129aSraghus 		case PORT_1G_FIBER:
5872e59129aSraghus 		case PORT_1G_SERDES:
5882e59129aSraghus 			nxgep->xcvr = nxge_n2_1G_table;
5892d17280bSsbehera 			nxgep->xcvr_addr = portn;
5902e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 1G %s Xcvr",
5912e59129aSraghus 			    (nxgep->mac.portmode == PORT_1G_FIBER) ? "Fiber" :
5922e59129aSraghus 			    "Serdes"));
5932e59129aSraghus 			break;
5942e59129aSraghus 		case PORT_10G_FIBER:
59589282175SSantwona Behera 		case PORT_10G_COPPER:
5962e59129aSraghus 		case PORT_10G_SERDES:
5972e59129aSraghus 			nxgep->xcvr = nxge_n2_10G_table;
5982d17280bSsbehera 			if (nxgep->nxge_hw_p->xcvr_addr[portn]) {
5992d17280bSsbehera 				nxgep->xcvr_addr =
6002d17280bSsbehera 				    nxgep->nxge_hw_p->xcvr_addr[portn];
6012d17280bSsbehera 			}
6022e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G %s Xcvr",
6032e59129aSraghus 			    (nxgep->mac.portmode == PORT_10G_FIBER) ? "Fiber" :
60489282175SSantwona Behera 			    ((nxgep->mac.portmode == PORT_10G_COPPER) ?
60589282175SSantwona Behera 			    "Copper" : "Serdes")));
6062e59129aSraghus 			break;
60700161856Syc 		case PORT_1G_TN1010:
60800161856Syc 			nxgep->xcvr = nxge_n2_1G_tn1010_table;
60900161856Syc 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
61000161856Syc 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61100161856Syc 			    "TN1010 Copper Xcvr in 1G"));
61200161856Syc 			break;
61300161856Syc 		case PORT_10G_TN1010:
61400161856Syc 			nxgep->xcvr = nxge_n2_10G_tn1010_table;
61500161856Syc 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
61600161856Syc 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
61700161856Syc 			    "TN1010 Copper Xcvr in 10G"));
61800161856Syc 			break;
6192d17280bSsbehera 		case PORT_HSP_MODE:
6202d17280bSsbehera 			nxgep->xcvr = nxge_n2_10G_table;
6212d17280bSsbehera 			nxgep->xcvr.xcvr_inuse = HSP_XCVR;
6222d17280bSsbehera 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G Hot "
6232d17280bSsbehera 			    "Swappable Xcvr (not present)"));
6242d17280bSsbehera 			break;
6252e59129aSraghus 		default:
6262e59129aSraghus 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6272e59129aSraghus 			    "<== nxge_setup_xcvr_table: "
6282e59129aSraghus 			    "Unable to determine NIU portmode"));
6292e59129aSraghus 			return (NXGE_ERROR);
6302e59129aSraghus 		}
6312e59129aSraghus 		break;
6322e59129aSraghus 	default:
6332e59129aSraghus 		if (nxgep->mac.portmode == 0) {
6342e59129aSraghus 			/*
6352e59129aSraghus 			 * Would be the case for platforms like Maramba
6362e59129aSraghus 			 * in which the phy type could not be got from conf
6372e59129aSraghus 			 * file, OBP, VPD or Serial PROM.
6382e59129aSraghus 			 */
6392e59129aSraghus 			if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
6402e59129aSraghus 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6412e59129aSraghus 				    "<== nxge_setup_xcvr_table:"
6422e59129aSraghus 				    " Invalid Neptune type [0x%x]",
6432e59129aSraghus 				    nxgep->niu_type));
6442e59129aSraghus 				return (NXGE_ERROR);
6452e59129aSraghus 			}
6462e59129aSraghus 
6472e59129aSraghus 			port_type = nxgep->niu_type >>
6482e59129aSraghus 			    (NXGE_PORT_TYPE_SHIFT * portn);
6492e59129aSraghus 			port_type = port_type & (NXGE_PORT_TYPE_MASK);
6502e59129aSraghus 
6512e59129aSraghus 			switch (port_type) {
6522e59129aSraghus 
6532e59129aSraghus 			case NXGE_PORT_1G_COPPER:
6542e59129aSraghus 				nxgep->mac.portmode = PORT_1G_COPPER;
6552e59129aSraghus 				break;
6562e59129aSraghus 			case NXGE_PORT_10G_COPPER:
6572e59129aSraghus 				nxgep->mac.portmode = PORT_10G_COPPER;
6582e59129aSraghus 				break;
6592e59129aSraghus 			case NXGE_PORT_1G_FIBRE:
6602e59129aSraghus 				nxgep->mac.portmode = PORT_1G_FIBER;
6612e59129aSraghus 				break;
6622e59129aSraghus 			case NXGE_PORT_10G_FIBRE:
6632e59129aSraghus 				nxgep->mac.portmode = PORT_10G_FIBER;
6642e59129aSraghus 				break;
6652e59129aSraghus 			case NXGE_PORT_1G_SERDES:
6662e59129aSraghus 				nxgep->mac.portmode = PORT_1G_SERDES;
6672e59129aSraghus 				break;
6682e59129aSraghus 			case NXGE_PORT_10G_SERDES:
6692e59129aSraghus 				nxgep->mac.portmode = PORT_10G_SERDES;
6702e59129aSraghus 				break;
67100161856Syc 			/* Ports 2 and 3 of Alonso or ARTM */
6722e59129aSraghus 			case NXGE_PORT_1G_RGMII_FIBER:
6732e59129aSraghus 				nxgep->mac.portmode = PORT_1G_RGMII_FIBER;
6742e59129aSraghus 				break;
67500161856Syc 			case NXGE_PORT_TN1010:
67600161856Syc 				/*
67700161856Syc 				 * If this port uses the TN1010 copper
67800161856Syc 				 * PHY, then its speed is not known yet
67900161856Syc 				 * because nxge_scan_ports_phy could only
68000161856Syc 				 * figure out the vendor of the PHY but
68100161856Syc 				 * not its speed. nxge_set_tn1010_param
68200161856Syc 				 * will read the PHY speed and set
68300161856Syc 				 * portmode accordingly.
68400161856Syc 				 */
68500161856Syc 				if ((status = nxge_set_tn1010_param(nxgep))
68600161856Syc 				    != NXGE_OK) {
68700161856Syc 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
68800161856Syc 					    "nxge_set_tn1010_param failed"));
68900161856Syc 					return (status);
69000161856Syc 				}
69100161856Syc 				break;
6922e59129aSraghus 			default:
6932e59129aSraghus 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
6942e59129aSraghus 				    "<== nxge_setup_xcvr_table: "
6952e59129aSraghus 				    "Unknown port-type: 0x%x", port_type));
6962e59129aSraghus 				return (NXGE_ERROR);
6972e59129aSraghus 			}
6982e59129aSraghus 		}
6992e59129aSraghus 
70000161856Syc 		/*
70100161856Syc 		 * Above switch has figured out nxge->mac.portmode, now set
70200161856Syc 		 * nxgep->xcvr (the table) and nxgep->xcvr_addr according
70300161856Syc 		 * to portmode.
70400161856Syc 		 */
7052e59129aSraghus 		switch (nxgep->mac.portmode) {
7062e59129aSraghus 		case PORT_1G_COPPER:
7072e59129aSraghus 		case PORT_1G_RGMII_FIBER:
70859ac0c16Sdavemq 			nxgep->xcvr = nxge_1G_copper_table;
7092d17280bSsbehera 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
71059ac0c16Sdavemq 			/*
71159ac0c16Sdavemq 			 * For Altas 4-1G copper, Xcvr port numbers are
71259ac0c16Sdavemq 			 * swapped with ethernet port number. This is
7132e59129aSraghus 			 * designed for better signal integrity in
7142e59129aSraghus 			 * routing. This is also the case for the
7152e59129aSraghus 			 * on-board Neptune copper ports on the Maramba
7162e59129aSraghus 			 * platform.
71759ac0c16Sdavemq 			 */
7182e59129aSraghus 			switch (nxgep->platform_type) {
7192e59129aSraghus 			case P_NEPTUNE_ATLAS_4PORT:
7202e59129aSraghus 			case P_NEPTUNE_MARAMBA_P0:
7212e59129aSraghus 			case P_NEPTUNE_MARAMBA_P1:
7222e59129aSraghus 				switch (portn) {
7232e59129aSraghus 				case 0:
7242d17280bSsbehera 					nxgep->xcvr_addr += 3;
7252e59129aSraghus 					break;
7262e59129aSraghus 				case 1:
7272d17280bSsbehera 					nxgep->xcvr_addr += 1;
7282e59129aSraghus 					break;
7292e59129aSraghus 				case 2:
7302d17280bSsbehera 					nxgep->xcvr_addr -= 1;
7312e59129aSraghus 					break;
7322e59129aSraghus 				case 3:
7332d17280bSsbehera 					nxgep->xcvr_addr -= 3;
7342e59129aSraghus 					break;
7352e59129aSraghus 				default:
7362e59129aSraghus 					return (NXGE_ERROR);
7372e59129aSraghus 				}
73859ac0c16Sdavemq 				break;
73959ac0c16Sdavemq 			default:
7402e59129aSraghus 				break;
74159ac0c16Sdavemq 			}
742d81011f0Ssbehera 
7432e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
7442e59129aSraghus 			    (nxgep->mac.portmode == PORT_1G_COPPER) ?
7452e59129aSraghus 			    "Copper" : "RGMII Fiber"));
74659ac0c16Sdavemq 			break;
74700161856Syc 
7482e59129aSraghus 		case PORT_10G_COPPER:
74959ac0c16Sdavemq 			nxgep->xcvr = nxge_10G_copper_table;
75059ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr"));
75159ac0c16Sdavemq 			break;
75200161856Syc 
75300161856Syc 		case PORT_1G_TN1010:
75400161856Syc 			nxgep->xcvr = nxge_1G_tn1010_table;
75500161856Syc 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
75600161856Syc 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
75700161856Syc 			    "1G TN1010 copper Xcvr"));
75800161856Syc 			break;
75900161856Syc 
76000161856Syc 		case PORT_10G_TN1010:
76100161856Syc 			nxgep->xcvr = nxge_10G_tn1010_table;
76200161856Syc 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
76300161856Syc 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
76400161856Syc 			    "10G TN1010 copper Xcvr"));
76500161856Syc 			break;
76600161856Syc 
7672e59129aSraghus 		case PORT_1G_FIBER:
7682e59129aSraghus 		case PORT_1G_SERDES:
76959ac0c16Sdavemq 			nxgep->xcvr = nxge_1G_fiber_table;
7702d17280bSsbehera 			nxgep->xcvr_addr = portn;
7712e59129aSraghus 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
7722e59129aSraghus 			    (nxgep->mac.portmode == PORT_1G_FIBER) ?
7732e59129aSraghus 			    "Fiber" : "Serdes"));
77459ac0c16Sdavemq 			break;
7752e59129aSraghus 		case PORT_10G_FIBER:
7762e59129aSraghus 		case PORT_10G_SERDES:
77759ac0c16Sdavemq 			nxgep->xcvr = nxge_10G_fiber_table;
778