Home | History | Annotate | Download | only in nxge
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #include <sys/nxge/nxge_impl.h>
     27 #include <sys/nxge/nxge_mac.h>
     28 #include <sys/nxge/nxge_hio.h>
     29 
     30 #define	LINK_MONITOR_PERIOD	(1000 * 1000)
     31 #define	LM_WAIT_MULTIPLIER	8
     32 
     33 #define	SERDES_RDY_WT_INTERVAL	50
     34 #define	MAX_SERDES_RDY_RETRIES	10
     35 
     36 #define	TN1010_SPEED_1G		1
     37 #define	TN1010_SPEED_10G	0
     38 #define	TN1010_AN_IN_PROG	0	/* Auto negotiation in progress */
     39 #define	TN1010_AN_COMPLETE	1
     40 #define	TN1010_AN_RSVD		2
     41 #define	TN1010_AN_FAILED	3
     42 
     43 extern uint32_t nxge_no_link_notify;
     44 extern boolean_t nxge_no_msg;
     45 extern uint32_t nxge_lb_dbg;
     46 extern uint32_t nxge_jumbo_mtu;
     47 
     48 typedef enum {
     49 	CHECK_LINK_RESCHEDULE,
     50 	CHECK_LINK_STOP
     51 } check_link_state_t;
     52 
     53 static check_link_state_t nxge_check_link_stop(nxge_t *);
     54 
     55 /*
     56  * Ethernet broadcast address definition.
     57  */
     58 static ether_addr_st etherbroadcastaddr =
     59 				{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
     60 /*
     61  * Ethernet zero address definition.
     62  */
     63 static ether_addr_st etherzeroaddr =
     64 				{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
     65 /*
     66  * Supported chip types
     67  */
     68 static uint32_t nxge_supported_cl45_ids[] = {
     69 	BCM8704_DEV_ID,
     70 	MARVELL_88X_201X_DEV_ID,
     71 	BCM8706_DEV_ID,
     72 	TN1010_DEV_ID
     73 };
     74 
     75 static uint32_t nxge_supported_cl22_ids[] = {
     76     BCM5464R_PHY_ID,
     77     BCM5482_PHY_ID
     78 };
     79 
     80 #define	NUM_CLAUSE_45_IDS	(sizeof (nxge_supported_cl45_ids) /	\
     81 				sizeof (uint32_t))
     82 #define	NUM_CLAUSE_22_IDS	(sizeof (nxge_supported_cl22_ids) /	\
     83 				sizeof (uint32_t))
     84 /*
     85  * static functions
     86  */
     87 static uint32_t nxge_get_cl45_pma_pmd_id(p_nxge_t, int);
     88 static uint32_t nxge_get_cl45_pcs_id(p_nxge_t, int);
     89 static uint32_t nxge_get_cl22_phy_id(p_nxge_t, int);
     90 static boolean_t nxge_is_supported_phy(uint32_t, uint8_t);
     91 static boolean_t nxge_is_phy_present(p_nxge_t, int, uint32_t, uint32_t);
     92 static nxge_status_t nxge_n2_serdes_init(p_nxge_t);
     93 static nxge_status_t nxge_n2_kt_serdes_init(p_nxge_t);
     94 static nxge_status_t nxge_neptune_10G_serdes_init(p_nxge_t);
     95 static nxge_status_t nxge_1G_serdes_init(p_nxge_t);
     96 static nxge_status_t nxge_10G_link_intr_stop(p_nxge_t);
     97 static nxge_status_t nxge_10G_link_intr_start(p_nxge_t);
     98 static nxge_status_t nxge_1G_copper_link_intr_stop(p_nxge_t);
     99 static nxge_status_t nxge_1G_copper_link_intr_start(p_nxge_t);
    100 static nxge_status_t nxge_1G_fiber_link_intr_stop(p_nxge_t);
    101 static nxge_status_t nxge_1G_fiber_link_intr_start(p_nxge_t);
    102 static nxge_status_t nxge_check_mii_link(p_nxge_t);
    103 static nxge_status_t nxge_check_10g_link(p_nxge_t);
    104 static nxge_status_t nxge_10G_xcvr_init(p_nxge_t);
    105 static nxge_status_t nxge_BCM8704_xcvr_init(p_nxge_t);
    106 static nxge_status_t nxge_BCM8706_xcvr_init(p_nxge_t);
    107 static nxge_status_t nxge_1G_xcvr_init(p_nxge_t);
    108 static void nxge_bcm5464_link_led_off(p_nxge_t);
    109 static nxge_status_t nxge_check_mrvl88x2011_link(p_nxge_t, boolean_t *);
    110 static nxge_status_t nxge_mrvl88x2011_xcvr_init(p_nxge_t);
    111 static nxge_status_t nxge_get_num_of_xaui(uint32_t *port_pma_pmd_dev_id,
    112 	uint32_t *port_pcs_dev_id, uint32_t *port_phy_id, uint8_t *num_xaui);
    113 static nxge_status_t nxge_get_tn1010_speed(p_nxge_t nxgep, uint16_t *speed);
    114 static nxge_status_t nxge_set_tn1010_param(p_nxge_t nxgep);
    115 static nxge_status_t nxge_tn1010_check(p_nxge_t nxgep,
    116 	nxge_link_state_t *link_up);
    117 static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep);
    118 static nxge_status_t nxge_tn1010_xcvr_init(p_nxge_t nxgep);
    119 
    120 nxge_status_t nxge_mac_init(p_nxge_t);
    121 static nxge_status_t nxge_mii_get_link_mode(p_nxge_t);
    122 
    123 #ifdef NXGE_DEBUG
    124 static void nxge_mii_dump(p_nxge_t);
    125 static nxge_status_t nxge_tn1010_reset(p_nxge_t nxgep);
    126 static void nxge_dump_tn1010_status_regs(p_nxge_t nxgep);
    127 #endif
    128 
    129 /*
    130  * xcvr tables for supported transceivers
    131  */
    132 
    133 /*
    134  * nxge_n2_10G_table is for 10G fiber or serdes on N2-NIU systems.
    135  * The Teranetics TN1010 based copper XAUI card can also be used
    136  * on N2-NIU systems in 10G mode, but it uses its own table
    137  * nxge_n2_10G_tn1010_table below.
    138  */
    139 static nxge_xcvr_table_t nxge_n2_10G_table = {
    140 	nxge_n2_serdes_init,
    141 	nxge_10G_xcvr_init,
    142 	nxge_10G_link_intr_stop,
    143 	nxge_10G_link_intr_start,
    144 	nxge_check_10g_link,
    145 	PCS_XCVR
    146 };
    147 
    148 /*
    149  * For the Teranetics TN1010 based copper XAUI card
    150  */
    151 static nxge_xcvr_table_t nxge_n2_10G_tn1010_table = {
    152 	nxge_n2_serdes_init,		/* Handle both 1G and 10G */
    153 	nxge_tn1010_xcvr_init,		/* Handle both 1G and 10G */
    154 	nxge_10G_link_intr_stop,
    155 	nxge_10G_link_intr_start,
    156 	nxge_check_tn1010_link,		/* Will figure out speed */
    157 	XPCS_XCVR
    158 };
    159 
    160 static nxge_xcvr_table_t nxge_n2_1G_table = {
    161 	nxge_n2_serdes_init,
    162 	nxge_1G_xcvr_init,
    163 	nxge_1G_fiber_link_intr_stop,
    164 	nxge_1G_fiber_link_intr_start,
    165 	nxge_check_mii_link,
    166 	PCS_XCVR
    167 };
    168 
    169 static nxge_xcvr_table_t nxge_n2_1G_tn1010_table = {
    170 	nxge_n2_serdes_init,
    171 	nxge_tn1010_xcvr_init,
    172 	nxge_1G_fiber_link_intr_stop,	/* TN1010 is a Cu PHY, but it uses */
    173 	nxge_1G_fiber_link_intr_start,	/* PCS for 1G, so call fiber func */
    174 	nxge_check_tn1010_link,
    175 	PCS_XCVR
    176 };
    177 
    178 static nxge_xcvr_table_t nxge_10G_tn1010_table = {
    179 	nxge_neptune_10G_serdes_init,
    180 	nxge_tn1010_xcvr_init,
    181 	nxge_10G_link_intr_stop,
    182 	nxge_10G_link_intr_start,
    183 	nxge_check_tn1010_link,
    184 	XPCS_XCVR
    185 };
    186 
    187 static nxge_xcvr_table_t nxge_1G_tn1010_table = {
    188 	nxge_1G_serdes_init,
    189 	nxge_tn1010_xcvr_init,
    190 	nxge_1G_fiber_link_intr_stop,
    191 	nxge_1G_fiber_link_intr_start,
    192 	nxge_check_tn1010_link,
    193 	PCS_XCVR
    194 };
    195 
    196 static nxge_xcvr_table_t nxge_10G_fiber_table = {
    197 	nxge_neptune_10G_serdes_init,
    198 	nxge_10G_xcvr_init,
    199 	nxge_10G_link_intr_stop,
    200 	nxge_10G_link_intr_start,
    201 	nxge_check_10g_link,
    202 	PCS_XCVR
    203 };
    204 
    205 static nxge_xcvr_table_t nxge_1G_copper_table = {
    206 	NULL,
    207 	nxge_1G_xcvr_init,
    208 	nxge_1G_copper_link_intr_stop,
    209 	nxge_1G_copper_link_intr_start,
    210 	nxge_check_mii_link,
    211 	INT_MII_XCVR
    212 };
    213 
    214 /* This table is for Neptune portmode == PORT_1G_SERDES cases */
    215 static nxge_xcvr_table_t nxge_1G_fiber_table = {
    216 	nxge_1G_serdes_init,
    217 	nxge_1G_xcvr_init,
    218 	nxge_1G_fiber_link_intr_stop,
    219 	nxge_1G_fiber_link_intr_start,
    220 	nxge_check_mii_link,
    221 	PCS_XCVR
    222 };
    223 
    224 static nxge_xcvr_table_t nxge_10G_copper_table = {
    225 	nxge_neptune_10G_serdes_init,
    226 	NULL,
    227 	NULL,
    228 	NULL,
    229 	NULL,
    230 	PCS_XCVR
    231 };
    232 
    233 /*
    234  * NXGE_PORT_TN1010 is defined as,
    235  *      NXGE_PORT_SPD_NONE | (NXGE_PHY_TN1010 << NXGE_PHY_SHIFT)
    236  *	= 0 | 5 << 16 = 0x50000
    237  *
    238  * So NEPTUNE_2_TN1010 =
    239  *      (NXGE_PORT_TN1010 |
    240  *      (NXGE_PORT_TN1010 << 4) |
    241  *      (NXGE_PORT_NONE << 8) |
    242  *      (NXGE_PORT_NONE << 12)),
    243  *      = 0x50000 | (0x50000 << 4)
    244  *	= 0x550000
    245  *
    246  * This function partitions nxgep->nxge_hw_p->niu_type (which may have
    247  * value NEPTUNE_2_TN1010) and checks if a port has type = NXGE_PORT_TN1010
    248  * = 0x50000
    249  */
    250 static boolean_t nxge_is_tn1010_phy(p_nxge_t nxgep)
    251 {
    252 	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
    253 
    254 	if (((nxgep->nxge_hw_p->niu_type >> (NXGE_PORT_TYPE_SHIFT * portn))
    255 	    & NXGE_PHY_MASK) == NXGE_PORT_TN1010) {
    256 		return (B_TRUE);
    257 	} else {
    258 		return (B_FALSE);
    259 	}
    260 }
    261 
    262 
    263 /*
    264  * Figure out nxgep->mac.portmode from nxge.conf, OBP's device properties,
    265  * serial EEPROM or VPD if possible.  Note that not all systems could get
    266  * the portmode information by calling this function.  For example, the
    267  * Maramba system figures out the portmode information by calling function
    268  * nxge_setup_xcvr_table.
    269  */
    270 nxge_status_t
    271 nxge_get_xcvr_type(p_nxge_t nxgep)
    272 {
    273 	nxge_status_t status = NXGE_OK;
    274 	char *phy_type;
    275 	char *prop_val;
    276 	uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num);
    277 	uint32_t	val;
    278 	npi_status_t	rs;
    279 
    280 	/* For Opus NEM, skip xcvr checking if 10G Serdes link is up */
    281 	if (nxgep->mac.portmode == PORT_10G_SERDES &&
    282 	    nxgep->statsp->mac_stats.link_up) {
    283 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
    284 		return (status);
    285 	}
    286 
    287 	nxgep->mac.portmode = 0;
    288 	nxgep->xcvr_addr = 0;
    289 
    290 	/*
    291 	 * First check for hot swappable phy property.
    292 	 */
    293 	if (nxgep->hot_swappable_phy == B_TRUE) {
    294 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
    295 		nxgep->mac.portmode = PORT_HSP_MODE;
    296 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Other: Hot Swappable"));
    297 	} else if (ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip,
    298 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
    299 	    "hot-swappable-phy") == 1) {
    300 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
    301 		nxgep->mac.portmode = PORT_HSP_MODE;
    302 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, ".conf: Hot Swappable"));
    303 	} else if (nxgep->niu_type == N2_NIU &&
    304 	    ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip, 0,
    305 	    "hot-swappable-phy") == 1) {
    306 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
    307 		nxgep->mac.portmode = PORT_HSP_MODE;
    308 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "OBP: Hot Swappable"));
    309 	}
    310 
    311 	/*
    312 	 * MDIO polling support for Monza RTM card, Goa NEM card
    313 	 */
    314 	if (nxgep->mac.portmode == PORT_HSP_MODE) {
    315 		nxgep->hot_swappable_phy = B_TRUE;
    316 		if (portn > 1) {
    317 			return (NXGE_ERROR);
    318 		}
    319 
    320 		/*
    321 		 * If this is the 2nd NIU port, then check 2 addresses
    322 		 * to take care of the Goa NEM card. Port 1 can have addr 17
    323 		 * (in the eval board) or 20 (in the P0 board).
    324 		 */
    325 		if (portn == 1) {
    326 			if (nxge_is_phy_present(nxgep,
    327 			    ALT_GOA_CLAUSE45_PORT1_ADDR, BCM8706_DEV_ID,
    328 			    BCM_PHY_ID_MASK)) {
    329 				nxgep->xcvr_addr =
    330 				    ALT_GOA_CLAUSE45_PORT1_ADDR;
    331 				goto found_phy;
    332 			}
    333 		}
    334 		if (nxge_is_phy_present(nxgep,
    335 		    GOA_CLAUSE45_PORT_ADDR_BASE + portn,
    336 		    BCM8706_DEV_ID, BCM_PHY_ID_MASK)) {
    337 			nxgep->xcvr_addr = GOA_CLAUSE45_PORT_ADDR_BASE +
    338 			    portn;
    339 			goto found_phy;
    340 		}
    341 
    342 		nxgep->phy_absent = B_TRUE;
    343 
    344 		/* Check Serdes link to detect Opus NEM */
    345 		rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
    346 		    XPCS_REG_STATUS, &val);
    347 
    348 		if (rs == 0 && val & XPCS_STATUS_LANE_ALIGN) {
    349 			nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
    350 			nxgep->mac.portmode = PORT_10G_SERDES;
    351 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    352 			    "HSP 10G Serdes FOUND!!"));
    353 		}
    354 		goto check_phy_done;
    355 found_phy:
    356 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
    357 		nxgep->mac.portmode = PORT_10G_FIBER;
    358 		nxgep->phy_absent = B_FALSE;
    359 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Fiber Xcvr "
    360 		    "found for hot swappable phy"));
    361 check_phy_done:
    362 		return (status);
    363 	}
    364 
    365 	/* Get phy-type property (May have been set by nxge.conf) */
    366 	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip,
    367 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
    368 	    "phy-type", &prop_val)) == DDI_PROP_SUCCESS) {
    369 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    370 		    "found  conf file: phy-type %s", prop_val));
    371 		if (strcmp("xgsd", prop_val) == 0) {
    372 			nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
    373 			nxgep->mac.portmode = PORT_10G_SERDES;
    374 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    375 			    "found: 10G Serdes"));
    376 		} else if (strcmp("gsd", prop_val) == 0) {
    377 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
    378 			nxgep->mac.portmode = PORT_1G_SERDES;
    379 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Serdes"));
    380 		} else if (strcmp("mif", prop_val) == 0) {
    381 			nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
    382 			nxgep->mac.portmode = PORT_1G_COPPER;
    383 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr"));
    384 		} else if (strcmp("pcs", prop_val) == 0) {
    385 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
    386 			nxgep->mac.portmode = PORT_1G_FIBER;
    387 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G FIBER Xcvr"));
    388 		} else if (strcmp("xgf", prop_val) == 0) {
    389 			/*
    390 			 * Before OBP supports new phy-type property
    391 			 * value "xgc", the 10G copper XAUI may carry
    392 			 * "xgf" instead of "xgc". If the OBP is
    393 			 * upgraded to a newer version which supports
    394 			 * "xgc", then the TN1010 related code in this
    395 			 * "xgf" case will not be used anymore.
    396 			 */
    397 			if (nxge_is_tn1010_phy(nxgep)) {
    398 				if ((status = nxge_set_tn1010_param(nxgep))
    399 				    != NXGE_OK) {
    400 					return (status);
    401 				}
    402 				NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
    403 			} else {  /* For Fiber XAUI */
    404 				nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
    405 				nxgep->mac.portmode = PORT_10G_FIBER;
    406 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    407 				    "10G Fiber Xcvr"));
    408 			}
    409 		} else if (strcmp("xgc", prop_val) == 0) {
    410 			if ((status = nxge_set_tn1010_param(nxgep)) != NXGE_OK)
    411 				return (status);
    412 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
    413 		}
    414 
    415 		(void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip,
    416 		    "phy-type", prop_val);
    417 		ddi_prop_free(prop_val);
    418 
    419 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
    420 		    "Got phy type [0x%x] from conf file",
    421 		    nxgep->mac.portmode));
    422 
    423 		return (NXGE_OK);
    424 	}
    425 
    426 	/* Get phy-type property from OBP */
    427 	if (nxgep->niu_type == N2_NIU) {
    428 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0,
    429 		    "phy-type", &prop_val) == DDI_PROP_SUCCESS) {
    430 			if (strcmp("xgf", prop_val) == 0) {
    431 				/*
    432 				 * Before OBP supports new phy-type property
    433 				 * value "xgc", the 10G copper XAUI may carry
    434 				 * "xgf" instead of "xgc". If the OBP is
    435 				 * upgraded to a newer version which supports
    436 				 * "xgc", then the TN1010 related code in this
    437 				 * "xgf" case will not be used anymore.
    438 				 */
    439 				if (nxge_is_tn1010_phy(nxgep)) {
    440 					if ((status =
    441 					    nxge_set_tn1010_param(nxgep))
    442 					    != NXGE_OK) {
    443 						return (status);
    444 					}
    445 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    446 					    "TN1010 Xcvr"));
    447 				} else {  /* For Fiber XAUI */
    448 					nxgep->statsp->mac_stats.xcvr_inuse
    449 					    = XPCS_XCVR;
    450 					nxgep->mac.portmode = PORT_10G_FIBER;
    451 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    452 					    "10G Fiber Xcvr"));
    453 				}
    454 			} else if (strcmp("mif", prop_val) == 0) {
    455 				nxgep->statsp->mac_stats.xcvr_inuse =
    456 				    INT_MII_XCVR;
    457 				nxgep->mac.portmode = PORT_1G_COPPER;
    458 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    459 				    "1G Copper Xcvr"));
    460 			} else if (strcmp("pcs", prop_val) == 0) {
    461 				nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
    462 				nxgep->mac.portmode = PORT_1G_FIBER;
    463 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    464 				    "1G Fiber Xcvr"));
    465 			} else if (strcmp("xgc", prop_val) == 0) {
    466 				status = nxge_set_tn1010_param(nxgep);
    467 				if (status != NXGE_OK)
    468 					return (status);
    469 				NXGE_DEBUG_MSG((nxgep, MAC_CTL, "TN1010 Xcvr"));
    470 			} else if (strcmp("xgsd", prop_val) == 0) {
    471 				nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
    472 				nxgep->mac.portmode = PORT_10G_SERDES;
    473 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    474 				    "OBP: 10G Serdes"));
    475 			} else if (strcmp("gsd", prop_val) == 0) {
    476 				nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
    477 				nxgep->mac.portmode = PORT_1G_SERDES;
    478 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    479 				    "OBP: 1G Serdes"));
    480 			} else {
    481 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    482 				    "Unknown phy-type: %s", prop_val));
    483 				ddi_prop_free(prop_val);
    484 				return (NXGE_ERROR);
    485 			}
    486 			status = NXGE_OK;
    487 			(void) ddi_prop_update_string(DDI_DEV_T_NONE,
    488 			    nxgep->dip, "phy-type", prop_val);
    489 			ddi_prop_free(prop_val);
    490 
    491 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
    492 			    "Got phy type [0x%x] from OBP",
    493 			    nxgep->mac.portmode));
    494 
    495 			return (status);
    496 		} else {
    497 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
    498 			    "Exiting...phy-type property not found"));
    499 			return (NXGE_ERROR);
    500 		}
    501 	}
    502 
    503 
    504 	if (!nxgep->vpd_info.present) {
    505 		return (NXGE_OK);
    506 	}
    507 
    508 	if (!nxgep->vpd_info.ver_valid) {
    509 		goto read_seeprom;
    510 	}
    511 
    512 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    513 	    "Reading phy type from expansion ROM"));
    514 	/*
    515 	 * Try to read the phy type from the vpd data read off the
    516 	 * expansion ROM.
    517 	 */
    518 	phy_type = nxgep->vpd_info.phy_type;
    519 
    520 	if (strncmp(phy_type, "mif", 3) == 0) {
    521 		nxgep->mac.portmode = PORT_1G_COPPER;
    522 		nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
    523 	} else if (strncmp(phy_type, "xgf", 3) == 0) {
    524 		nxgep->mac.portmode = PORT_10G_FIBER;
    525 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
    526 	} else if (strncmp(phy_type, "pcs", 3) == 0) {
    527 		nxgep->mac.portmode = PORT_1G_FIBER;
    528 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
    529 	} else if (strncmp(phy_type, "xgc", 3) == 0) {
    530 		status = nxge_set_tn1010_param(nxgep);
    531 		if (status != NXGE_OK) {
    532 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
    533 			    "nxge_get_xcvr_type: Failed to set TN1010 param"));
    534 			goto read_seeprom;
    535 		}
    536 	} else if (strncmp(phy_type, "xgsd", 4) == 0) {
    537 		nxgep->mac.portmode = PORT_10G_SERDES;
    538 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
    539 	} else if (strncmp(phy_type, "gsd", 3) == 0) {
    540 		nxgep->mac.portmode = PORT_1G_SERDES;
    541 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
    542 	} else {
    543 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
    544 		    "nxge_get_xcvr_type: Unknown phy type [%c%c%c] in EEPROM",
    545 		    phy_type[0], phy_type[1], phy_type[2]));
    546 		goto read_seeprom;
    547 	}
    548 
    549 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
    550 	    "Got phy type [0x%x] from VPD", nxgep->mac.portmode));
    551 
    552 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type"));
    553 	return (status);
    554 
    555 read_seeprom:
    556 	/*
    557 	 * read the phy type from the SEEPROM - NCR registers
    558 	 */
    559 	status = nxge_espc_phy_type_get(nxgep);
    560 	if (status != NXGE_OK) {
    561 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
    562 		    "Failed to get phy type"));
    563 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version "
    564 		    "[%s] invalid...please update", nxgep->vpd_info.ver));
    565 	}
    566 
    567 	return (status);
    568 
    569 }
    570 
    571 /* Set up the PHY specific values. */
    572 
    573 nxge_status_t
    574 nxge_setup_xcvr_table(p_nxge_t nxgep)
    575 {
    576 	nxge_status_t	status = NXGE_OK;
    577 	uint32_t	port_type;
    578 	uint8_t		portn = NXGE_GET_PORT_NUM(nxgep->function_num);
    579 	uint32_t	pcs_id = 0;
    580 	uint32_t	pma_pmd_id = 0;
    581 	uint32_t	phy_id = 0;
    582 	uint16_t	chip_id = 0;
    583 
    584 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_setup_xcvr_table: port<%d>",
    585 	    portn));
    586 
    587 	switch (nxgep->niu_type) {
    588 	case N2_NIU:
    589 		switch (nxgep->mac.portmode) {
    590 		case PORT_1G_FIBER:
    591 		case PORT_1G_SERDES:
    592 			nxgep->xcvr = nxge_n2_1G_table;
    593 			nxgep->xcvr_addr = portn;
    594 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 1G %s Xcvr",
    595 			    (nxgep->mac.portmode == PORT_1G_FIBER) ? "Fiber" :
    596 			    "Serdes"));
    597 			break;
    598 		case PORT_10G_FIBER:
    599 		case PORT_10G_SERDES:
    600 			nxgep->xcvr = nxge_n2_10G_table;
    601 			if (nxgep->nxge_hw_p->xcvr_addr[portn]) {
    602 				nxgep->xcvr_addr =
    603 				    nxgep->nxge_hw_p->xcvr_addr[portn];
    604 			}
    605 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G %s Xcvr",
    606 			    (nxgep->mac.portmode == PORT_10G_FIBER) ? "Fiber" :
    607 			    "Serdes"));
    608 			break;
    609 		case PORT_1G_TN1010:
    610 			nxgep->xcvr = nxge_n2_1G_tn1010_table;
    611 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
    612 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    613 			    "TN1010 Copper Xcvr in 1G"));
    614 			break;
    615 		case PORT_10G_TN1010:
    616 			nxgep->xcvr = nxge_n2_10G_tn1010_table;
    617 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
    618 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    619 			    "TN1010 Copper Xcvr in 10G"));
    620 			break;
    621 		case PORT_HSP_MODE:
    622 			nxgep->xcvr = nxge_n2_10G_table;
    623 			nxgep->xcvr.xcvr_inuse = HSP_XCVR;
    624 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G Hot "
    625 			    "Swappable Xcvr (not present)"));
    626 			break;
    627 		default:
    628 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
    629 			    "<== nxge_setup_xcvr_table: "
    630 			    "Unable to determine NIU portmode"));
    631 			return (NXGE_ERROR);
    632 		}
    633 		break;
    634 	default:
    635 		if (nxgep->mac.portmode == 0) {
    636 			/*
    637 			 * Would be the case for platforms like Maramba
    638 			 * in which the phy type could not be got from conf
    639 			 * file, OBP, VPD or Serial PROM.
    640 			 */
    641 			if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
    642 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
    643 				    "<== nxge_setup_xcvr_table:"
    644 				    " Invalid Neptune type [0x%x]",
    645 				    nxgep->niu_type));
    646 				return (NXGE_ERROR);
    647 			}
    648 
    649 			port_type = nxgep->niu_type >>
    650 			    (NXGE_PORT_TYPE_SHIFT * portn);
    651 			port_type = port_type & (NXGE_PORT_TYPE_MASK);
    652 
    653 			switch (port_type) {
    654 
    655 			case NXGE_PORT_1G_COPPER:
    656 				nxgep->mac.portmode = PORT_1G_COPPER;
    657 				break;
    658 			case NXGE_PORT_10G_COPPER:
    659 				nxgep->mac.portmode = PORT_10G_COPPER;
    660 				break;
    661 			case NXGE_PORT_1G_FIBRE:
    662 				nxgep->mac.portmode = PORT_1G_FIBER;
    663 				break;
    664 			case NXGE_PORT_10G_FIBRE:
    665 				nxgep->mac.portmode = PORT_10G_FIBER;
    666 				break;
    667 			case NXGE_PORT_1G_SERDES:
    668 				nxgep->mac.portmode = PORT_1G_SERDES;
    669 				break;
    670 			case NXGE_PORT_10G_SERDES:
    671 				nxgep->mac.portmode = PORT_10G_SERDES;
    672 				break;
    673 			/* Ports 2 and 3 of Alonso or ARTM */
    674 			case NXGE_PORT_1G_RGMII_FIBER:
    675 				nxgep->mac.portmode = PORT_1G_RGMII_FIBER;
    676 				break;
    677 			case NXGE_PORT_TN1010:
    678 				/*
    679 				 * If this port uses the TN1010 copper
    680 				 * PHY, then its speed is not known yet
    681 				 * because nxge_scan_ports_phy could only
    682 				 * figure out the vendor of the PHY but
    683 				 * not its speed. nxge_set_tn1010_param
    684 				 * will read the PHY speed and set
    685 				 * portmode accordingly.
    686 				 */
    687 				if ((status = nxge_set_tn1010_param(nxgep))
    688 				    != NXGE_OK) {
    689 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
    690 					    "nxge_set_tn1010_param failed"));
    691 					return (status);
    692 				}
    693 				break;
    694 			default:
    695 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
    696 				    "<== nxge_setup_xcvr_table: "
    697 				    "Unknown port-type: 0x%x", port_type));
    698 				return (NXGE_ERROR);
    699 			}
    700 		}
    701 
    702 		/*
    703 		 * Above switch has figured out nxge->mac.portmode, now set
    704 		 * nxgep->xcvr (the table) and nxgep->xcvr_addr according
    705 		 * to portmode.
    706 		 */
    707 		switch (nxgep->mac.portmode) {
    708 		case PORT_1G_COPPER:
    709 		case PORT_1G_RGMII_FIBER:
    710 			nxgep->xcvr = nxge_1G_copper_table;
    711 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
    712 			/*
    713 			 * For Altas 4-1G copper, Xcvr port numbers are
    714 			 * swapped with ethernet port number. This is
    715 			 * designed for better signal integrity in
    716 			 * routing. This is also the case for the
    717 			 * on-board Neptune copper ports on the Maramba
    718 			 * platform.
    719 			 */
    720 			switch (nxgep->platform_type) {
    721 			case P_NEPTUNE_ATLAS_4PORT:
    722 			case P_NEPTUNE_MARAMBA_P0:
    723 			case P_NEPTUNE_MARAMBA_P1:
    724 				switch (portn) {
    725 				case 0:
    726 					nxgep->xcvr_addr += 3;
    727 					break;
    728 				case 1:
    729 					nxgep->xcvr_addr += 1;
    730 					break;
    731 				case 2:
    732 					nxgep->xcvr_addr -= 1;
    733 					break;
    734 				case 3:
    735 					nxgep->xcvr_addr -= 3;
    736 					break;
    737 				default:
    738 					return (NXGE_ERROR);
    739 				}
    740 				break;
    741 			default:
    742 				break;
    743 			}
    744 
    745 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
    746 			    (nxgep->mac.portmode == PORT_1G_COPPER) ?
    747 			    "Copper" : "RGMII Fiber"));
    748 			break;
    749 
    750 		case PORT_10G_COPPER:
    751 			nxgep->xcvr = nxge_10G_copper_table;
    752 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr"));
    753 			break;
    754 
    755 		case PORT_1G_TN1010:
    756 			nxgep->xcvr = nxge_1G_tn1010_table;
    757 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
    758 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    759 			    "1G TN1010 copper Xcvr"));
    760 			break;
    761 
    762 		case PORT_10G_TN1010:
    763 			nxgep->xcvr = nxge_10G_tn1010_table;
    764 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
    765 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    766 			    "10G TN1010 copper Xcvr"));
    767 			break;
    768 
    769 		case PORT_1G_FIBER:
    770 		case PORT_1G_SERDES:
    771 			nxgep->xcvr = nxge_1G_fiber_table;
    772 			nxgep->xcvr_addr = portn;
    773 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
    774 			    (nxgep->mac.portmode == PORT_1G_FIBER) ?
    775 			    "Fiber" : "Serdes"));
    776 			break;
    777 		case PORT_10G_FIBER:
    778 		case PORT_10G_SERDES:
    779 			nxgep->xcvr = nxge_10G_fiber_table;
    780 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G xcvr "
    781 			    "nxgep->nxge_hw_p->xcvr_addr[portn] = [%d] "
    782 			    "nxgep->xcvr_addr = [%d]",
    783 			    nxgep->nxge_hw_p->xcvr_addr[portn],
    784 			    nxgep->xcvr_addr));
    785 			if (nxgep->nxge_hw_p->xcvr_addr[portn]) {
    786 				nxgep->xcvr_addr =
    787 				    nxgep->nxge_hw_p->xcvr_addr[portn];
    788 			}
    789 			switch (nxgep->platform_type) {
    790 			case P_NEPTUNE_MARAMBA_P0:
    791 			case P_NEPTUNE_MARAMBA_P1:
    792 				/*
    793 				 * Switch off LED for corresponding copper
    794 				 * port
    795 				 */
    796 				nxge_bcm5464_link_led_off(nxgep);
    797 				break;
    798 			default:
    799 				break;
    800 			}
    801 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G %s Xcvr",
    802 			    (nxgep->mac.portmode == PORT_10G_FIBER) ?
    803 			    "Fiber" : "Serdes"));
    804 			break;
    805 
    806 		case PORT_HSP_MODE:
    807 			nxgep->xcvr = nxge_10G_fiber_table;
    808 			nxgep->xcvr.xcvr_inuse = HSP_XCVR;
    809 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Neptune 10G Hot "
    810 			    "Swappable Xcvr (not present)"));
    811 			break;
    812 		default:
    813 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
    814 			    "Unknown port-type: 0x%x", port_type));
    815 			return (NXGE_ERROR);
    816 		}
    817 	}
    818 
    819 	if (nxgep->mac.portmode == PORT_10G_FIBER) {
    820 		uint32_t pma_pmd_id;
    821 		pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep,
    822 		    nxgep->xcvr_addr);
    823 		if ((pma_pmd_id & BCM_PHY_ID_MASK) == MARVELL_88X201X_PHY_ID) {
    824 			chip_id = MRVL88X201X_CHIP_ID;
    825 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    826 			    "nxge_setup_xcvr_table: "
    827 			    "Chip ID  MARVELL [0x%x] for 10G xcvr", chip_id));
    828 		} else if ((status = nxge_mdio_read(nxgep, nxgep->xcvr_addr,
    829 		    BCM8704_PCS_DEV_ADDR, BCM8704_CHIP_ID_REG,
    830 		    &chip_id)) == NXGE_OK) {
    831 
    832 			switch (chip_id) {
    833 			case BCM8704_CHIP_ID:
    834 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    835 				    "nxge_setup_xcvr_table: "
    836 				    "Chip ID 8704 [0x%x] for 10G xcvr",
    837 				    chip_id));
    838 				break;
    839 			case BCM8706_CHIP_ID:
    840 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    841 				    "nxge_setup_xcvr_table: "
    842 				    "Chip ID 8706 [0x%x] for 10G xcvr",
    843 				    chip_id));
    844 				break;
    845 			default:
    846 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
    847 				    "nxge_setup_xcvr_table: "
    848 				    "Unknown Chip ID [0x%x] for 10G xcvr",
    849 				    chip_id));
    850 				break;
    851 			}
    852 		}
    853 	}
    854 
    855 	nxgep->statsp->mac_stats.xcvr_inuse = nxgep->xcvr.xcvr_inuse;
    856 	nxgep->statsp->mac_stats.xcvr_portn = nxgep->xcvr_addr;
    857 	nxgep->chip_id = chip_id;
    858 
    859 	/*
    860 	 * Get the actual device ID value returned by MDIO read.
    861 	 */
    862 	nxgep->statsp->mac_stats.xcvr_id = 0;
    863 
    864 	pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, nxgep->xcvr_addr);
    865 	if (nxge_is_supported_phy(pma_pmd_id, CLAUSE_45_TYPE)) {
    866 		nxgep->statsp->mac_stats.xcvr_id = pma_pmd_id;
    867 	} else {
    868 		pcs_id = nxge_get_cl45_pcs_id(nxgep, nxgep->xcvr_addr);
    869 		if (nxge_is_supported_phy(pcs_id, CLAUSE_45_TYPE)) {
    870 			nxgep->statsp->mac_stats.xcvr_id = pcs_id;
    871 		} else {
    872 			phy_id = nxge_get_cl22_phy_id(nxgep,
    873 			    nxgep->xcvr_addr);
    874 			if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) {
    875 				nxgep->statsp->mac_stats.xcvr_id = phy_id;
    876 			}
    877 		}
    878 	}
    879 
    880 	nxgep->mac.linkchkmode = LINKCHK_TIMER;
    881 
    882 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_setup_xcvr_table: niu_type"
    883 	    "[0x%x] platform type[0x%x] xcvr_addr[%d]", nxgep->niu_type,
    884 	    nxgep->platform_type, nxgep->xcvr_addr));
    885 
    886 	return (status);
    887 }
    888 
    889 /* Initialize the entire MAC and physical layer */
    890 
    891 nxge_status_t
    892 nxge_mac_init(p_nxge_t nxgep)
    893 {
    894 	uint8_t			portn;
    895 	nxge_status_t		status = NXGE_OK;
    896 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
    897 
    898 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn));
    899 
    900 	nxgep->mac.portnum = portn;
    901 	nxgep->mac.porttype = PORT_TYPE_XMAC;
    902 
    903 	if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1))
    904 		nxgep->mac.porttype = PORT_TYPE_BMAC;
    905 
    906 
    907 	/* Initialize XIF to configure a network mode */
    908 	if ((status = nxge_xif_init(nxgep)) != NXGE_OK) {
    909 		goto fail;
    910 	}
    911 
    912 	if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) {
    913 		goto fail;
    914 	}
    915 
    916 	/* Initialize TX and RX MACs */
    917 	/*
    918 	 * Always perform XIF init first, before TX and RX MAC init
    919 	 */
    920 	if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK)
    921 		goto fail;
    922 
    923 	if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
    924 		goto fail;
    925 
    926 	if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK)
    927 		goto fail;
    928 
    929 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
    930 		goto fail;
    931 
    932 	if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK)
    933 		goto fail;
    934 
    935 	if (nxgep->nxge_mac_state == NXGE_MAC_STARTED) {
    936 		if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
    937 			goto fail;
    938 	}
    939 
    940 	/* Initialize MAC control configuration */
    941 	if ((status = nxge_mac_ctrl_init(nxgep)) != NXGE_OK) {
    942 		goto fail;
    943 	}
    944 
    945 	nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize;
    946 
    947 	/* The Neptune Serdes needs to be reinitialized again */
    948 	if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
    949 	    ((nxgep->mac.portmode == PORT_1G_SERDES) ||
    950 	    (nxgep->mac.portmode == PORT_1G_TN1010) ||
    951 	    (nxgep->mac.portmode == PORT_1G_FIBER)) &&
    952 	    ((portn == 0) || (portn == 1))) {
    953 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    954 		    "nxge_mac_init: reinit Neptune 1G Serdes "));
    955 		if ((status = nxge_1G_serdes_init(nxgep)) != NXGE_OK) {
    956 			goto fail;
    957 		}
    958 	}
    959 
    960 
    961 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn));
    962 
    963 	return (NXGE_OK);
    964 fail:
    965 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
    966 	    "nxge_mac_init: failed to initialize MAC port<%d>", portn));
    967 	return (status);
    968 }
    969 
    970 /* Initialize the Ethernet Link */
    971 
    972 nxge_status_t
    973 nxge_link_init(p_nxge_t nxgep)
    974 {
    975 	nxge_status_t		status = NXGE_OK;
    976 	nxge_port_mode_t	portmode;
    977 #ifdef	NXGE_DEBUG
    978 	uint8_t			portn;
    979 
    980 	portn = nxgep->mac.portnum;
    981 
    982 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn));
    983 #endif
    984 	/* For Opus NEM, Serdes always needs to be initialized */
    985 
    986 	portmode = nxgep->mac.portmode;
    987 
    988 	/*
    989 	 * Workaround to get link up in both NIU ports. Some portmodes require
    990 	 * that the xcvr be initialized twice, the first time before calling
    991 	 * nxge_serdes_init.
    992 	 */
    993 	if (nxgep->niu_type == N2_NIU && (portmode != PORT_10G_SERDES) &&
    994 	    (portmode != PORT_10G_TN1010) &&
    995 	    (portmode != PORT_1G_TN1010) &&
    996 	    (portmode != PORT_1G_SERDES)) {
    997 		if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) {
    998 			goto fail;
    999 		}
   1000 	}
   1001 
   1002 	NXGE_DELAY(200000);
   1003 	/* Initialize internal serdes */
   1004 	if ((status = nxge_serdes_init(nxgep)) != NXGE_OK)
   1005 		goto fail;
   1006 	NXGE_DELAY(200000);
   1007 	if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK)
   1008 		goto fail;
   1009 
   1010 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn));
   1011 
   1012 	return (NXGE_OK);
   1013 
   1014 fail:
   1015 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_link_init: ",
   1016 	    "failed to initialize Ethernet link on port<%d>", portn));
   1017 
   1018 	return (status);
   1019 }
   1020 
   1021 
   1022 /* Initialize the XIF sub-block within the MAC */
   1023 
   1024 nxge_status_t
   1025 nxge_xif_init(p_nxge_t nxgep)
   1026 {
   1027 	uint32_t		xif_cfg = 0;
   1028 	npi_attr_t		ap;
   1029 	uint8_t			portn;
   1030 	nxge_port_t		portt;
   1031 	nxge_port_mode_t	portmode;
   1032 	p_nxge_stats_t		statsp;
   1033 	npi_status_t		rs = NPI_SUCCESS;
   1034 	npi_handle_t		handle;
   1035 
   1036 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
   1037 
   1038 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn));
   1039 
   1040 	handle = nxgep->npi_handle;
   1041 	portmode = nxgep->mac.portmode;
   1042 	portt = nxgep->mac.porttype;
   1043 	statsp = nxgep->statsp;
   1044 
   1045 	if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
   1046 	    ((nxgep->mac.portmode == PORT_1G_SERDES) ||
   1047 	    (nxgep->mac.portmode == PORT_1G_TN1010) ||
   1048 	    (nxgep->mac.portmode == PORT_1G_FIBER)) &&
   1049 	    ((portn == 0) || (portn == 1))) {
   1050 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1051 		    "nxge_xcvr_init: set ATCA mode"));
   1052 		npi_mac_mif_set_atca_mode(nxgep->npi_handle, B_TRUE);
   1053 	}
   1054 
   1055 	if (portt == PORT_TYPE_XMAC) {
   1056 
   1057 		/* Setup XIF Configuration for XMAC */
   1058 
   1059 		if ((portmode == PORT_10G_FIBER) ||
   1060 		    (portmode == PORT_10G_COPPER) ||
   1061 		    (portmode == PORT_10G_TN1010) ||
   1062 		    (portmode == PORT_HSP_MODE) ||
   1063 		    (portmode == PORT_10G_SERDES))
   1064 			xif_cfg |= CFG_XMAC_XIF_LFS;
   1065 
   1066 		/* Bypass PCS so that RGMII will be used */
   1067 		if (portmode == PORT_1G_COPPER) {
   1068 			xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS;
   1069 		}
   1070 
   1071 		/* Set MAC Internal Loopback if necessary */
   1072 		if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
   1073 			xif_cfg |= CFG_XMAC_XIF_LOOPBACK;
   1074 
   1075 		if (statsp->mac_stats.link_speed == 100)
   1076 			xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ;
   1077 
   1078 		xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT;
   1079 
   1080 		if ((portmode == PORT_10G_FIBER) ||
   1081 		    (portmode == PORT_10G_TN1010) ||
   1082 		    (portmode == PORT_1G_TN1010) ||
   1083 		    (portmode == PORT_HSP_MODE) ||
   1084 		    (portmode == PORT_10G_SERDES)) {
   1085 			/* Assume LED same for 1G and 10G */
   1086 			if (statsp->mac_stats.link_up) {
   1087 				xif_cfg |= CFG_XMAC_XIF_LED_POLARITY;
   1088 			} else {
   1089 				xif_cfg |= CFG_XMAC_XIF_LED_FORCE;
   1090 			}
   1091 		}
   1092 
   1093 		rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg);
   1094 		if (rs != NPI_SUCCESS)
   1095 			goto fail;
   1096 
   1097 		nxgep->mac.xif_config = xif_cfg;
   1098 
   1099 		/* Set Port Mode */
   1100 		if ((portmode == PORT_10G_FIBER) ||
   1101 		    (portmode == PORT_10G_COPPER) ||
   1102 		    (portmode == PORT_10G_TN1010) ||
   1103 		    (portmode == PORT_HSP_MODE) ||
   1104 		    (portmode == PORT_10G_SERDES)) {
   1105 			SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
   1106 			    MAC_XGMII_MODE, rs);
   1107 			if (rs != NPI_SUCCESS)
   1108 				goto fail;
   1109 			if (statsp->mac_stats.link_up) {
   1110 				if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
   1111 					goto fail;
   1112 			} else {
   1113 				if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
   1114 					goto fail;
   1115 			}
   1116 		} else if ((portmode == PORT_1G_FIBER) ||
   1117 		    (portmode == PORT_1G_COPPER) ||
   1118 		    (portmode == PORT_1G_SERDES) ||
   1119 		    (portmode == PORT_1G_TN1010) ||
   1120 		    (portmode == PORT_1G_RGMII_FIBER)) {
   1121 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1122 			    "nxge_xif_init: Port[%d] Mode[%d] Speed[%d]",
   1123 			    portn, portmode, statsp->mac_stats.link_speed));
   1124 			if (statsp->mac_stats.link_speed == 1000) {
   1125 				SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
   1126 				    MAC_GMII_MODE, rs);
   1127 			} else {
   1128 				SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
   1129 				    MAC_MII_MODE, rs);
   1130 			}
   1131 			if (rs != NPI_SUCCESS)
   1132 				goto fail;
   1133 		} else {
   1134 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1135 			    "nxge_xif_init: Unknown port mode (%d)"
   1136 			    " for port<%d>", portmode, portn));
   1137 			goto fail;
   1138 		}
   1139 
   1140 		/* Enable ATCA mode */
   1141 
   1142 	} else if (portt == PORT_TYPE_BMAC) {
   1143 
   1144 		/* Setup XIF Configuration for BMAC */
   1145 
   1146 		if ((portmode == PORT_1G_COPPER) ||
   1147 		    (portmode == PORT_1G_RGMII_FIBER)) {
   1148 			if (statsp->mac_stats.link_speed == 100)
   1149 				xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ;
   1150 		}
   1151 
   1152 		if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
   1153 			xif_cfg |= CFG_BMAC_XIF_LOOPBACK;
   1154 
   1155 		if (statsp->mac_stats.link_speed == 1000)
   1156 			xif_cfg |= CFG_BMAC_XIF_GMII_MODE;
   1157 
   1158 		xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT;
   1159 
   1160 		rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg);
   1161 		if (rs != NPI_SUCCESS)
   1162 			goto fail;
   1163 		nxgep->mac.xif_config = xif_cfg;
   1164 	}
   1165 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn));
   1166 	return (NXGE_OK);
   1167 fail:
   1168 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1169 	    "nxge_xif_init: Failed to initialize XIF port<%d>", portn));
   1170 	return (NXGE_ERROR | rs);
   1171 }
   1172 
   1173 
   1174 /*
   1175  * Initialize the PCS sub-block in the MAC.  Note that PCS does not
   1176  * support loopback like XPCS.
   1177  */
   1178 nxge_status_t
   1179 nxge_pcs_init(p_nxge_t nxgep)
   1180 {
   1181 	pcs_cfg_t		pcs_cfg;
   1182 	uint32_t		val;
   1183 	uint8_t			portn;
   1184 	nxge_port_mode_t	portmode;
   1185 	npi_handle_t		handle;
   1186 	p_nxge_stats_t		statsp;
   1187 	pcs_ctrl_t		pcs_ctrl;
   1188 	npi_status_t		rs = NPI_SUCCESS;
   1189 	uint8_t i;
   1190 
   1191 	handle = nxgep->npi_handle;
   1192 	portmode = nxgep->mac.portmode;
   1193 	portn = nxgep->mac.portnum;
   1194 	statsp = nxgep->statsp;
   1195 
   1196 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn));
   1197 
   1198 	if (portmode == PORT_1G_FIBER ||
   1199 	    portmode == PORT_1G_TN1010 ||
   1200 	    portmode == PORT_1G_SERDES) {
   1201 		if (portmode == PORT_1G_TN1010) {
   1202 			/* Reset PCS multiple time in PORT_1G_TN1010 mode */
   1203 			for (i = 0; i < 6; i ++) {
   1204 				if ((rs = npi_mac_pcs_reset(handle, portn))
   1205 				    != NPI_SUCCESS) {
   1206 					goto fail;
   1207 				}
   1208 			}
   1209 		} else {
   1210 			if ((rs = npi_mac_pcs_reset(handle, portn))
   1211 			    != NPI_SUCCESS)
   1212 				goto fail;
   1213 		}
   1214 
   1215 		/* Initialize port's PCS */
   1216 		pcs_cfg.value = 0;
   1217 		pcs_cfg.bits.w0.enable = 1;
   1218 		pcs_cfg.bits.w0.mask = 1;
   1219 		PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value);
   1220 		PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0);
   1221 
   1222 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1223 		    "==> nxge_pcs_init: (1G) port<%d> write config 0x%llx",
   1224 		    portn, pcs_cfg.value));
   1225 
   1226 		if (portmode == PORT_1G_TN1010) {
   1227 			/*
   1228 			 * Must disable PCS auto-negotiation when the the driver
   1229 			 * is driving the TN1010 based XAUI card  Otherwise the
   1230 			 * autonegotiation between the PCS and the TN1010 PCS
   1231 			 * will never complete and the Neptune/NIU will not work
   1232 			 */
   1233 			pcs_ctrl.value = 0;
   1234 			PCS_REG_WR(handle, portn, PCS_MII_CTRL_REG,
   1235 			    pcs_ctrl.value);
   1236 		}
   1237 	} else if (portmode == PORT_10G_FIBER ||
   1238 	    portmode == PORT_10G_COPPER ||
   1239 	    portmode == PORT_10G_TN1010 ||
   1240 	    portmode == PORT_HSP_MODE ||
   1241 	    portmode == PORT_10G_SERDES) {
   1242 		/* Use internal XPCS, bypass 1G PCS */
   1243 		XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val);
   1244 		val &= ~XMAC_XIF_XPCS_BYPASS;
   1245 		XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val);
   1246 
   1247 		if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS)
   1248 			goto fail;
   1249 
   1250 		/* Set XPCS Internal Loopback if necessary */
   1251 		if ((rs = npi_xmac_xpcs_read(handle, portn,
   1252 		    XPCS_REG_CONTROL1, &val)) != NPI_SUCCESS)
   1253 			goto fail;
   1254 
   1255 		if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) ||
   1256 		    (statsp->port_stats.lb_mode == nxge_lb_mac1000))
   1257 			val |= XPCS_CTRL1_LOOPBK;
   1258 		else
   1259 			val &= ~XPCS_CTRL1_LOOPBK;
   1260 		if ((rs = npi_xmac_xpcs_write(handle, portn,
   1261 		    XPCS_REG_CONTROL1, val)) != NPI_SUCCESS)
   1262 			goto fail;
   1263 
   1264 		/* Clear descw errors */
   1265 		if ((rs = npi_xmac_xpcs_write(handle, portn,
   1266 		    XPCS_REG_DESCWERR_COUNTER, 0)) != NPI_SUCCESS)
   1267 			goto fail;
   1268 		/* Clear symbol errors */
   1269 		if ((rs = npi_xmac_xpcs_read(handle, portn,
   1270 		    XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val)) != NPI_SUCCESS)
   1271 			goto fail;
   1272 		if ((rs = npi_xmac_xpcs_read(handle, portn,
   1273 		    XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val)) != NPI_SUCCESS)
   1274 			goto fail;
   1275 
   1276 	} else if ((portmode == PORT_1G_COPPER) ||
   1277 	    (portmode == PORT_1G_RGMII_FIBER)) {
   1278 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1279 		    "==> nxge_pcs_init: (1G) copper port<%d>", portn));
   1280 		if (portn < 4) {
   1281 			PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG,
   1282 			    PCS_DATAPATH_MODE_MII);
   1283 		}
   1284 		if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS)
   1285 			goto fail;
   1286 
   1287 	} else {
   1288 		goto fail;
   1289 	}
   1290 pass:
   1291 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn));
   1292 	return (NXGE_OK);
   1293 fail:
   1294 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1295 	    "nxge_pcs_init: Failed to initialize PCS port<%d>", portn));
   1296 	return (NXGE_ERROR | rs);
   1297 }
   1298 
   1299 /*
   1300  * Initialize the MAC CTRL sub-block within the MAC
   1301  * Only the receive-pause-cap is supported.
   1302  */
   1303 nxge_status_t
   1304 nxge_mac_ctrl_init(p_nxge_t nxgep)
   1305 {
   1306 	uint8_t			portn;
   1307 	nxge_port_t		portt;
   1308 	p_nxge_stats_t		statsp;
   1309 	npi_handle_t		handle;
   1310 	uint32_t		val;
   1311 
   1312 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
   1313 
   1314 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_ctrl_init: port<%d>",
   1315 	    portn));
   1316 
   1317 	handle = nxgep->npi_handle;
   1318 	portt = nxgep->mac.porttype;
   1319 	statsp = nxgep->statsp;
   1320 
   1321 	if (portt == PORT_TYPE_XMAC) {
   1322 		/* Reading the current XMAC Config Register for XMAC */
   1323 		XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val);
   1324 
   1325 		/*
   1326 		 * Setup XMAC Configuration for XMAC
   1327 		 * XMAC only supports receive-pause
   1328 		 */
   1329 		if (statsp->mac_stats.adv_cap_asmpause) {
   1330 			if (!statsp->mac_stats.adv_cap_pause) {
   1331 				/*
   1332 				 * If adv_cap_asmpause is 1 and adv_cap_pause
   1333 				 * is 0, enable receive pause.
   1334 				 */
   1335 				val |= XMAC_RX_CFG_RX_PAUSE_EN;
   1336 			} else {
   1337 				/*
   1338 				 * If adv_cap_asmpause is 1 and adv_cap_pause
   1339 				 * is 1, disable receive pause.  Send pause is
   1340 				 * not supported.
   1341 				 */
   1342 				val &= ~XMAC_RX_CFG_RX_PAUSE_EN;
   1343 			}
   1344 		} else {
   1345 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1346 			    "==> nxge_mac_ctrl_init: port<%d>: pause",
   1347 			    portn));
   1348 			if (statsp->mac_stats.adv_cap_pause) {
   1349 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1350 				    "==> nxge_mac_ctrl_init: port<%d>: "
   1351 				    "enable pause", portn));
   1352 				/*
   1353 				 * If adv_cap_asmpause is 0 and adv_cap_pause
   1354 				 * is 1, enable receive pause.
   1355 				 */
   1356 				val |= XMAC_RX_CFG_RX_PAUSE_EN;
   1357 			} else {
   1358 				/*
   1359 				 * If adv_cap_asmpause is 0 and adv_cap_pause
   1360 				 * is 0, disable receive pause. Send pause is
   1361 				 * not supported
   1362 				 */
   1363 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1364 				    "==> nxge_mac_ctrl_init: port<%d>: "
   1365 				    "disable pause", portn));
   1366 				val &= ~XMAC_RX_CFG_RX_PAUSE_EN;
   1367 			}
   1368 		}
   1369 		XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val);
   1370 	} else if (portt == PORT_TYPE_BMAC) {
   1371 		/* Reading the current MAC CTRL Config Register for BMAC */
   1372 		BMAC_REG_RD(handle, portn, MAC_CTRL_CONFIG_REG, &val);
   1373 
   1374 		/* Setup MAC CTRL Configuration for BMAC */
   1375 		if (statsp->mac_stats.adv_cap_asmpause) {
   1376 			if (statsp->mac_stats.adv_cap_pause) {
   1377 				/*
   1378 				 * If adv_cap_asmpause is 1 and adv_cap_pause
   1379 				 * is 1, disable receive pause. Send pause
   1380 				 * is not supported
   1381 				 */
   1382 				val &= ~MAC_CTRL_CFG_RECV_PAUSE_EN;
   1383 			} else {
   1384 				/*
   1385 				 * If adv_cap_asmpause is 1 and adv_cap_pause
   1386 				 * is 0, enable receive pause and disable
   1387 				 * send pause.
   1388 				 */
   1389 				val |= MAC_CTRL_CFG_RECV_PAUSE_EN;
   1390 				val &= ~MAC_CTRL_CFG_SEND_PAUSE_EN;
   1391 			}
   1392 		} else {
   1393 			if (statsp->mac_stats.adv_cap_pause) {
   1394 				/*
   1395 				 * If adv_cap_asmpause is 0 and adv_cap_pause
   1396 				 * is 1, enable receive pause. Send pause is
   1397 				 * not supported.
   1398 				 */
   1399 				val |= MAC_CTRL_CFG_RECV_PAUSE_EN;
   1400 			} else {
   1401 				/*
   1402 				 * If adv_cap_asmpause is 0 and adv_cap_pause
   1403 				 * is 0, pause capability is not available in
   1404 				 * either direction.
   1405 				 */
   1406 				val &= (~MAC_CTRL_CFG_SEND_PAUSE_EN &
   1407 				    ~MAC_CTRL_CFG_RECV_PAUSE_EN);
   1408 			}
   1409 		}
   1410 		BMAC_REG_WR(handle, portn, MAC_CTRL_CONFIG_REG, val);
   1411 	}
   1412 
   1413 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_ctrl_init: port<%d>",
   1414 	    portn));
   1415 
   1416 	return (NXGE_OK);
   1417 }
   1418 
   1419 /* Initialize the Internal Serdes */
   1420 
   1421 nxge_status_t
   1422 nxge_serdes_init(p_nxge_t nxgep)
   1423 {
   1424 	p_nxge_stats_t		statsp;
   1425 #ifdef	NXGE_DEBUG
   1426 	uint8_t			portn;
   1427 #endif
   1428 	nxge_status_t		status = NXGE_OK;
   1429 
   1430 #ifdef	NXGE_DEBUG
   1431 	portn = nxgep->mac.portnum;
   1432 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1433 	    "==> nxge_serdes_init port<%d>", portn));
   1434 #endif
   1435 
   1436 	if (nxgep->xcvr.serdes_init) {
   1437 		statsp = nxgep->statsp;
   1438 		status = nxgep->xcvr.serdes_init(nxgep);
   1439 		if (status != NXGE_OK)
   1440 			goto fail;
   1441 		statsp->mac_stats.serdes_inits++;
   1442 	}
   1443 
   1444 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>",
   1445 	    portn));
   1446 
   1447 	return (NXGE_OK);
   1448 
   1449 fail:
   1450 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1451 	    "nxge_serdes_init: Failed to initialize serdes for port<%d>",
   1452 	    portn));
   1453 
   1454 	return (status);
   1455 }
   1456 
   1457 /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */
   1458 
   1459 static nxge_status_t
   1460 nxge_n2_serdes_init(p_nxge_t nxgep)
   1461 {
   1462 	uint8_t portn;
   1463 	int chan;
   1464 	esr_ti_cfgpll_l_t pll_cfg_l;
   1465 	esr_ti_cfgpll_l_t pll_sts_l;
   1466 	esr_ti_cfgrx_l_t rx_cfg_l;
   1467 	esr_ti_cfgrx_h_t rx_cfg_h;
   1468 	esr_ti_cfgtx_l_t tx_cfg_l;
   1469 	esr_ti_cfgtx_h_t tx_cfg_h;
   1470 #ifdef NXGE_DEBUG
   1471 	esr_ti_testcfg_t cfg;
   1472 #endif
   1473 	esr_ti_testcfg_t test_cfg;
   1474 	nxge_status_t status = NXGE_OK;
   1475 
   1476 	portn = nxgep->mac.portnum;
   1477 
   1478 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>",
   1479 	    portn));
   1480 	if (nxgep->niu_hw_type == NIU_HW_TYPE_RF) {
   1481 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1482 		    "==> nxge_n2_serdes_init port<%d>: KT-NIU", portn));
   1483 		return (nxge_n2_kt_serdes_init(nxgep));
   1484 	}
   1485 
   1486 	tx_cfg_l.value = 0;
   1487 	tx_cfg_h.value = 0;
   1488 	rx_cfg_l.value = 0;
   1489 	rx_cfg_h.value = 0;
   1490 	pll_cfg_l.value = 0;
   1491 	pll_sts_l.value = 0;
   1492 	test_cfg.value = 0;
   1493 
   1494 	/*
   1495 	 * If the nxge driver has been plumbed without a link, then it will
   1496 	 * detect a link up when a cable connecting to an anto-negotiation
   1497 	 * partner is plugged into the port. Because the TN1010 PHY supports
   1498 	 * both 1G and 10G speeds, the driver must re-configure the
   1499 	 * Neptune/NIU according to the negotiated speed.  nxge_n2_serdes_init
   1500 	 * is called at the post-link-up reconfiguration time. Here it calls
   1501 	 * nxge_set_tn1010_param to set portmode before re-initializing
   1502 	 * the serdes.
   1503 	 */
   1504 	if (nxgep->mac.portmode == PORT_1G_TN1010 ||
   1505 	    nxgep->mac.portmode == PORT_10G_TN1010) {
   1506 		if (nxge_set_tn1010_param(nxgep) != NXGE_OK) {
   1507 			goto fail;
   1508 		}
   1509 	}
   1510 
   1511 	if (nxgep->mac.portmode == PORT_10G_FIBER ||
   1512 	    nxgep->mac.portmode == PORT_10G_TN1010 ||
   1513 	    nxgep->mac.portmode == PORT_HSP_MODE ||
   1514 	    nxgep->mac.portmode == PORT_10G_SERDES) {
   1515 		/* 0x0E01 */
   1516 		tx_cfg_l.bits.entx = 1;
   1517 		tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
   1518 
   1519 		/* 0x9101 */
   1520 		rx_cfg_l.bits.enrx = 1;
   1521 		rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
   1522 		rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
   1523 		rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
   1524 
   1525 		/* 0x0008 */
   1526 		rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
   1527 
   1528 		/* Set loopback mode if necessary */
   1529 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
   1530 			tx_cfg_l.bits.entest = 1;
   1531 			rx_cfg_l.bits.entest = 1;
   1532 			test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
   1533 			if ((status = nxge_mdio_write(nxgep, portn,
   1534 			    ESR_N2_DEV_ADDR,
   1535 			    ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK)
   1536 			goto fail;
   1537 		}
   1538 
   1539 		/* Initialize PLL for 10G */
   1540 		pll_cfg_l.bits.mpy = CFGPLL_MPY_10X;
   1541 		pll_cfg_l.bits.enpll = 1;
   1542 		pll_sts_l.bits.enpll = 1;
   1543 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1544 		    ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK)
   1545 			goto fail;
   1546 
   1547 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1548 		    ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK)
   1549 			goto fail;
   1550 
   1551 #ifdef  NXGE_DEBUG
   1552 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
   1553 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
   1554 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1555 		    "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
   1556 		    portn, pll_cfg_l.value, cfg.value));
   1557 
   1558 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
   1559 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
   1560 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1561 		    "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)",
   1562 		    portn, pll_sts_l.value, cfg.value));
   1563 #endif
   1564 	} else if (nxgep->mac.portmode == PORT_1G_FIBER ||
   1565 	    nxgep->mac.portmode == PORT_1G_TN1010 ||
   1566 	    nxgep->mac.portmode == PORT_1G_SERDES) {
   1567 		/* 0x0E21 */
   1568 		tx_cfg_l.bits.entx = 1;
   1569 		tx_cfg_l.bits.rate = CFGTX_RATE_HALF;
   1570 		tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
   1571 
   1572 		/* 0x9121 */
   1573 		rx_cfg_l.bits.enrx = 1;
   1574 		rx_cfg_l.bits.rate = CFGRX_RATE_HALF;
   1575 		rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
   1576 		rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
   1577 		rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
   1578 
   1579 		if (portn == 0) {
   1580 			/* 0x8 */
   1581 			rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
   1582 		}
   1583 
   1584 		/* Initialize PLL for 1G */
   1585 		pll_cfg_l.bits.mpy = CFGPLL_MPY_8X;
   1586 		pll_cfg_l.bits.enpll = 1;
   1587 		pll_sts_l.bits.enpll = 1;
   1588 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1589 		    ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK)
   1590 			goto fail;
   1591 
   1592 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1593 		    ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK)
   1594 			goto fail;
   1595 
   1596 #ifdef  NXGE_DEBUG
   1597 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
   1598 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
   1599 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1600 		    "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
   1601 		    portn, pll_cfg_l.value, cfg.value));
   1602 
   1603 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
   1604 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
   1605 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1606 		    "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)",
   1607 		    portn, pll_sts_l.value, cfg.value));
   1608 #endif
   1609 
   1610 		/* Set loopback mode if necessary */
   1611 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
   1612 			tx_cfg_l.bits.entest = 1;
   1613 			rx_cfg_l.bits.entest = 1;
   1614 			test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
   1615 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1616 			    "==> nxge_n2_serdes_init port<%d>: loopback 0x%x",
   1617 			    portn, test_cfg.value));
   1618 			if ((status = nxge_mdio_write(nxgep, portn,
   1619 			    ESR_N2_DEV_ADDR,
   1620 			    ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) {
   1621 				goto fail;
   1622 			}
   1623 		}
   1624 	} else {
   1625 		goto fail;
   1626 	}
   1627 
   1628 	/*   MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */
   1629 
   1630 	NXGE_DELAY(20);
   1631 
   1632 	/* init TX channels */
   1633 	for (chan = 0; chan < 4; chan++) {
   1634 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1635 		    ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) != NXGE_OK)
   1636 			goto fail;
   1637 
   1638 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1639 		    ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) != NXGE_OK)
   1640 			goto fail;
   1641 
   1642 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1643 		    "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_l 0x%x",
   1644 		    portn, chan, tx_cfg_l.value));
   1645 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1646 		    "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_h 0x%x",
   1647 		    portn, chan, tx_cfg_h.value));
   1648 	}
   1649 
   1650 	/* init RX channels */
   1651 	for (chan = 0; chan < 4; chan++) {
   1652 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1653 		    ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value)) != NXGE_OK)
   1654 			goto fail;
   1655 
   1656 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1657 		    ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value)) != NXGE_OK)
   1658 			goto fail;
   1659 
   1660 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1661 		    "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_l 0x%x",
   1662 		    portn, chan, rx_cfg_l.value));
   1663 
   1664 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1665 		    "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_h 0x%x",
   1666 		    portn, chan, rx_cfg_h.value));
   1667 	}
   1668 
   1669 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>",
   1670 	    portn));
   1671 
   1672 	return (NXGE_OK);
   1673 fail:
   1674 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   1675 	    "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>",
   1676 	    portn));
   1677 
   1678 	return (status);
   1679 
   1680 }
   1681 
   1682 /* Initialize the TI Hedwig Internal Serdes (N2-KT-NIU only) */
   1683 
   1684 static nxge_status_t
   1685 nxge_n2_kt_serdes_init(p_nxge_t nxgep)
   1686 {
   1687 	uint8_t portn;
   1688 	int chan;
   1689 	k_esr_ti_cfgpll_l_t pll_cfg_l;
   1690 	k_esr_ti_cfgrx_l_t rx_cfg_l;
   1691 	k_esr_ti_cfgrx_h_t rx_cfg_h;
   1692 	k_esr_ti_cfgtx_l_t tx_cfg_l;
   1693 	k_esr_ti_cfgtx_h_t tx_cfg_h;
   1694 #ifdef NXGE_DEBUG
   1695 	k_esr_ti_testcfg_t cfg;
   1696 #endif
   1697 	k_esr_ti_testcfg_t test_cfg;
   1698 	nxge_status_t status = NXGE_OK;
   1699 	boolean_t mode_1g = B_FALSE;
   1700 
   1701 	portn = nxgep->mac.portnum;
   1702 
   1703 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1704 	    "==> nxge_n2_kt_serdes_init port<%d>", portn));
   1705 
   1706 	tx_cfg_l.value = 0;
   1707 	tx_cfg_h.value = 0;
   1708 	rx_cfg_l.value = 0;
   1709 	rx_cfg_h.value = 0;
   1710 	pll_cfg_l.value = 0;
   1711 	test_cfg.value = 0;
   1712 
   1713 	/*
   1714 	 * The following setting assumes the reference clock frquency
   1715 	 * is 156.25 MHz.
   1716 	 */
   1717 	/*
   1718 	 * If the nxge driver has been plumbed without a link, then it will
   1719 	 * detect a link up when a cable connecting to an anto-negotiation
   1720 	 * partner is plugged into the port. Because the TN1010 PHY supports
   1721 	 * both 1G and 10G speeds, the driver must re-configure the
   1722 	 * Neptune/NIU according to the negotiated speed.  nxge_n2_serdes_init
   1723 	 * is called at the post-link-up reconfiguration time. Here it calls
   1724 	 * nxge_set_tn1010_param to set portmode before re-initializing
   1725 	 * the serdes.
   1726 	 */
   1727 	if (nxgep->mac.portmode == PORT_1G_TN1010 ||
   1728 	    nxgep->mac.portmode == PORT_10G_TN1010) {
   1729 		if (nxge_set_tn1010_param(nxgep) != NXGE_OK) {
   1730 			goto fail;
   1731 		}
   1732 	}
   1733 	if (nxgep->mac.portmode == PORT_10G_FIBER ||
   1734 	    nxgep->mac.portmode == PORT_10G_TN1010 ||
   1735 	    nxgep->mac.portmode == PORT_10G_SERDES) {
   1736 		tx_cfg_l.bits.entx = K_CFGTX_ENABLE_TX;
   1737 		/* 0x1e21 */
   1738 		tx_cfg_l.bits.swing = K_CFGTX_SWING_2000MV;
   1739 		tx_cfg_l.bits.rate = K_CFGTX_RATE_HALF;
   1740 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1741 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_l 0x%x",
   1742 		    portn, tx_cfg_l.value));
   1743 
   1744 		/* channel 0: enable syn. master */
   1745 		/* 0x40 */
   1746 		tx_cfg_h.bits.msync = K_CFGTX_ENABLE_MSYNC;
   1747 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1748 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x",
   1749 		    portn, tx_cfg_h.value));
   1750 		/* 0x4821 */
   1751 		rx_cfg_l.bits.enrx = K_CFGRX_ENABLE_RX;
   1752 		rx_cfg_l.bits.rate = K_CFGRX_RATE_HALF;
   1753 		rx_cfg_l.bits.align = K_CFGRX_ALIGN_EN;
   1754 		rx_cfg_l.bits.los = K_CFGRX_LOS_ENABLE;
   1755 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1756 		    "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_l 0x%x",
   1757 		    portn, rx_cfg_l.value));
   1758 
   1759 		/* 0x0008 */
   1760 		rx_cfg_h.bits.eq = K_CFGRX_EQ_ADAPTIVE;
   1761 
   1762 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1763 		    "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_h 0x%x",
   1764 		    portn, rx_cfg_h.value));
   1765 
   1766 		/* Set loopback mode if necessary */
   1767 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
   1768 			tx_cfg_h.bits.loopback = K_CFGTX_INNER_CML_ENA_LOOPBACK;
   1769 			rx_cfg_h.bits.loopback = K_CFGTX_INNER_CML_ENA_LOOPBACK;
   1770 			rx_cfg_l.bits.los = 0;
   1771 
   1772 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1773 			    "==> nxge_n2_kt_serdes_init port<%d>: "
   1774 			    "loopback 0x%x", portn, tx_cfg_h.value));
   1775 		}
   1776 		/* 0xa1: Initialize PLL for 10G */
   1777 		pll_cfg_l.bits.mpy = K_CFGPLL_MPY_20X;
   1778 		pll_cfg_l.bits.enpll = K_CFGPLL_ENABLE_PLL;
   1779 
   1780 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1781 		    "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x",
   1782 		    portn, pll_cfg_l.value));
   1783 
   1784 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1785 		    ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value)) != NXGE_OK)
   1786 			goto fail;
   1787 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1788 		    "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x",
   1789 		    portn, pll_cfg_l.value));
   1790 #ifdef  NXGE_DEBUG
   1791 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
   1792 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
   1793 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   1794 		    "==> nxge_n2_kt_serdes_init port<%d>: "
   1795 		    "PLL cfg.l 0x%x (0x%x)",
   1796 		    portn, pll_cfg_l.value, cfg.value));
   1797 
   1798 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
   1799 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
   1800 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   1801 		    "==> nxge_n2_kt_serdes_init port<%d>: (0x%x)",
   1802 		    portn, cfg.value));
   1803 #endif
   1804 	} else if (nxgep->mac.portmode == PORT_1G_FIBER ||
   1805 	    nxgep->mac.portmode == PORT_1G_TN1010 ||
   1806 	    nxgep->mac.portmode == PORT_1G_SERDES) {
   1807 		mode_1g = B_TRUE;
   1808 		/* 0x1e41 */
   1809 		tx_cfg_l.bits.entx = 1;
   1810 		tx_cfg_l.bits.rate = K_CFGTX_RATE_HALF;
   1811 		tx_cfg_l.bits.swing = K_CFGTX_SWING_2000MV;
   1812 
   1813 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1814 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_l 0x%x",
   1815 		    portn, tx_cfg_l.value));
   1816 
   1817 
   1818 		/* channel 0: enable syn. master */
   1819 		tx_cfg_h.bits.msync = K_CFGTX_ENABLE_MSYNC;
   1820 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1821 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x",
   1822 		    portn, tx_cfg_h.value));
   1823 
   1824 
   1825 		/* 0x4841 */
   1826 		rx_cfg_l.bits.enrx = 1;
   1827 		rx_cfg_l.bits.rate = K_CFGRX_RATE_HALF;
   1828 		rx_cfg_l.bits.align = K_CFGRX_ALIGN_EN;
   1829 		rx_cfg_l.bits.los = K_CFGRX_LOS_ENABLE;
   1830 
   1831 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1832 		    "==> nxge_n2_kt_serdes_init port<%d> rx_cfg_l 0x%x",
   1833 		    portn, rx_cfg_l.value));
   1834 
   1835 		/* 0x0008 */
   1836 		rx_cfg_h.bits.eq = K_CFGRX_EQ_ADAPTIVE_LF_365MHZ_ZF;
   1837 
   1838 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1839 		    "==> nxge_n2_kt_serdes_init port<%d> tx_cfg_h 0x%x",
   1840 		    portn, rx_cfg_h.value));
   1841 
   1842 		/* 0xa1: Initialize PLL for 1G */
   1843 		pll_cfg_l.bits.mpy = K_CFGPLL_MPY_20X;
   1844 		pll_cfg_l.bits.enpll = K_CFGPLL_ENABLE_PLL;
   1845 
   1846 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1847 		    "==> nxge_n2_kt_serdes_init port<%d> pll_cfg_l 0x%x",
   1848 		    portn, pll_cfg_l.value));
   1849 
   1850 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1851 		    ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value))
   1852 		    != NXGE_OK)
   1853 			goto fail;
   1854 
   1855 
   1856 #ifdef  NXGE_DEBUG
   1857 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
   1858 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
   1859 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   1860 		    "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
   1861 		    portn, pll_cfg_l.value, cfg.value));
   1862 
   1863 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
   1864 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
   1865 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   1866 		    "==> nxge_n2_kt_serdes_init port<%d>: (0x%x)",
   1867 		    portn, cfg.value));
   1868 #endif
   1869 
   1870 		/* Set loopback mode if necessary */
   1871 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
   1872 			tx_cfg_h.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
   1873 
   1874 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1875 			    "==> nxge_n2_kt_serdes_init port<%d>: "
   1876 			    "loopback 0x%x", portn, test_cfg.value));
   1877 			if ((status = nxge_mdio_write(nxgep, portn,
   1878 			    ESR_N2_DEV_ADDR,
   1879 			    ESR_N2_TX_CFG_L_REG_ADDR(0),
   1880 			    tx_cfg_h.value)) != NXGE_OK) {
   1881 				goto fail;
   1882 			}
   1883 		}
   1884 	} else {
   1885 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   1886 		    "nxge_n2_kt_serdes_init:port<%d> - "
   1887 		    "unsupported port mode %d",
   1888 		    portn, nxgep->mac.portmode));
   1889 		goto fail;
   1890 	}
   1891 
   1892 	NXGE_DELAY(20);
   1893 	/* Clear the test register (offset 0x8004) */
   1894 	if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1895 	    ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) {
   1896 		goto fail;
   1897 	}
   1898 	NXGE_DELAY(20);
   1899 
   1900 	/* init TX channels */
   1901 	for (chan = 0; chan < 4; chan++) {
   1902 		if (mode_1g)
   1903 			tx_cfg_l.value = 0;
   1904 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1905 		    ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value)) != NXGE_OK)
   1906 			goto fail;
   1907 
   1908 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1909 		    ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value)) != NXGE_OK)
   1910 			goto fail;
   1911 
   1912 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1913 		    "==> nxge_n2_kt_serdes_init port<%d>: "
   1914 		    "chan %d tx_cfg_l 0x%x", portn, chan, tx_cfg_l.value));
   1915 
   1916 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1917 		    "==> nxge_n2_kt_serdes_init port<%d>: "
   1918 		    "chan %d tx_cfg_h 0x%x", portn, chan, tx_cfg_h.value));
   1919 	}
   1920 
   1921 	/* init RX channels */
   1922 	/* 1G mode only write to the first channel */
   1923 	for (chan = 0; chan < 4; chan++) {
   1924 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1925 		    ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value))
   1926 		    != NXGE_OK)
   1927 			goto fail;
   1928 
   1929 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
   1930 		    ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value))
   1931 		    != NXGE_OK)
   1932 			goto fail;
   1933 
   1934 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1935 		    "==> nxge_n2_kt_serdes_init port<%d>: "
   1936 		    "chan %d rx_cfg_l 0x%x", portn, chan, rx_cfg_l.value));
   1937 
   1938 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1939 		    "==> nxge_n2_kt_serdes_init port<%d>: "
   1940 		    "chan %d rx_cfg_h 0x%x", portn, chan, rx_cfg_h.value));
   1941 	}
   1942 
   1943 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1944 	    "<== nxge_n2_kt_serdes_init port<%d>", portn));
   1945 
   1946 	return (NXGE_OK);
   1947 fail:
   1948 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   1949 	    "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>",
   1950 	    portn));
   1951 
   1952 	return (status);
   1953 }
   1954 
   1955 /* Initialize the Neptune Internal Serdes for 10G (Neptune only) */
   1956 
   1957 static nxge_status_t
   1958 nxge_neptune_10G_serdes_init(p_nxge_t nxgep)
   1959 {
   1960 	npi_handle_t		handle;
   1961 	uint8_t			portn;
   1962 	int			chan, i;
   1963 	sr_rx_tx_ctrl_l_t	rx_tx_ctrl_l;
   1964 	sr_rx_tx_ctrl_h_t	rx_tx_ctrl_h;
   1965 	sr_glue_ctrl0_l_t	glue_ctrl0_l;
   1966 	sr_glue_ctrl0_h_t	glue_ctrl0_h;
   1967 	uint64_t		val;
   1968 	uint16_t		val16l;
   1969 	uint16_t		val16h;
   1970 	nxge_status_t		status = NXGE_OK;
   1971 
   1972 	portn = nxgep->mac.portnum;
   1973 
   1974 	if ((portn != 0) && (portn != 1))
   1975 		return (NXGE_OK);
   1976 
   1977 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   1978 	    "==> nxge_neptune_10G_serdes_init port<%d>", portn));
   1979 	handle = nxgep->npi_handle;
   1980 	switch (portn) {
   1981 	case 0:
   1982 		/* Reset Serdes */
   1983 		ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0);
   1984 		NXGE_DELAY(20);
   1985 		ESR_REG_WR(handle, ESR_RESET_REG, 0x0);
   1986 		NXGE_DELAY(2000);
   1987 
   1988 		/* Configure Serdes to 10G mode */
   1989 		ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG,
   1990 		    ESR_PLL_CFG_10G_SERDES);
   1991 
   1992 		ESR_REG_WR(handle, ESR_0_CONTROL_REG,
   1993 		    ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
   1994 		    ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
   1995 		    (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
   1996 		    (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
   1997 		    (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
   1998 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
   1999 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
   2000 		    (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
   2001 		    (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
   2002 		    (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
   2003 		    (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
   2004 
   2005 		/* Set Serdes0 Internal Loopback if necessary */
   2006 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
   2007 			ESR_REG_WR(handle,
   2008 			    ESR_0_TEST_CONFIG_REG,
   2009 			    ESR_PAD_LOOPBACK_CH3 |
   2010 			    ESR_PAD_LOOPBACK_CH2 |
   2011 			    ESR_PAD_LOOPBACK_CH1 |
   2012 			    ESR_PAD_LOOPBACK_CH0);
   2013 		} else {
   2014 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0);
   2015 		}
   2016 		break;
   2017 	case 1:
   2018 		/* Reset Serdes */
   2019 		ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_1);
   2020 		NXGE_DELAY(20);
   2021 		ESR_REG_WR(handle, ESR_RESET_REG, 0x0);
   2022 		NXGE_DELAY(2000);
   2023 
   2024 		/* Configure Serdes to 10G mode */
   2025 		ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG,
   2026 		    ESR_PLL_CFG_10G_SERDES);
   2027 
   2028 		ESR_REG_WR(handle, ESR_1_CONTROL_REG,
   2029 		    ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
   2030 		    ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
   2031 		    (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
   2032 		    (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
   2033 		    (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
   2034 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
   2035 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
   2036 		    (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
   2037 		    (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
   2038 		    (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
   2039 		    (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
   2040 
   2041 		/* Set Serdes1 Internal Loopback if necessary */
   2042 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
   2043 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG,
   2044 			    ESR_PAD_LOOPBACK_CH3 | ESR_PAD_LOOPBACK_CH2 |
   2045 			    ESR_PAD_LOOPBACK_CH1 | ESR_PAD_LOOPBACK_CH0);
   2046 		} else {
   2047 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0);
   2048 		}
   2049 		break;
   2050 	default:
   2051 		/* Nothing to do here */
   2052 		goto done;
   2053 	}
   2054 
   2055 	/* init TX RX channels */
   2056 	for (chan = 0; chan < 4; chan++) {
   2057 		if ((status = nxge_mdio_read(nxgep, portn,
   2058 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
   2059 		    &rx_tx_ctrl_l.value)) != NXGE_OK)
   2060 			goto fail;
   2061 		if ((status = nxge_mdio_read(nxgep, portn,
   2062 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
   2063 		    &rx_tx_ctrl_h.value)) != NXGE_OK)
   2064 			goto fail;
   2065 		if ((status = nxge_mdio_read(nxgep, portn,
   2066 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
   2067 		    &glue_ctrl0_l.value)) != NXGE_OK)
   2068 			goto fail;
   2069 		if ((status = nxge_mdio_read(nxgep, portn,
   2070 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
   2071 		    &glue_ctrl0_h.value)) != NXGE_OK)
   2072 			goto fail;
   2073 		rx_tx_ctrl_l.bits.enstretch = 1;
   2074 		rx_tx_ctrl_h.bits.vmuxlo = 2;
   2075 		rx_tx_ctrl_h.bits.vpulselo = 2;
   2076 		glue_ctrl0_l.bits.rxlosenable = 1;
   2077 		glue_ctrl0_l.bits.samplerate = 0xF;
   2078 		glue_ctrl0_l.bits.thresholdcount = 0xFF;
   2079 		glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
   2080 		if ((status = nxge_mdio_write(nxgep, portn,
   2081 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
   2082 		    rx_tx_ctrl_l.value)) != NXGE_OK)
   2083 			goto fail;
   2084 		if ((status = nxge_mdio_write(nxgep, portn,
   2085 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
   2086 		    rx_tx_ctrl_h.value)) != NXGE_OK)
   2087 			goto fail;
   2088 		if ((status = nxge_mdio_write(nxgep, portn,
   2089 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
   2090 		    glue_ctrl0_l.value)) != NXGE_OK)
   2091 			goto fail;
   2092 		if ((status = nxge_mdio_write(nxgep, portn,
   2093 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
   2094 		    glue_ctrl0_h.value)) != NXGE_OK)
   2095 			goto fail;
   2096 		}
   2097 
   2098 	/* Apply Tx core reset */
   2099 	if ((status = nxge_mdio_write(nxgep, portn,
   2100 	    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
   2101 	    (uint16_t)0)) != NXGE_OK)
   2102 		goto fail;
   2103 
   2104 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
   2105 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) !=
   2106 	    NXGE_OK)
   2107 		goto fail;
   2108 
   2109 	NXGE_DELAY(200);
   2110 
   2111 	/* Apply Rx core reset */
   2112 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
   2113 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) !=
   2114 	    NXGE_OK)
   2115 		goto fail;
   2116 
   2117 	NXGE_DELAY(200);
   2118 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
   2119 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK)
   2120 		goto fail;
   2121 
   2122 	NXGE_DELAY(200);
   2123 	if ((status = nxge_mdio_read(nxgep, portn,
   2124 	    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
   2125 	    &val16l)) != NXGE_OK)
   2126 		goto fail;
   2127 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
   2128 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK)
   2129 		goto fail;
   2130 	if ((val16l != 0) || (val16h != 0)) {
   2131 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   2132 		    "Failed to reset port<%d> XAUI Serdes "
   2133 		    "(val16l 0x%x val16h 0x%x)",
   2134 		    portn, val16l, val16h));
   2135 	}
   2136 
   2137 	if (portn == 0) {
   2138 		/* Wait for serdes to be ready */
   2139 		for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) {
   2140 			ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
   2141 			if ((val & ESR_SIG_P0_BITS_MASK) !=
   2142 			    (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 |
   2143 			    ESR_SIG_XSERDES_RDY_P0 |
   2144 			    ESR_SIG_XDETECT_P0_CH3 |
   2145 			    ESR_SIG_XDETECT_P0_CH2 |
   2146 			    ESR_SIG_XDETECT_P0_CH1 |
   2147 			    ESR_SIG_XDETECT_P0_CH0))
   2148 
   2149 				NXGE_DELAY(SERDES_RDY_WT_INTERVAL);
   2150 			else
   2151 				break;
   2152 		}
   2153 
   2154 		if (i == MAX_SERDES_RDY_RETRIES) {
   2155 			/*
   2156 			 * RDY signal stays low may due to the absent of the
   2157 			 * external PHY, it is not an error condition. But still
   2158 			 * print the message for the debugging purpose when link
   2159 			 * stays down
   2160 			 */
   2161 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   2162 			    "nxge_neptune_10G_serdes_init: "
   2163 			    "Serdes/signal for port<%d> not ready", portn));
   2164 				goto done;
   2165 		}
   2166 	} else if (portn == 1) {
   2167 		/* Wait for serdes to be ready */
   2168 		for (i = 0; i < MAX_SERDES_RDY_RETRIES; i++) {
   2169 			ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
   2170 			if ((val & ESR_SIG_P1_BITS_MASK) !=
   2171 			    (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 |
   2172 			    ESR_SIG_XSERDES_RDY_P1 |
   2173 			    ESR_SIG_XDETECT_P1_CH3 |
   2174 			    ESR_SIG_XDETECT_P1_CH2 |
   2175 			    ESR_SIG_XDETECT_P1_CH1 |
   2176 			    ESR_SIG_XDETECT_P1_CH0))
   2177 
   2178 				NXGE_DELAY(SERDES_RDY_WT_INTERVAL);
   2179 			else
   2180 				break;
   2181 		}
   2182 
   2183 		if (i == MAX_SERDES_RDY_RETRIES) {
   2184 			/*
   2185 			 * RDY signal stays low may due to the absent of the
   2186 			 * external PHY, it is not an error condition. But still
   2187 			 * print the message for the debugging purpose when link
   2188 			 * stays down
   2189 			 */
   2190 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   2191 			    "nxge_neptune_10G_serdes_init: "
   2192 			    "Serdes/signal for port<%d> not ready", portn));
   2193 				goto done;
   2194 		}
   2195 	}
   2196 
   2197 done:
   2198 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   2199 	    "<== nxge_neptune_10G_serdes_init port<%d>", portn));
   2200 
   2201 	return (NXGE_OK);
   2202 fail:
   2203 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   2204 	    "nxge_neptune_10G_serdes_init: "
   2205 	    "Failed to initialize Neptune serdes for port<%d>", portn));
   2206 
   2207 	return (status);
   2208 }
   2209 
   2210 /* Initialize Neptune Internal Serdes for 1G (Neptune only) */
   2211 
   2212 static nxge_status_t
   2213 nxge_1G_serdes_init(p_nxge_t nxgep)
   2214 {
   2215 	npi_handle_t		handle;
   2216 	uint8_t			portn;
   2217 	int			chan;
   2218 	sr_rx_tx_ctrl_l_t	rx_tx_ctrl_l;
   2219 	sr_rx_tx_ctrl_h_t	rx_tx_ctrl_h;
   2220 	sr_glue_ctrl0_l_t	glue_ctrl0_l;
   2221 	sr_glue_ctrl0_h_t	glue_ctrl0_h;
   2222 	uint64_t		val;
   2223 	uint16_t		val16l;
   2224 	uint16_t		val16h;
   2225 	nxge_status_t		status = NXGE_OK;
   2226 
   2227 	portn = nxgep->mac.portnum;
   2228 
   2229 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   2230 	    "==> nxge_1G_serdes_init port<%d>", portn));
   2231 
   2232 	handle = nxgep->npi_handle;
   2233 
   2234 	switch (portn) {
   2235 	case 0:
   2236 		/* Assert the reset register */
   2237 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
   2238 		val |= ESR_RESET_0;
   2239 		ESR_REG_WR(handle, ESR_RESET_REG, val);
   2240 
   2241 		/* Set the PLL register to 0x79 */
   2242 		ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG,
   2243 		    ESR_PLL_CFG_1G_SERDES);
   2244 
   2245 		/* Set the control register to 0x249249f */
   2246 		ESR_REG_WR(handle, ESR_0_CONTROL_REG, ESR_CTL_1G_SERDES);
   2247 
   2248 		/* Set Serdes0 Internal Loopback if necessary */
   2249 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
   2250 			/* Set pad loopback modes 0xaa */
   2251 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG,
   2252 			    ESR_TSTCFG_LBTEST_PAD);
   2253 		} else {
   2254 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0);
   2255 		}
   2256 
   2257 		/* Deassert the reset register */
   2258 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
   2259 		val &= ~ESR_RESET_0;
   2260 		ESR_REG_WR(handle, ESR_RESET_REG, val);
   2261 		break;
   2262 
   2263 	case 1:
   2264 		/* Assert the reset register */
   2265 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
   2266 		val |= ESR_RESET_1;
   2267 		ESR_REG_WR(handle, ESR_RESET_REG, val);
   2268 
   2269 		/* Set PLL register to 0x79 */
   2270 		ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG,
   2271 		    ESR_PLL_CFG_1G_SERDES);
   2272 
   2273 		/* Set the control register to 0x249249f */
   2274 		ESR_REG_WR(handle, ESR_1_CONTROL_REG, ESR_CTL_1G_SERDES);
   2275 
   2276 		/* Set Serdes1 Internal Loopback if necessary */
   2277 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
   2278 			/* Set pad loopback mode 0xaa */
   2279 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG,
   2280 			    ESR_TSTCFG_LBTEST_PAD);
   2281 		} else {
   2282 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0);
   2283 		}
   2284 
   2285 		/* Deassert the reset register */
   2286 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
   2287 		val &= ~ESR_RESET_1;
   2288 		ESR_REG_WR(handle, ESR_RESET_REG, val);
   2289 		break;
   2290 
   2291 	default:
   2292 		/* Nothing to do here */
   2293 		goto done;
   2294 	}
   2295 
   2296 	/* init TX RX channels */
   2297 	for (chan = 0; chan < 4; chan++) {
   2298 		if ((status = nxge_mdio_read(nxgep, portn,
   2299 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
   2300 		    &rx_tx_ctrl_l.value)) != NXGE_OK) {
   2301 			goto fail;
   2302 		}
   2303 		if ((status = nxge_mdio_read(nxgep, portn,
   2304 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
   2305 		    &rx_tx_ctrl_h.value)) != NXGE_OK) {
   2306 			goto fail;
   2307 		}
   2308 		if ((status = nxge_mdio_read(nxgep, portn,
   2309 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
   2310 		    &glue_ctrl0_l.value)) != NXGE_OK) {
   2311 			goto fail;
   2312 		}
   2313 		if ((status = nxge_mdio_read(nxgep, portn,
   2314 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
   2315 		    &glue_ctrl0_h.value)) != NXGE_OK) {
   2316 			goto fail;
   2317 		}
   2318 
   2319 		rx_tx_ctrl_l.bits.enstretch = 1;
   2320 		rx_tx_ctrl_h.bits.vmuxlo = 2;
   2321 		rx_tx_ctrl_h.bits.vpulselo = 2;
   2322 		glue_ctrl0_l.bits.rxlosenable = 1;
   2323 		glue_ctrl0_l.bits.samplerate = 0xF;
   2324 		glue_ctrl0_l.bits.thresholdcount = 0xFF;
   2325 		glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
   2326 		if ((status = nxge_mdio_write(nxgep, portn,
   2327 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
   2328 		    rx_tx_ctrl_l.value)) != NXGE_OK) {
   2329 			goto fail;
   2330 		}
   2331 		if ((status = nxge_mdio_write(nxgep, portn,
   2332 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
   2333 		    rx_tx_ctrl_h.value)) != NXGE_OK) {
   2334 			goto fail;
   2335 		}
   2336 		if ((status = nxge_mdio_write(nxgep, portn,
   2337 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
   2338 		    glue_ctrl0_l.value)) != NXGE_OK) {
   2339 			goto fail;
   2340 		}
   2341 		if ((status = nxge_mdio_write(nxgep, portn,
   2342 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
   2343 		    glue_ctrl0_h.value)) != NXGE_OK) {
   2344 			goto fail;
   2345 		}
   2346 	}
   2347 
   2348 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
   2349 	    ESR_NEP_RX_POWER_CONTROL_L_ADDR(), 0xfff)) != NXGE_OK) {
   2350 		goto fail;
   2351 	}
   2352 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
   2353 	    ESR_NEP_RX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) {
   2354 		goto fail;
   2355 	}
   2356 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
   2357 	    ESR_NEP_TX_POWER_CONTROL_L_ADDR(), 0x70)) != NXGE_OK) {
   2358 		goto fail;
   2359 	}
   2360 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
   2361 	    ESR_NEP_TX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) {
   2362 		goto fail;
   2363 	}
   2364 
   2365 	/* Apply Tx core reset */
   2366 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
   2367 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0)) != NXGE_OK) {
   2368 		goto fail;
   2369 	}
   2370 
   2371 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
   2372 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) !=
   2373 	    NXGE_OK) {
   2374 		goto fail;
   2375 	}
   2376 
   2377 	NXGE_DELAY(200);
   2378 
   2379 	/* Apply Rx core reset */
   2380 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
   2381 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) !=
   2382 	    NXGE_OK) {
   2383 		goto fail;
   2384 	}
   2385 
   2386 	NXGE_DELAY(200);
   2387 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
   2388 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) {
   2389 		goto fail;
   2390 	}
   2391 
   2392 	NXGE_DELAY(200);
   2393 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
   2394 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), &val16l)) != NXGE_OK) {
   2395 		goto fail;
   2396 	}
   2397 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
   2398 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) {
   2399 		goto fail;
   2400 	}
   2401 	if ((val16l != 0) || (val16h != 0)) {
   2402 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   2403 		    "Failed to reset port<%d> XAUI Serdes "
   2404 		    "(val16l 0x%x val16h 0x%x)", portn, val16l, val16h));
   2405 		status = NXGE_ERROR;
   2406 		goto fail;
   2407 	}
   2408 
   2409 	NXGE_DELAY(200);
   2410 	ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
   2411 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   2412 	    "nxge_neptune_serdes_init: read internal signal reg port<%d> "
   2413 	    "val 0x%x", portn, val));
   2414 	if (portn == 0) {
   2415 		if ((val & ESR_SIG_P0_BITS_MASK_1G) !=
   2416 		    (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0)) {
   2417 			/*
   2418 			 * RDY signal stays low may due to the absent of the
   2419 			 * external PHY, it is not an error condition. But still
   2420 			 * print the message for the debugging purpose when link
   2421 			 * stays down
   2422 			 */
   2423 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   2424 			    "nxge_neptune_1G_serdes_init: "
   2425 			    "Serdes/signal for port<%d> not ready", portn));
   2426 				goto done;
   2427 		}
   2428 	} else if (portn == 1) {
   2429 		if ((val & ESR_SIG_P1_BITS_MASK_1G) !=
   2430 		    (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1)) {
   2431 			/*
   2432 			 * RDY signal stays low may due to the absent of the
   2433 			 * external PHY, it is not an error condition. But still
   2434 			 * print the message for the debugging purpose when link
   2435 			 * stays down
   2436 			 */
   2437 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   2438 			    "nxge_neptune_1G_serdes_init: "
   2439 			    "Serdes/signal for port<%d> not ready", portn));
   2440 				goto done;
   2441 
   2442 		}
   2443 	}
   2444 done:
   2445 
   2446 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   2447 	    "<== nxge_1G_serdes_init port<%d>", portn));
   2448 	return (NXGE_OK);
   2449 fail:
   2450 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   2451 	    "nxge_1G_serdes_init: "
   2452 	    "Failed to initialize Neptune serdes for port<%d>",
   2453 	    portn));
   2454 
   2455 	return (status);
   2456 }
   2457 
   2458 /* Initialize the BCM 8704 xcvr */
   2459 
   2460 static nxge_status_t
   2461 nxge_BCM8704_xcvr_init(p_nxge_t nxgep)
   2462 {
   2463 	uint16_t		val;
   2464 #ifdef	NXGE_DEBUG
   2465 	uint8_t			portn;
   2466 	uint16_t		val1;
   2467 #endif
   2468 	uint8_t			phy_port_addr;
   2469 	pmd_tx_control_t	tx_ctl;
   2470 	control_t		ctl;
   2471 	phyxs_control_t		phyxs_ctl;
   2472 	pcs_control_t		pcs_ctl;
   2473 	uint32_t		delay = 0;
   2474 	optics_dcntr_t		op_ctr;
   2475 	nxge_status_t		status = NXGE_OK;
   2476 #ifdef	NXGE_DEBUG
   2477 	portn = nxgep->mac.portnum;
   2478 #endif
   2479 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>",
   2480 	    portn));
   2481 
   2482 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
   2483 
   2484 	/* Reset the transceiver */
   2485 	if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
   2486 	    BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK)
   2487 		goto fail;
   2488 
   2489 	phyxs_ctl.bits.reset = 1;
   2490 	if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
   2491 	    BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK)
   2492 		goto fail;
   2493 
   2494 	do {
   2495 		drv_usecwait(500);
   2496 		if ((status = nxge_mdio_read(nxgep, phy_port_addr,
   2497 		    BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG,
   2498 		    &phyxs_ctl.value)) != NXGE_OK)
   2499 			goto fail;
   2500 		delay++;
   2501 	} while ((phyxs_ctl.bits.reset) && (delay < 100));
   2502 	if (delay == 100) {
   2503 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
   2504 		    "failed to reset Transceiver on port<%d>", portn));
   2505 		status = NXGE_ERROR;
   2506 		goto fail;
   2507 	}
   2508 
   2509 	/* Set to 0x7FBF */
   2510 	ctl.value = 0;
   2511 	ctl.bits.res1 = 0x3F;
   2512 	ctl.bits.optxon_lvl = 1;
   2513 	ctl.bits.oprxflt_lvl = 1;
   2514 	ctl.bits.optrxlos_lvl = 1;
   2515 	ctl.bits.optxflt_lvl = 1;
   2516 	ctl.bits.opprflt_lvl = 1;
   2517 	ctl.bits.obtmpflt_lvl = 1;
   2518 	ctl.bits.opbiasflt_lvl = 1;
   2519 	ctl.bits.optxrst_lvl = 1;
   2520 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
   2521 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, ctl.value))
   2522 	    != NXGE_OK)
   2523 		goto fail;
   2524 
   2525 	/* Set to 0x164 */
   2526 	tx_ctl.value = 0;
   2527 	tx_ctl.bits.tsck_lpwren = 1;
   2528 	tx_ctl.bits.tx_dac_txck = 0x2;
   2529 	tx_ctl.bits.tx_dac_txd = 0x1;
   2530 	tx_ctl.bits.xfp_clken = 1;
   2531 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
   2532 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG,
   2533 	    tx_ctl.value)) != NXGE_OK)
   2534 		goto fail;
   2535 	/*
   2536 	 * According to Broadcom's instruction, SW needs to read
   2537 	 * back these registers twice after written.
   2538 	 */
   2539 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
   2540 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
   2541 	    != NXGE_OK)
   2542 		goto fail;
   2543 
   2544 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
   2545 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
   2546 	    != NXGE_OK)
   2547 		goto fail;
   2548 
   2549 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
   2550 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
   2551 	    != NXGE_OK)
   2552 		goto fail;
   2553 
   2554 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
   2555 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
   2556 	    != NXGE_OK)
   2557 		goto fail;
   2558 
   2559 	/* Enable Tx and Rx LEDs to be driven by traffic */
   2560 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
   2561 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
   2562 	    &op_ctr.value)) != NXGE_OK)
   2563 		goto fail;
   2564 	if (NXGE_IS_XAUI_PLATFORM(nxgep)) {
   2565 		op_ctr.bits.gpio_sel = 0x1;
   2566 	} else {
   2567 		op_ctr.bits.gpio_sel = 0x3;
   2568 	}
   2569 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
   2570 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
   2571 	    op_ctr.value)) != NXGE_OK)
   2572 		goto fail;
   2573 
   2574 	NXGE_DELAY(1000000);
   2575 
   2576 	/* Set BCM8704 Internal Loopback mode if necessary */
   2577 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
   2578 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value))
   2579 	    != NXGE_OK)
   2580 		goto fail;
   2581 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
   2582 		pcs_ctl.bits.loopback = 1;
   2583 	else
   2584 		pcs_ctl.bits.loopback = 0;
   2585 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
   2586 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value))
   2587 	    != NXGE_OK)
   2588 		goto fail;
   2589 
   2590 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x1, 0xA, &val);
   2591 	if (status != NXGE_OK)
   2592 		goto fail;
   2593 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   2594 	    "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", portn, val));
   2595 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val);
   2596 	if (status != NXGE_OK)
   2597 		goto fail;
   2598 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   2599 	    "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", portn, val));
   2600 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val);
   2601 	if (status != NXGE_OK)
   2602 		goto fail;
   2603 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   2604 	    "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", portn, val));
   2605 
   2606 #ifdef	NXGE_DEBUG
   2607 	/* Diagnose link issue if link is not up */
   2608 	status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_USER_DEV3_ADDR,
   2609 	    BCM8704_USER_ANALOG_STATUS0_REG,
   2610 	    &val);
   2611 	if (status != NXGE_OK)
   2612 		goto fail;
   2613 
   2614 	status = nxge_mdio_read(nxgep, phy_port_addr,
   2615 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_ANALOG_STATUS0_REG, &val);
   2616 	if (status != NXGE_OK)
   2617 		goto fail;
   2618 
   2619 	status = nxge_mdio_read(nxgep, phy_port_addr,
   2620 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1);
   2621 	if (status != NXGE_OK)
   2622 		goto fail;
   2623 
   2624 	status = nxge_mdio_read(nxgep, phy_port_addr,
   2625 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_TX_ALARM_STATUS_REG, &val1);
   2626 	if (status != NXGE_OK)
   2627 		goto fail;
   2628 
   2629 	if (val != 0x3FC) {
   2630 		if ((val == 0x43BC) && (val1 != 0)) {
   2631 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   2632 			    "Cable not connected to peer or bad"
   2633 			    " cable on port<%d>\n", portn));
   2634 		} else if (val == 0x639C) {
   2635 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   2636 			    "Optical module (XFP) is bad or absent"
   2637 			    " on port<%d>\n", portn));
   2638 		}
   2639 	}
   2640 #endif
   2641 
   2642 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>",
   2643 	    portn));
   2644 	return (NXGE_OK);
   2645 
   2646 fail:
   2647 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   2648 	    "nxge_BCM8704_xcvr_init: failed to initialize transceiver for "
   2649 	    "port<%d>", nxgep->mac.portnum));
   2650 	return (NXGE_ERROR);
   2651 }
   2652 
   2653 /* Initialize the BCM 8706 Transceiver */
   2654 
   2655 static nxge_status_t
   2656 nxge_BCM8706_xcvr_init(p_nxge_t nxgep)
   2657 {
   2658 	uint8_t			phy_port_addr;
   2659 	phyxs_control_t		phyxs_ctl;
   2660 	pcs_control_t		pcs_ctl;
   2661 	uint32_t		delay = 0;
   2662 	optics_dcntr_t		op_ctr;
   2663 	nxge_status_t		status = NXGE_OK;
   2664 #ifdef	NXGE_DEBUG
   2665 	uint8_t			portn = nxgep->mac.portnum;
   2666 #endif
   2667 
   2668 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>",
   2669 	    portn));
   2670 
   2671 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
   2672 
   2673 	/* Reset the transceiver */
   2674 	if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
   2675 	    BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK)
   2676 		goto fail;
   2677 
   2678 	phyxs_ctl.bits.reset = 1;
   2679 	if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
   2680 	    BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK)
   2681 		goto fail;
   2682 	do {
   2683 		drv_usecwait(500);
   2684 		if ((status = nxge_mdio_read(nxgep, phy_port_addr,
   2685 		    BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG,
   2686 		    &phyxs_ctl.value)) != NXGE_OK)
   2687 			goto fail;
   2688 		delay++;
   2689 	} while ((phyxs_ctl.bits.reset) && (delay < 100));
   2690 
   2691 	if (delay == 100) {
   2692 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
   2693 		    "failed to reset Transceiver on port<%d>", portn));
   2694 		status = NXGE_ERROR;
   2695 		goto fail;
   2696 	}
   2697 
   2698 	NXGE_DELAY(1000000);
   2699 
   2700 	/* Set BCM8706 Internal Loopback mode if necessary */
   2701 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
   2702 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value))
   2703 	    != NXGE_OK)
   2704 		goto fail;
   2705 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
   2706 		pcs_ctl.bits.loopback = 1;
   2707 	else
   2708 		pcs_ctl.bits.loopback = 0;
   2709 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
   2710 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value))
   2711 	    != NXGE_OK)
   2712 		goto fail;
   2713 
   2714 	/* Enable Tx and Rx LEDs to be driven by traffic */
   2715 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
   2716 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
   2717 	    &op_ctr.value)) != NXGE_OK)
   2718 		goto fail;
   2719 	op_ctr.bits.gpio_sel = 0x3;
   2720 	op_ctr.bits.res2 = 0x1;
   2721 
   2722 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
   2723 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
   2724 	    op_ctr.value)) != NXGE_OK)
   2725 		goto fail;
   2726 
   2727 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>",
   2728 	    portn));
   2729 	return (NXGE_OK);
   2730 
   2731 fail:
   2732 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   2733 	    "nxge_BCM8706_xcvr_init: failed to initialize transceiver for "
   2734 	    "port<%d>", nxgep->mac.portnum));
   2735 	return (status);
   2736 }
   2737 
   2738 #define	CHK_STAT(x)	status = (x); if (status != NXGE_OK) goto fail
   2739 
   2740 #define	MRVL88X2011_RD(nxgep, port, d, r, p) \
   2741 	CHK_STAT(nxge_mdio_read(nxgep, port, d, r, p))
   2742 
   2743 #define	MRVL88X2011_WR(nxgep, port, d, r, p) \
   2744 	CHK_STAT(nxge_mdio_write(nxgep, port, d, r, p))
   2745 
   2746 
   2747 static void
   2748 nxge_mrvl88x2011_led_blink_rate(p_nxge_t nxgep, uint16_t rate)
   2749 {
   2750 	uint16_t	value;
   2751 	uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn;
   2752 
   2753 	if (nxge_mdio_read(nxgep, phy, MRVL_88X2011_USER_DEV2_ADDR,
   2754 	    MRVL_88X2011_LED_BLINK_CTL, &value) == NXGE_OK) {
   2755 		value &= ~MRVL_88X2011_LED_BLK_MASK;
   2756 		value |= (rate << MRVL_88X2011_LED_BLK_SHIFT);
   2757 		(void) nxge_mdio_write(nxgep, phy,
   2758 		    MRVL_88X2011_USER_DEV2_ADDR, MRVL_88X2011_LED_BLINK_CTL,
   2759 		    value);
   2760 	}
   2761 }
   2762 
   2763 static nxge_status_t
   2764 nxge_mrvl88x2011_setup_lb(p_nxge_t nxgep)
   2765 {
   2766 	nxge_status_t	status;
   2767 	pcs_control_t	pcs_ctl;
   2768 	uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn;
   2769 
   2770 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
   2771 	    MRVL_88X2011_PMA_PMD_CTL_1, &pcs_ctl.value);
   2772 
   2773 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
   2774 		pcs_ctl.bits.loopback = 1;
   2775 	else
   2776 		pcs_ctl.bits.loopback = 0;
   2777 
   2778 	MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
   2779 	    MRVL_88X2011_PMA_PMD_CTL_1, pcs_ctl.value);
   2780 
   2781 fail:
   2782 	return (status);
   2783 }
   2784 
   2785 
   2786 static void
   2787 nxge_mrvl88x2011_led(p_nxge_t nxgep,  uint16_t val)
   2788 {
   2789 	uint16_t	val2;
   2790 	uint8_t phy = nxgep->statsp->mac_stats.xcvr_portn;
   2791 
   2792 	val2 = MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, val);
   2793 	val2 &= ~MRVL_88X2011_LED(MRVL_88X2011_LED_ACT,
   2794 	    MRVL_88X2011_LED_CTL_MASK);
   2795 	val2 |= MRVL_88X2011_LED(MRVL_88X2011_LED_ACT, val);
   2796 
   2797 	if (nxge_mdio_write(nxgep, phy, MRVL_88X2011_USER_DEV2_ADDR,
   2798 	    MRVL_88X2011_LED_8_TO_11_CTL, val2) != NXGE_OK) {
   2799 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   2800 		    "nxge_mrvl88x2011_led: nxge_mdio_write failed!!"));
   2801 	}
   2802 }
   2803 
   2804 
   2805 static nxge_status_t
   2806 nxge_mrvl88x2011_xcvr_init(p_nxge_t nxgep)
   2807 {
   2808 	uint8_t		phy;
   2809 	nxge_status_t	status;
   2810 	uint16_t	clk;
   2811 
   2812 	phy = nxgep->statsp->mac_stats.xcvr_portn;
   2813 
   2814 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   2815 	    "==> nxge_mrvl88x2011_xcvr_init: port<%d> addr<0x%x>",
   2816 	    nxgep->mac.portnum, phy));
   2817 
   2818 	/* Set LED functions	*/
   2819 	nxge_mrvl88x2011_led_blink_rate(nxgep, MRVL_88X2011_LED_BLK134MS);
   2820 	/* PCS activity */
   2821 	nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_ACT);
   2822 
   2823 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
   2824 	    MRVL_88X2011_GEN_CTL, &clk);
   2825 	clk |= MRVL_88X2011_ENA_XFPREFCLK;
   2826 	MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
   2827 	    MRVL_88X2011_GEN_CTL, clk);
   2828 
   2829 	/* Set internal loopback mode if necessary */
   2830 
   2831 	CHK_STAT(nxge_mrvl88x2011_setup_lb(nxgep));
   2832 
   2833 	/* Enable PMD */
   2834 	MRVL88X2011_WR(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR,
   2835 	    MRVL_88X2011_10G_PMD_TX_DIS, MRVL_88X2011_ENA_PMDTX);
   2836 
   2837 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, " nxge_mrvl88x2011_reset: OK"));
   2838 
   2839 fail:
   2840 	return (status);
   2841 }
   2842 
   2843 
   2844 
   2845 /* Initialize the 10G Transceiver */
   2846 
   2847 static nxge_status_t
   2848 nxge_10G_xcvr_init(p_nxge_t nxgep)
   2849 {
   2850 	p_nxge_stats_t		statsp;
   2851 	p_nxge_param_t		param_arr = nxgep->param_arr;
   2852 	nxge_status_t		status = NXGE_OK;
   2853 #ifdef	NXGE_DEBUG
   2854 	uint8_t			portn = nxgep->mac.portnum;
   2855 #endif
   2856 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
   2857 	    portn));
   2858 
   2859 	statsp = nxgep->statsp;
   2860 
   2861 	/* Disable Link LEDs, with or without PHY */
   2862 	if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
   2863 		goto done;
   2864 
   2865 	/* Skip MDIO, if PHY absent */
   2866 	if (nxgep->mac.portmode == PORT_10G_SERDES || nxgep->phy_absent) {
   2867 		goto done;
   2868 	}
   2869 
   2870 	/* Set Clause 45 */
   2871 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
   2872 
   2873 	switch (nxgep->chip_id) {
   2874 	case BCM8704_CHIP_ID:
   2875 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
   2876 		    "Chip ID 8704 [0x%x] for 10G xcvr", nxgep->chip_id));
   2877 		status = nxge_BCM8704_xcvr_init(nxgep);
   2878 		break;
   2879 	case BCM8706_CHIP_ID:
   2880 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
   2881 		    "Chip ID 8706 [0x%x] for 10G xcvr", nxgep->chip_id));
   2882 		status = nxge_BCM8706_xcvr_init(nxgep);
   2883 		break;
   2884 	case MRVL88X201X_CHIP_ID:
   2885 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_10G_xcvr_init: "
   2886 		    "Chip ID 8706 [0x%x] for 10G xcvr", nxgep->chip_id));
   2887 		status = nxge_mrvl88x2011_xcvr_init(nxgep);
   2888 		break;
   2889 	default:
   2890 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_xcvr_init: "
   2891 		    "Unknown chip ID 0x%x for 10G xcvr addr[%d]",
   2892 		    nxgep->chip_id, nxgep->statsp->mac_stats.xcvr_portn));
   2893 		goto fail;
   2894 	}
   2895 
   2896 	if (status != NXGE_OK) {
   2897 		goto fail;
   2898 	}
   2899 done:
   2900 	statsp->mac_stats.cap_10gfdx = 1;
   2901 	statsp->mac_stats.lp_cap_10gfdx = 1;
   2902 	statsp->mac_stats.adv_cap_asmpause =
   2903 	    param_arr[param_anar_asmpause].value;
   2904 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
   2905 
   2906 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
   2907 	    portn));
   2908 	return (NXGE_OK);
   2909 
   2910 fail:
   2911 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   2912 	    "nxge_10G_xcvr_init: failed to initialize transceiver for "
   2913 	    "port<%d>", nxgep->mac.portnum));
   2914 	return (NXGE_ERROR);
   2915 }
   2916 
   2917 /* Initialize the 1G copper (BCM 5464) Transceiver */
   2918 
   2919 static nxge_status_t
   2920 nxge_1G_xcvr_init(p_nxge_t nxgep)
   2921 {
   2922 	p_nxge_param_t		param_arr = nxgep->param_arr;
   2923 	p_nxge_stats_t		statsp = nxgep->statsp;
   2924 	nxge_status_t		status = NXGE_OK;
   2925 
   2926 	if (nxgep->mac.portmode == PORT_1G_SERDES) {
   2927 		statsp->mac_stats.cap_1000fdx =
   2928 		    param_arr[param_anar_1000fdx].value;
   2929 		goto done;
   2930 	}
   2931 
   2932 	/* Set Clause 22 */
   2933 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE);
   2934 
   2935 	/* Set capability flags */
   2936 	statsp->mac_stats.cap_1000fdx = param_arr[param_anar_1000fdx].value;
   2937 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
   2938 	    (nxgep->mac.portmode == PORT_1G_FIBER)) {
   2939 		statsp->mac_stats.cap_100fdx =
   2940 		    param_arr[param_anar_100fdx].value;
   2941 		statsp->mac_stats.cap_10fdx =
   2942 		    param_arr[param_anar_10fdx].value;
   2943 	}
   2944 
   2945 	status = nxge_mii_xcvr_init(nxgep);
   2946 done:
   2947 	return (status);
   2948 }
   2949 
   2950 /*
   2951  * Although the Teranetics copper transceiver (TN1010) does not need
   2952  * to be initialized by the driver for passing packets, this funtion
   2953  * initializes the members of nxgep->statsp->mac_stats struct for
   2954  * kstat based on the value of nxgep->statsp->ports_stats.lb_mode.
   2955  * It also configures the TN1010 for PHY loopback to support SunVTS.
   2956  *
   2957  * TN1010 only has the option to disable advertisement for the 10G
   2958  * mode. So we can set it to either Dual Mode or 1G Only mode but
   2959  * can't set it to 10G Only mode.
   2960  *
   2961  * ndd -set command can set the following 6 speed/duplex related parameters.
   2962  *
   2963  * ----------------------------------------------------------------
   2964  * ndd -set /dev/nxgeX param n		kstat nxge:X | grep param
   2965  * ----------------------------------------------------------------
   2966  * adv_autoneg_cap		kstat nxge:1 | grep adv_cap_autoneg
   2967  * adv_10gfdx_cap
   2968  * adv_1000fdx_cap		kstat nxge:1 | grep adv_cap_1000fdx
   2969  * adv_100fdx_cap		kstat nxge:1 | grep adv_cap_100fdx
   2970  * adv_10fdx_cap		kstat nxge:1 | grep adv_cap_10fdx
   2971  * adv_pause_cap		kstat nxge:1 | grep adv_cap_pause
   2972  * ----------------------------------------------------------------
   2973  */
   2974 static nxge_status_t
   2975 nxge_tn1010_xcvr_init(p_nxge_t nxgep)
   2976 {
   2977 	p_nxge_param_t		param_arr;
   2978 	p_nxge_stats_t		statsp;
   2979 	tn1010_pcs_ctrl_t	tn1010_pcs_ctrl;
   2980 	uint16_t		speed;
   2981 	uint8_t			phy_port_addr;
   2982 	uint8_t			portn = NXGE_GET_PORT_NUM(nxgep->function_num);
   2983 	int			status = NXGE_OK;
   2984 
   2985 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_1G_tn1010_xcvr_init"));
   2986 
   2987 	param_arr	= nxgep->param_arr;
   2988 	statsp		= nxgep->statsp;
   2989 
   2990 	/*
   2991 	 * Initialize the xcvr statistics which are NOT controlled by ndd
   2992 	 */
   2993 	statsp->mac_stats.cap_autoneg  = 1; /* TN1010 autoneg is always on */
   2994 	statsp->mac_stats.cap_100T4    = 0;
   2995 
   2996 	/*
   2997 	 * Read the TN1010 link speed and initialize capabilities kstat. Note
   2998 	 * that function nxge_check_tn1010_link repeatedly invoked by the
   2999 	 * timer will update link_speed real time.
   3000 	 */
   3001 	if (nxge_get_tn1010_speed(nxgep,  &speed) != NXGE_OK) {
   3002 		goto fail;
   3003 	}
   3004 	if (speed == TN1010_SPEED_1G) {
   3005 		statsp->mac_stats.cap_10gfdx = 0;
   3006 	} else {
   3007 		statsp->mac_stats.cap_10gfdx = 1;
   3008 	}
   3009 
   3010 	/* Whether we are in 1G or 10G mode, we always have the 1G capability */
   3011 	statsp->mac_stats.cap_1000fdx  = 1;
   3012 
   3013 	/* TN1010 is not able to operate in the following states */
   3014 	statsp->mac_stats.cap_1000hdx  = 0;
   3015 	statsp->mac_stats.cap_100fdx   = 0;
   3016 	statsp->mac_stats.cap_100hdx   = 0;
   3017 	statsp->mac_stats.cap_10fdx    = 0;
   3018 	statsp->mac_stats.cap_10hdx    = 0;
   3019 
   3020 	/* param_anar_pause can be modified by ndd -set */
   3021 	statsp->mac_stats.cap_pause    = param_arr[param_anar_pause].value;
   3022 
   3023 	/*
   3024 	 * The following 4 lines actually overwrites what ever the ndd command
   3025 	 * has set. For example, by command
   3026 	 * 	ndd -set /dev/nxge1 adv_autoneg_cap n (n = 0 or 1)
   3027 	 * we could set param_arr[param_autoneg].value to n.  However, because
   3028 	 * here we assign constants to these parameters, whatever we set with
   3029 	 * the "ndd -set" command will be replaced. So command
   3030 	 *	kstat nxge:X | grep param
   3031 	 * will always show those constant values.  In other words, the
   3032 	 * "ndd -set" command can NOT change the values of these 4 parameters
   3033 	 * even though the command appears to be successful.
   3034 	 *
   3035 	 * Note: TN1010 auto negotiation is always enabled.
   3036 	 */
   3037 	statsp->mac_stats.adv_cap_autoneg
   3038 	    = param_arr[param_autoneg].value = 1;
   3039 	statsp->mac_stats.adv_cap_1000fdx
   3040 	    = param_arr[param_anar_1000fdx].value = 1;
   3041 	statsp->mac_stats.adv_cap_100fdx
   3042 	    = param_arr[param_anar_100fdx].value = 0;
   3043 	statsp->mac_stats.adv_cap_10fdx
   3044 	    = param_arr[param_anar_10fdx].value = 0;
   3045 
   3046 	/*
   3047 	 * The following 4 ndd params have type NXGE_PARAM_MAC_DONT_SHOW as
   3048 	 * defined in nxge_param_arr[], therefore they are not seen by the
   3049 	 * "ndd -get" command and can not be changed by ndd.  We just set
   3050 	 * them (both ndd param and kstat values) to constant 0 because TN1010
   3051 	 * does not support those speeds.
   3052 	 */
   3053 	statsp->mac_stats.adv_cap_100T4
   3054 	    = param_arr[param_anar_100T4].value = 0;
   3055 	statsp->mac_stats.adv_cap_1000hdx
   3056 	    = param_arr[param_anar_1000hdx].value = 0;
   3057 	statsp->mac_stats.adv_cap_100hdx
   3058 	    = param_arr[param_anar_100hdx].value = 0;
   3059 	statsp->mac_stats.adv_cap_10hdx
   3060 	    = param_arr[param_anar_10hdx].value = 0;
   3061 
   3062 	/*
   3063 	 * adv_cap_pause has type NXGE_PARAM_MAC_RW, so it can be modified
   3064 	 * by ndd
   3065 	 */
   3066 	statsp->mac_stats.adv_cap_pause    = param_arr[param_anar_pause].value;
   3067 
   3068 	/*
   3069 	 * nxge_param_arr[] defines the adv_cap_asmpause with type
   3070 	 * NXGE_PARAM_DONT_SHOW, therefore they are NOT seen by the
   3071 	 * "ndd -get" command and can not be changed by ndd. Here we do not
   3072 	 * assign a constant to it so the default value defined in
   3073 	 * nxge_param_arr[] will be used to set the parameter and
   3074 	 * will be shown by the kstat.
   3075 	 */
   3076 	statsp->mac_stats.adv_cap_asmpause
   3077 	    = param_arr[param_anar_asmpause].value;
   3078 
   3079 	/*
   3080 	 * Initialize the link statistics.
   3081 	 */
   3082 	statsp->mac_stats.link_T4 = 0;
   3083 	statsp->mac_stats.link_asmpause = 0;
   3084 	statsp->mac_stats.link_pause = 0;
   3085 	if (speed == TN1010_SPEED_1G) {
   3086 		statsp->mac_stats.link_speed = 1000;
   3087 		statsp->mac_stats.link_duplex = 2;	/* Full duplex */
   3088 		statsp->mac_stats.link_up = 1;
   3089 	} else {
   3090 		statsp->mac_stats.link_speed = 10000;
   3091 		statsp->mac_stats.link_duplex = 2;
   3092 		statsp->mac_stats.link_up = 1;
   3093 	}
   3094 
   3095 	/*
   3096 	 * Because TN1010 does not have a link partner register, to
   3097 	 * figure out the link partner's capabilities is tricky. Here we
   3098 	 * just set the kstat based on our knowledge about the partner
   3099 	 * (The partner must support auto-neg because auto-negotiation
   3100 	 * has completed, it must support 1G or 10G because that is the
   3101 	 * negotiated speed we are using.)
   3102 	 *
   3103 	 * Note: Current kstat does not show lp_cap_10gfdx and
   3104 	 *	lp_cap_10ghdx.
   3105 	 */
   3106 	if (speed == TN1010_SPEED_1G) {
   3107 		statsp->mac_stats.lp_cap_1000fdx  = 1;
   3108 		statsp->mac_stats.lp_cap_10gfdx   = 0;
   3109 	} else {
   3110 		statsp->mac_stats.lp_cap_1000fdx  = 0;
   3111 		statsp->mac_stats.lp_cap_10gfdx   = 1;
   3112 	}
   3113 	statsp->mac_stats.lp_cap_10ghdx   = 0;
   3114 	statsp->mac_stats.lp_cap_1000hdx  = 0;
   3115 	statsp->mac_stats.lp_cap_100fdx   = 0;
   3116 	statsp->mac_stats.lp_cap_100hdx   = 0;
   3117 	statsp->mac_stats.lp_cap_10fdx    = 0;
   3118 	statsp->mac_stats.lp_cap_10hdx    = 0;
   3119 	statsp->mac_stats.lp_cap_10gfdx   = 0;
   3120 	statsp->mac_stats.lp_cap_10ghdx   = 0;
   3121 	statsp->mac_stats.lp_cap_100T4    = 0;
   3122 	statsp->mac_stats.lp_cap_autoneg  = 1;
   3123 	statsp->mac_stats.lp_cap_asmpause = 0;
   3124 	statsp->mac_stats.lp_cap_pause    = 0;
   3125 
   3126 	/* Handle PHY loopback for SunVTS loopback test */
   3127 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
   3128 	phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
   3129 
   3130 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
   3131 	    TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG,
   3132 	    &tn1010_pcs_ctrl.value)) != NXGE_OK) {
   3133 		goto fail;
   3134 	}
   3135 	if ((statsp->port_stats.lb_mode == nxge_lb_phy1000) ||
   3136 	    (statsp->port_stats.lb_mode == nxge_lb_phy10g)) {
   3137 		tn1010_pcs_ctrl.bits.loopback = 1;
   3138 	} else {
   3139 		tn1010_pcs_ctrl.bits.loopback = 0;
   3140 	}
   3141 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
   3142 	    TN1010_PCS_DEV_ADDR, TN1010_PCS_CONTROL_REG,
   3143 	    tn1010_pcs_ctrl.value)) != NXGE_OK) {
   3144 		goto fail;
   3145 	}
   3146 
   3147 	statsp->mac_stats.xcvr_inits++;
   3148 
   3149 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   3150 	    "<== nxge_1G_tn1010_xcvr_init status 0x%x", status));
   3151 	return (status);
   3152 fail:
   3153 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   3154 	    "<== nxge_1G_tn1010_xcvr_init status 0x%x", status));
   3155 	return (status);
   3156 }
   3157 
   3158 /* Initialize transceiver */
   3159 
   3160 nxge_status_t
   3161 nxge_xcvr_init(p_nxge_t nxgep)
   3162 {
   3163 	p_nxge_stats_t		statsp;
   3164 #ifdef	NXGE_DEBUG
   3165 	uint8_t			portn;
   3166 #endif
   3167 
   3168 	nxge_status_t		status = NXGE_OK;
   3169 #ifdef	NXGE_DEBUG
   3170 	portn = nxgep->mac.portnum;
   3171 #endif
   3172 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn));
   3173 	statsp = nxgep->statsp;
   3174 
   3175 	/*
   3176 	 * Initialize the xcvr statistics. nxgep->xcvr.xcvr_init will
   3177 	 * modify mac_stats.
   3178 	 */
   3179 	statsp->mac_stats.cap_autoneg = 0;
   3180 	statsp->mac_stats.cap_100T4 = 0;
   3181 	statsp->mac_stats.cap_100fdx = 0;
   3182 	statsp->mac_stats.cap_100hdx = 0;
   3183 	statsp->mac_stats.cap_10fdx = 0;
   3184 	statsp->mac_stats.cap_10hdx = 0;
   3185 	statsp->mac_stats.cap_asmpause = 0;
   3186 	statsp->mac_stats.cap_pause = 0;
   3187 	statsp->mac_stats.cap_1000fdx = 0;
   3188 	statsp->mac_stats.cap_1000hdx = 0;
   3189 	statsp->mac_stats.cap_10gfdx = 0;
   3190 	statsp->mac_stats.cap_10ghdx = 0;
   3191 
   3192 	/*
   3193 	 * Initialize the link statistics.
   3194 	 */
   3195 	statsp->mac_stats.link_T4 = 0;
   3196 	statsp->mac_stats.link_asmpause = 0;
   3197 	statsp->mac_stats.link_pause = 0;
   3198 
   3199 	if (nxgep->xcvr.xcvr_init) {
   3200 		status = nxgep->xcvr.xcvr_init(nxgep);
   3201 		if (status != NXGE_OK)
   3202 			goto fail;
   3203 		statsp->mac_stats.xcvr_inits++;
   3204 	}
   3205 
   3206 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>",
   3207 	    portn));
   3208 	return (NXGE_OK);
   3209 
   3210 fail:
   3211 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   3212 	    "nxge_xcvr_init: failed to initialize transceiver for port<%d>",
   3213 	    portn));
   3214 	return (status);
   3215 }
   3216 
   3217 /* Look for transceiver type */
   3218 
   3219 nxge_status_t
   3220 nxge_xcvr_find(p_nxge_t nxgep)
   3221 {
   3222 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_find: port<%d>",
   3223 	    nxgep->mac.portnum));
   3224 
   3225 	if (nxge_get_xcvr_type(nxgep) != NXGE_OK)
   3226 		return (NXGE_ERROR);
   3227 
   3228 	if (nxge_setup_xcvr_table(nxgep) != NXGE_OK)
   3229 		return (NXGE_ERROR);
   3230 
   3231 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xcvr_find: xcvr_inuse = %d",
   3232 	    nxgep->statsp->mac_stats.xcvr_inuse));
   3233 	return (NXGE_OK);
   3234 }
   3235 
   3236 /* Initialize the TxMAC sub-block */
   3237 
   3238 nxge_status_t
   3239 nxge_tx_mac_init(p_nxge_t nxgep)
   3240 {
   3241 	npi_attr_t		ap;
   3242 	uint8_t			portn;
   3243 	nxge_port_mode_t	portmode;
   3244 	nxge_port_t		portt;
   3245 	npi_handle_t		handle;
   3246 	npi_status_t		rs = NPI_SUCCESS;
   3247 
   3248 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
   3249 	portt    = nxgep->mac.porttype;
   3250 	handle   = nxgep->npi_handle;
   3251 	portmode = nxgep->mac.portmode;
   3252 
   3253 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>",
   3254 	    portn));
   3255 	/* Set Max and Min Frame Size */
   3256 	/*
   3257 	 * Use maxframesize to configure the hardware maxframe size
   3258 	 * and minframesize to configure the hardware minframe size.
   3259 	 */
   3260 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   3261 	    "==> nxge_tx_mac_init: port<%d> "
   3262 	    "min framesize %d max framesize %d ",
   3263 	    nxgep->mac.minframesize,
   3264 	    nxgep->mac.maxframesize,
   3265 	    portn));
   3266 
   3267 	SET_MAC_ATTR2(handle, ap, portn,
   3268 	    MAC_PORT_FRAME_SIZE,
   3269 	    nxgep->mac.minframesize,
   3270 	    nxgep->mac.maxframesize,
   3271 	    rs);
   3272 	if (rs != NPI_SUCCESS)
   3273 		goto fail;
   3274 
   3275 	if (portt == PORT_TYPE_XMAC) {
   3276 		if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn,
   3277 		    0)) != NPI_SUCCESS)
   3278 			goto fail;
   3279 		nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS;
   3280 		if ((portmode == PORT_10G_FIBER) ||
   3281 		    (portmode == PORT_10G_COPPER) ||
   3282 		    (portmode == PORT_10G_TN1010) ||
   3283 		    (portmode == PORT_HSP_MODE) ||
   3284 		    (portmode == PORT_10G_SERDES)) {
   3285 			SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG,
   3286 			    XGMII_IPG_12_15, rs);
   3287 			if (rs != NPI_SUCCESS)
   3288 				goto fail;
   3289 			nxgep->mac.ipg[0] = XGMII_IPG_12_15;
   3290 		} else {
   3291 			SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG,
   3292 			    MII_GMII_IPG_12, rs);
   3293 			if (rs != NPI_SUCCESS)
   3294 				goto fail;
   3295 			nxgep->mac.ipg[0] = MII_GMII_IPG_12;
   3296 		}
   3297 		if ((rs = npi_xmac_tx_config(handle, INIT, portn,
   3298 		    CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS)
   3299 			goto fail;
   3300 		nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX;
   3301 		nxgep->mac.maxburstsize = 0;	/* not programmable */
   3302 		nxgep->mac.ctrltype = 0;	/* not programmable */
   3303 		nxgep->mac.pa_size = 0;		/* not programmable */
   3304 
   3305 		if ((rs = npi_xmac_zap_tx_counters(handle, portn))
   3306 		    != NPI_SUCCESS)
   3307 			goto fail;
   3308 
   3309 	} else {
   3310 		if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn,
   3311 		    0)) != NPI_SUCCESS)
   3312 			goto fail;
   3313 		nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS;
   3314 
   3315 		SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808,
   3316 		    rs);
   3317 		if (rs != NPI_SUCCESS)
   3318 			goto fail;
   3319 		nxgep->mac.ctrltype = 0x8808;
   3320 
   3321 		SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs);
   3322 		if (rs != NPI_SUCCESS)
   3323 			goto fail;
   3324 		nxgep->mac.pa_size = 0x7;
   3325 
   3326 		if ((rs = npi_bmac_tx_config(handle, INIT, portn,
   3327 		    CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS)
   3328 			goto fail;
   3329 		nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX;
   3330 	}
   3331 
   3332 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>",
   3333 	    portn));
   3334 
   3335 	return (NXGE_OK);
   3336 fail:
   3337 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   3338 	    "nxge_tx_mac_init: failed to initialize port<%d> TXMAC", portn));
   3339 
   3340 	return (NXGE_ERROR | rs);
   3341 }
   3342 
   3343 
   3344 /* Initialize the RxMAC sub-block */
   3345 
   3346 nxge_status_t
   3347 nxge_rx_mac_init(p_nxge_t nxgep)
   3348 {
   3349 	npi_attr_t		ap;
   3350 	uint32_t		i;
   3351 	uint16_t		hashtab_e;
   3352 	p_hash_filter_t		hash_filter;
   3353 	nxge_port_t		portt;
   3354 	uint8_t			portn;
   3355 	npi_handle_t		handle;
   3356 	npi_status_t		rs = NPI_SUCCESS;
   3357 	uint16_t 		*addr16p;
   3358 	uint16_t 		addr0, addr1, addr2;
   3359 	xmac_rx_config_t	xconfig;
   3360 	bmac_rx_config_t	bconfig;
   3361 
   3362 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
   3363 
   3364 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n",
   3365 	    portn));
   3366 	handle = nxgep->npi_handle;
   3367 	portt = nxgep->mac.porttype;
   3368 
   3369 	addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet;
   3370 	addr0 = ntohs(addr16p[2]);
   3371 	addr1 = ntohs(addr16p[1]);
   3372 	addr2 = ntohs(addr16p[0]);
   3373 	SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR, addr0, addr1, addr2,
   3374 	    rs);
   3375 
   3376 	if (rs != NPI_SUCCESS)
   3377 		goto fail;
   3378 	SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs);
   3379 	if (rs != NPI_SUCCESS)
   3380 		goto fail;
   3381 	SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs);
   3382 	if (rs != NPI_SUCCESS)
   3383 		goto fail;
   3384 
   3385 	/*
   3386 	 * Load the multicast hash filter bits.
   3387 	 */
   3388 	hash_filter = nxgep->hash_filter;
   3389 	for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) {
   3390 		if (hash_filter != NULL) {
   3391 			hashtab_e = (uint16_t)hash_filter->hash_filter_regs[
   3392 			    (NMCFILTER_REGS - 1) - i];
   3393 		} else {
   3394 			hashtab_e = 0;
   3395 		}
   3396 
   3397 		if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i,
   3398 		    (uint16_t *)&hashtab_e)) != NPI_SUCCESS)
   3399 			goto fail;
   3400 	}
   3401 
   3402 	if (portt == PORT_TYPE_XMAC) {
   3403 		if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn,
   3404 		    0)) != NPI_SUCCESS)
   3405 			goto fail;
   3406 		nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS;
   3407 
   3408 		(void) nxge_fflp_init_hostinfo(nxgep);
   3409 
   3410 		xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK |
   3411 		    CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK &
   3412 		    ~CFG_XMAC_RX_STRIP_CRC;
   3413 
   3414 		if (nxgep->filter.all_phys_cnt != 0)
   3415 			xconfig |= CFG_XMAC_RX_PROMISCUOUS;
   3416 
   3417 		if (nxgep->filter.all_multicast_cnt != 0)
   3418 			xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP;
   3419 
   3420 		xconfig |= CFG_XMAC_RX_HASH_FILTER;
   3421 
   3422 		if ((rs = npi_xmac_rx_config(handle, INIT, portn,
   3423 		    xconfig)) != NPI_SUCCESS)
   3424 			goto fail;
   3425 		nxgep->mac.rx_config = xconfig;
   3426 
   3427 		/* Comparison of mac unique address is always enabled on XMAC */
   3428 
   3429 		if ((rs = npi_xmac_zap_rx_counters(handle, portn))
   3430 		    != NPI_SUCCESS)
   3431 			goto fail;
   3432 	} else {
   3433 		(void) nxge_fflp_init_hostinfo(nxgep);
   3434 
   3435 		if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn,
   3436 		    0) != NPI_SUCCESS)
   3437 			goto fail;
   3438 		nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS;
   3439 
   3440 		bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX &
   3441 		    ~CFG_BMAC_RX_STRIP_CRC;
   3442 
   3443 		if (nxgep->filter.all_phys_cnt != 0)
   3444 			bconfig |= CFG_BMAC_RX_PROMISCUOUS;
   3445 
   3446 		if (nxgep->filter.all_multicast_cnt != 0)
   3447 			bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP;
   3448 
   3449 		bconfig |= CFG_BMAC_RX_HASH_FILTER;
   3450 		if ((rs = npi_bmac_rx_config(handle, INIT, portn,
   3451 		    bconfig)) != NPI_SUCCESS)
   3452 			goto fail;
   3453 		nxgep->mac.rx_config = bconfig;
   3454 
   3455 		/* Always enable comparison of mac unique address */
   3456 		if ((rs = npi_mac_altaddr_enable(handle, portn, 0))
   3457 		    != NPI_SUCCESS)
   3458 			goto fail;
   3459 	}
   3460 
   3461 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n",
   3462 	    portn));
   3463 
   3464 	return (NXGE_OK);
   3465 
   3466 fail:
   3467 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   3468 	    "nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC", portn));
   3469 
   3470 	return (NXGE_ERROR | rs);
   3471 }
   3472 
   3473 /* Enable TXMAC */
   3474 
   3475 nxge_status_t
   3476 nxge_tx_mac_enable(p_nxge_t nxgep)
   3477 {
   3478 	npi_handle_t	handle;
   3479 	npi_status_t	rs = NPI_SUCCESS;
   3480 	nxge_status_t	status = NXGE_OK;
   3481 
   3482 	handle = nxgep->npi_handle;
   3483 
   3484 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>",
   3485 	    nxgep->mac.portnum));
   3486 
   3487 	if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
   3488 		goto fail;
   3489 
   3490 	/* based on speed */
   3491 	nxgep->msg_min = ETHERMIN;
   3492 
   3493 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
   3494 		if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
   3495 		    CFG_XMAC_TX)) != NPI_SUCCESS)
   3496 			goto fail;
   3497 	} else {
   3498 		if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
   3499 		    CFG_BMAC_TX)) != NPI_SUCCESS)
   3500 			goto fail;
   3501 	}
   3502 
   3503 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>",
   3504 	    nxgep->mac.portnum));
   3505 
   3506 	return (NXGE_OK);
   3507 fail:
   3508 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   3509 	    "nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC",
   3510 	    nxgep->mac.portnum));
   3511 	if (rs != NPI_SUCCESS)
   3512 		return (NXGE_ERROR | rs);
   3513 	else
   3514 		return (status);
   3515 }
   3516 
   3517 /* Disable TXMAC */
   3518 
   3519 nxge_status_t
   3520 nxge_tx_mac_disable(p_nxge_t nxgep)
   3521 {
   3522 	npi_handle_t	handle;
   3523 	npi_status_t	rs = NPI_SUCCESS;
   3524 
   3525 	if (isLDOMguest(nxgep))
   3526 		return (NXGE_OK);
   3527 
   3528 	handle = nxgep->npi_handle;
   3529 
   3530 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>",
   3531 	    nxgep->mac.portnum));
   3532 
   3533 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
   3534 		if ((rs = npi_xmac_tx_config(handle, DISABLE,
   3535 		    nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS)
   3536 			goto fail;
   3537 	} else {
   3538 		if ((rs = npi_bmac_tx_config(handle, DISABLE,
   3539 		    nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS)
   3540 			goto fail;
   3541 	}
   3542 
   3543 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>",
   3544 	    nxgep->mac.portnum));
   3545 	return (NXGE_OK);
   3546 fail:
   3547 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   3548 	    "nxge_tx_mac_disable: Failed to disable port<%d> TxMAC",
   3549 	    nxgep->mac.portnum));
   3550 	return (NXGE_ERROR | rs);
   3551 }
   3552 
   3553 /* Enable RXMAC */
   3554 
   3555 nxge_status_t
   3556 nxge_rx_mac_enable(p_nxge_t nxgep)
   3557 {
   3558 	npi_handle_t	handle;
   3559 	uint8_t 	portn;
   3560 	npi_status_t	rs = NPI_SUCCESS;
   3561 	nxge_status_t	status = NXGE_OK;
   3562 
   3563 	/* This is a service-domain-only activity. */
   3564 	if (isLDOMguest(nxgep))
   3565 		return (status);
   3566 
   3567 	handle = nxgep->npi_handle;
   3568 	portn = nxgep->mac.portnum;
   3569 
   3570 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>",
   3571 	    portn));
   3572 
   3573 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
   3574 		goto fail;
   3575 
   3576 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
   3577 		if ((rs = npi_xmac_rx_config(handle, ENABLE, portn,
   3578 		    CFG_XMAC_RX)) != NPI_SUCCESS)
   3579 			goto fail;
   3580 	} else {
   3581 		if ((rs = npi_bmac_rx_config(handle, ENABLE, portn,
   3582 		    CFG_BMAC_RX)) != NPI_SUCCESS)
   3583 			goto fail;
   3584 	}
   3585 
   3586 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   3587 	    "<== nxge_rx_mac_enable: port<%d>", portn));
   3588 
   3589 	return (NXGE_OK);
   3590 fail:
   3591 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   3592 	    "nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC", portn));
   3593 
   3594 	if (rs != NPI_SUCCESS)
   3595 		return (NXGE_ERROR | rs);
   3596 	else
   3597 		return (status);
   3598 }
   3599 
   3600 /* Disable RXMAC */
   3601 
   3602 nxge_status_t
   3603 nxge_rx_mac_disable(p_nxge_t nxgep)
   3604 {
   3605 	npi_handle_t	handle;
   3606 	uint8_t		portn;
   3607 	npi_status_t	rs = NPI_SUCCESS;
   3608 
   3609 	/* If we are a guest domain driver, don't bother. */
   3610 	if (isLDOMguest(nxgep))
   3611 		return (NXGE_OK);
   3612 
   3613 	handle = nxgep->npi_handle;
   3614 	portn = nxgep->mac.portnum;
   3615 
   3616 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>",
   3617 	    portn));
   3618 
   3619 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
   3620 		if ((rs = npi_xmac_rx_config(handle, DISABLE, portn,
   3621 		    CFG_XMAC_RX)) != NPI_SUCCESS)
   3622 			goto fail;
   3623 	} else {
   3624 		if ((rs = npi_bmac_rx_config(handle, DISABLE, portn,
   3625 		    CFG_BMAC_RX)) != NPI_SUCCESS)
   3626 			goto fail;
   3627 	}
   3628 
   3629 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>",
   3630 	    portn));
   3631 	return (NXGE_OK);
   3632 fail:
   3633 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   3634 	    "nxgep_rx_mac_disable: Failed to disable port<%d> RxMAC", portn));
   3635 
   3636 	return (NXGE_ERROR | rs);
   3637 }
   3638 
   3639 /* Reset TXMAC */
   3640 
   3641 nxge_status_t
   3642 nxge_tx_mac_reset(p_nxge_t nxgep)
   3643 {
   3644 	npi_handle_t	handle;
   3645 	uint8_t		portn;
   3646 	npi_status_t	rs = NPI_SUCCESS;
   3647 
   3648 	handle = nxgep->npi_handle;
   3649 	portn = nxgep->mac.portnum;
   3650 
   3651 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>",
   3652 	    portn));
   3653 
   3654 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
   3655 		if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL))
   3656 		    != NPI_SUCCESS)
   3657 			goto fail;
   3658 	} else {
   3659 		if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET))
   3660 		    != NPI_SUCCESS)
   3661 			goto fail;
   3662 	}
   3663 
   3664 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>",
   3665 	    portn));
   3666 
   3667 	return (NXGE_OK);
   3668 fail:
   3669 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   3670 	    "nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>", portn));
   3671 
   3672 	return (NXGE_ERROR | rs);
   3673 }
   3674 
   3675 /* Reset RXMAC */
   3676 
   3677 nxge_status_t
   3678 nxge_rx_mac_reset(p_nxge_t nxgep)
   3679 {
   3680 	npi_handle_t	handle;
   3681 	uint8_t		portn;
   3682 	npi_status_t	rs = NPI_SUCCESS;
   3683 
   3684 	handle = nxgep->npi_handle;
   3685 	portn = nxgep->mac.portnum;
   3686 
   3687 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>",
   3688 	    portn));
   3689 
   3690 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
   3691 		if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL))
   3692 		    != NPI_SUCCESS)
   3693 		goto fail;
   3694 	} else {
   3695 		if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET))
   3696 		    != NPI_SUCCESS)
   3697 		goto fail;
   3698 	}
   3699 
   3700 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>",
   3701 	    portn));
   3702 
   3703 	return (NXGE_OK);
   3704 fail:
   3705 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   3706 	    "nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>", portn));
   3707 	return (NXGE_ERROR | rs);
   3708 }
   3709 
   3710 /* 10G fiber link interrupt start routine */
   3711 
   3712 static nxge_status_t
   3713 nxge_10G_link_intr_start(p_nxge_t nxgep)
   3714 {
   3715 	npi_status_t	rs = NPI_SUCCESS;
   3716 	uint8_t		portn = nxgep->mac.portnum;
   3717 
   3718 	rs = npi_xmac_xpcs_link_intr_enable(nxgep->npi_handle, portn);
   3719 
   3720 	if (rs != NPI_SUCCESS)
   3721 		return (NXGE_ERROR | rs);
   3722 	else
   3723 		return (NXGE_OK);
   3724 }
   3725 
   3726 /* 10G fiber link interrupt stop routine */
   3727 
   3728 static nxge_status_t
   3729 nxge_10G_link_intr_stop(p_nxge_t nxgep)
   3730 {
   3731 	npi_status_t	rs = NPI_SUCCESS;
   3732 	uint8_t		portn = nxgep->mac.portnum;
   3733 
   3734 	rs = npi_xmac_xpcs_link_intr_disable(nxgep->npi_handle, portn);
   3735 
   3736 	if (rs != NPI_SUCCESS)
   3737 		return (NXGE_ERROR | rs);
   3738 	else
   3739 		return (NXGE_OK);
   3740 }
   3741 
   3742 /* 1G fiber link interrupt start routine */
   3743 
   3744 static nxge_status_t
   3745 nxge_1G_fiber_link_intr_start(p_nxge_t nxgep)
   3746 {
   3747 	npi_status_t	rs = NPI_SUCCESS;
   3748 	uint8_t		portn = nxgep->mac.portnum;
   3749 
   3750 	rs = npi_mac_pcs_link_intr_enable(nxgep->npi_handle, portn);
   3751 	if (rs != NPI_SUCCESS)
   3752 		return (NXGE_ERROR | rs);
   3753 	else
   3754 		return (NXGE_OK);
   3755 }
   3756 
   3757 /* 1G fiber link interrupt stop routine */
   3758 
   3759 static nxge_status_t
   3760 nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep)
   3761 {
   3762 	npi_status_t	rs = NPI_SUCCESS;
   3763 	uint8_t		portn = nxgep->mac.portnum;
   3764 
   3765 	rs = npi_mac_pcs_link_intr_disable(nxgep->npi_handle, portn);
   3766 
   3767 	if (rs != NPI_SUCCESS)
   3768 		return (NXGE_ERROR | rs);
   3769 	else
   3770 		return (NXGE_OK);
   3771 }
   3772 
   3773 /* 1G copper link interrupt start routine */
   3774 
   3775 static nxge_status_t
   3776 nxge_1G_copper_link_intr_start(p_nxge_t nxgep)
   3777 {
   3778 	npi_status_t	rs = NPI_SUCCESS;
   3779 	uint8_t		portn = nxgep->mac.portnum;
   3780 
   3781 	rs = npi_mac_mif_link_intr_enable(nxgep->npi_handle, portn,
   3782 	    MII_STATUS, MII_STATUS_LINKUP);
   3783 
   3784 	if (rs != NPI_SUCCESS)
   3785 		return (NXGE_ERROR | rs);
   3786 	else
   3787 		return (NXGE_OK);
   3788 }
   3789 
   3790 /* 1G copper link interrupt stop routine */
   3791 
   3792 static nxge_status_t
   3793 nxge_1G_copper_link_intr_stop(p_nxge_t nxgep)
   3794 {
   3795 	npi_status_t	rs = NPI_SUCCESS;
   3796 	uint8_t		portn = nxgep->mac.portnum;
   3797 
   3798 	rs = npi_mac_mif_link_intr_disable(nxgep->npi_handle, portn);
   3799 
   3800 	if (rs != NPI_SUCCESS)
   3801 		return (NXGE_ERROR | rs);
   3802 	else
   3803 		return (NXGE_OK);
   3804 }
   3805 
   3806 /* Enable/Disable Link Status change interrupt */
   3807 
   3808 nxge_status_t
   3809 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable)
   3810 {
   3811 	uint8_t		portn;
   3812 	nxge_status_t	status = NXGE_OK;
   3813 
   3814 	portn = nxgep->mac.portnum;
   3815 
   3816 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn));
   3817 	if (!nxgep->xcvr.link_intr_stop || !nxgep->xcvr.link_intr_start)
   3818 		return (NXGE_OK);
   3819 
   3820 	if (enable == LINK_INTR_START)
   3821 		status = nxgep->xcvr.link_intr_start(nxgep);
   3822 	else if (enable == LINK_INTR_STOP)
   3823 		status = nxgep->xcvr.link_intr_stop(nxgep);
   3824 	if (status != NXGE_OK)
   3825 		goto fail;
   3826 
   3827 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn));
   3828 
   3829 	return (NXGE_OK);
   3830 fail:
   3831 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   3832 	    "nxge_link_intr: Failed to set port<%d> mif intr mode", portn));
   3833 
   3834 	return (status);
   3835 }
   3836 
   3837 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */
   3838 
   3839 nxge_status_t
   3840 nxge_mii_xcvr_init(p_nxge_t nxgep)
   3841 {
   3842 	p_nxge_param_t	param_arr;
   3843 	p_nxge_stats_t	statsp;
   3844 	uint8_t		xcvr_portn;
   3845 	p_mii_regs_t	mii_regs;
   3846 	mii_bmcr_t	bmcr;
   3847 	mii_bmsr_t	bmsr;
   3848 	mii_anar_t	anar;
   3849 	mii_gcr_t	gcr;
   3850 	mii_esr_t	esr;
   3851 	mii_aux_ctl_t	bcm5464r_aux;
   3852 	int		status = NXGE_OK;
   3853 
   3854 	uint_t delay;
   3855 
   3856 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init"));
   3857 
   3858 	param_arr = nxgep->param_arr;
   3859 	statsp = nxgep->statsp;
   3860 	xcvr_portn = statsp->mac_stats.xcvr_portn;
   3861 
   3862 	mii_regs = NULL;
   3863 
   3864 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   3865 	    "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value));
   3866 
   3867 	/*
   3868 	 * The mif phy mode may be connected to either a copper link
   3869 	 * or fiber link. Read the mode control register to get the fiber
   3870 	 * configuration if it is hard-wired to fiber link.
   3871 	 */
   3872 	(void) nxge_mii_get_link_mode(nxgep);
   3873 	if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) {
   3874 		return (nxge_mii_xcvr_fiber_init(nxgep));
   3875 	}
   3876 
   3877 	/*
   3878 	 * Reset the transceiver.
   3879 	 */
   3880 	delay = 0;
   3881 	bmcr.value = 0;
   3882 	bmcr.bits.reset = 1;
   3883 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
   3884 #if defined(__i386)
   3885 	    (uint8_t)(uint32_t)&mii_regs->bmcr,
   3886 #else
   3887 	    (uint8_t)(uint64_t)&mii_regs->bmcr,
   3888 #endif
   3889 	    bmcr.value)) != NXGE_OK)
   3890 		goto fail;
   3891 	do {
   3892 		drv_usecwait(500);
   3893 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
   3894 #if defined(__i386)
   3895 		    (uint8_t)(uint32_t)&mii_regs->bmcr,
   3896 #else
   3897 		    (uint8_t)(uint64_t)&mii_regs->bmcr,
   3898 #endif
   3899 		    &bmcr.value)) != NXGE_OK)
   3900 			goto fail;
   3901 		delay++;
   3902 	} while ((bmcr.bits.reset) && (delay < 1000));
   3903 	if (delay == 1000) {
   3904 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed."));
   3905 		goto fail;
   3906 	}
   3907 
   3908 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
   3909 #if defined(__i386)
   3910 	    (uint8_t)(uint32_t)(&mii_regs->bmsr),
   3911 #else
   3912 	    (uint8_t)(uint64_t)(&mii_regs->bmsr),
   3913 #endif
   3914 	    &bmsr.value)) != NXGE_OK)
   3915 		goto fail;
   3916 
   3917 	param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able;
   3918 	param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4;
   3919 	param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx;
   3920 	param_arr[param_anar_100hdx].value = 0;
   3921 	param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx;
   3922 	param_arr[param_anar_10hdx].value = 0;
   3923 
   3924 	/*
   3925 	 * Initialize the xcvr statistics.
   3926 	 */
   3927 	statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able;
   3928 	statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4;
   3929 	statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx;
   3930 	statsp->mac_stats.cap_100hdx = 0;
   3931 	statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx;
   3932 	statsp->mac_stats.cap_10hdx = 0;
   3933 	statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value;
   3934 	statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
   3935 
   3936 	/*
   3937 	 * Initialize the xcvr advertised capability statistics.
   3938 	 */
   3939 	statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value;
   3940 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
   3941 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
   3942 	statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value;
   3943 	statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value;
   3944 	statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value;
   3945 	statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value;
   3946 	statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value;
   3947 	statsp->mac_stats.adv_cap_asmpause =
   3948 	    param_arr[param_anar_asmpause].value;
   3949 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
   3950 
   3951 
   3952 	/*
   3953 	 * Check for extended status just in case we're
   3954 	 * running a Gigibit phy.
   3955 	 */
   3956 	if (bmsr.bits.extend_status) {
   3957 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
   3958 #if defined(__i386)
   3959 		    (uint8_t)(uint32_t)(&mii_regs->esr),
   3960 #else
   3961 		    (uint8_t)(uint64_t)(&mii_regs->esr),
   3962 #endif
   3963 		    &esr.value)) != NXGE_OK)
   3964 			goto fail;
   3965 		param_arr[param_anar_1000fdx].value &= esr.bits.link_1000fdx;
   3966 		param_arr[param_anar_1000hdx].value = 0;
   3967 
   3968 		statsp->mac_stats.cap_1000fdx =
   3969 		    (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx);
   3970 		statsp->mac_stats.cap_1000hdx = 0;
   3971 	} else {
   3972 		param_arr[param_anar_1000fdx].value = 0;
   3973 		param_arr[param_anar_1000hdx].value = 0;
   3974 	}
   3975 
   3976 	/*
   3977 	 * Initialize 1G Statistics once the capability is established.
   3978 	 */
   3979 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
   3980 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
   3981 
   3982 	/*
   3983 	 * Initialize the link statistics.
   3984 	 */
   3985 	statsp->mac_stats.link_T4 = 0;
   3986 	statsp->mac_stats.link_asmpause = 0;
   3987 	statsp->mac_stats.link_pause = 0;
   3988 	statsp->mac_stats.link_speed = 0;
   3989 	statsp->mac_stats.link_duplex = 0;
   3990 	statsp->mac_stats.link_up = 0;
   3991 
   3992 	/*
   3993 	 * Switch off Auto-negotiation, 100M and full duplex.
   3994 	 */
   3995 	bmcr.value = 0;
   3996 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
   3997 #if defined(__i386)
   3998 	    (uint8_t)(uint32_t)(&mii_regs->bmcr),
   3999 #else
   4000 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
   4001 #endif
   4002 	    bmcr.value)) != NXGE_OK)
   4003 		goto fail;
   4004 
   4005 	if ((statsp->port_stats.lb_mode == nxge_lb_phy) ||
   4006 	    (statsp->port_stats.lb_mode == nxge_lb_phy1000)) {
   4007 		bmcr.bits.loopback = 1;
   4008 		bmcr.bits.enable_autoneg = 0;
   4009 		if (statsp->port_stats.lb_mode == nxge_lb_phy1000)
   4010 			bmcr.bits.speed_1000_sel = 1;
   4011 		bmcr.bits.duplex_mode = 1;
   4012 		param_arr[param_autoneg].value = 0;
   4013 	} else {
   4014 		bmcr.bits.loopback = 0;
   4015 	}
   4016 
   4017 	if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
   4018 	    (statsp->port_stats.lb_mode == nxge_lb_ext100) ||
   4019 	    (statsp->port_stats.lb_mode == nxge_lb_ext10)) {
   4020 		param_arr[param_autoneg].value = 0;
   4021 		bcm5464r_aux.value = 0;
   4022 		bcm5464r_aux.bits.ext_lb = 1;
   4023 		bcm5464r_aux.bits.write_1 = 1;
   4024 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4025 		    BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK)
   4026 			goto fail;
   4027 	}
   4028 
   4029 	/* If auto-negotiation is desired */
   4030 	if (param_arr[param_autoneg].value) {
   4031 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   4032 		    "Restarting Auto-negotiation."));
   4033 		/*
   4034 		 * Setup our Auto-negotiation advertisement register.
   4035 		 */
   4036 		anar.value = 0;
   4037 		anar.bits.selector = 1;
   4038 		anar.bits.cap_100T4 = param_arr[param_anar_100T4].value;
   4039 		anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value;
   4040 		anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value;
   4041 		anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value;
   4042 		anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value;
   4043 		anar.bits.cap_asmpause = 0;
   4044 		anar.bits.cap_pause = 0;
   4045 		if (param_arr[param_anar_1000fdx].value ||
   4046 		    param_arr[param_anar_100fdx].value ||
   4047 		    param_arr[param_anar_10fdx].value) {
   4048 			anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause;
   4049 			anar.bits.cap_pause = statsp->mac_stats.cap_pause;
   4050 		}
   4051 
   4052 		/* Write to the auto-negotiation advertisement register */
   4053 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4054 #if defined(__i386)
   4055 		    (uint8_t)(uint32_t)(&mii_regs->anar),
   4056 #else
   4057 		    (uint8_t)(uint64_t)(&mii_regs->anar),
   4058 #endif
   4059 		    anar.value)) != NXGE_OK)
   4060 			goto fail;
   4061 		if (bmsr.bits.extend_status) {
   4062 			gcr.value = 0;
   4063 			gcr.bits.ms_mode_en =
   4064 			    param_arr[param_master_cfg_enable].value;
   4065 			gcr.bits.master =
   4066 			    param_arr[param_master_cfg_value].value;
   4067 			gcr.bits.link_1000fdx =
   4068 			    param_arr[param_anar_1000fdx].value;
   4069 			gcr.bits.link_1000hdx =
   4070 			    param_arr[param_anar_1000hdx].value;
   4071 			if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4072 #if defined(__i386)
   4073 			    (uint8_t)(uint32_t)(&mii_regs->gcr),
   4074 #else
   4075 			    (uint8_t)(uint64_t)(&mii_regs->gcr),
   4076 #endif
   4077 			    gcr.value)) != NXGE_OK)
   4078 				goto fail;
   4079 		}
   4080 
   4081 		bmcr.bits.enable_autoneg = 1;
   4082 		bmcr.bits.restart_autoneg = 1;
   4083 
   4084 	} else {
   4085 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode."));
   4086 		bmcr.bits.speed_1000_sel =
   4087 		    param_arr[param_anar_1000fdx].value |
   4088 		    param_arr[param_anar_1000hdx].value;
   4089 		bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) &
   4090 		    (param_arr[param_anar_100fdx].value |
   4091 		    param_arr[param_anar_100hdx].value);
   4092 
   4093 		/* Force to 1G */
   4094 		if (bmcr.bits.speed_1000_sel) {
   4095 			statsp->mac_stats.link_speed = 1000;
   4096 			gcr.value = 0;
   4097 			gcr.bits.ms_mode_en =
   4098 			    param_arr[param_master_cfg_enable].value;
   4099 			gcr.bits.master =
   4100 			    param_arr[param_master_cfg_value].value;
   4101 			if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4102 #if defined(__i386)
   4103 			    (uint8_t)(uint32_t)(&mii_regs->gcr),
   4104 #else
   4105 			    (uint8_t)(uint64_t)(&mii_regs->gcr),
   4106 #endif
   4107 			    gcr.value)) != NXGE_OK)
   4108 				goto fail;
   4109 			if (param_arr[param_anar_1000fdx].value) {
   4110 				bmcr.bits.duplex_mode = 1;
   4111 				statsp->mac_stats.link_duplex = 2;
   4112 			} else
   4113 				statsp->mac_stats.link_duplex = 1;
   4114 
   4115 		/* Force to 100M */
   4116 		} else if (bmcr.bits.speed_sel) {
   4117 			statsp->mac_stats.link_speed = 100;
   4118 			if (param_arr[param_anar_100fdx].value) {
   4119 				bmcr.bits.duplex_mode = 1;
   4120 				statsp->mac_stats.link_duplex = 2;
   4121 			} else
   4122 				statsp->mac_stats.link_duplex = 1;
   4123 
   4124 		/* Force to 10M */
   4125 		} else {
   4126 			statsp->mac_stats.link_speed = 10;
   4127 			if (param_arr[param_anar_10fdx].value) {
   4128 				bmcr.bits.duplex_mode = 1;
   4129 				statsp->mac_stats.link_duplex = 2;
   4130 			} else
   4131 				statsp->mac_stats.link_duplex = 1;
   4132 		}
   4133 		if (statsp->mac_stats.link_duplex != 1) {
   4134 			statsp->mac_stats.link_asmpause =
   4135 			    statsp->mac_stats.cap_asmpause;
   4136 			statsp->mac_stats.link_pause =
   4137 			    statsp->mac_stats.cap_pause;
   4138 		}
   4139 
   4140 		if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
   4141 		    (statsp->port_stats.lb_mode == nxge_lb_ext100) ||
   4142 		    (statsp->port_stats.lb_mode == nxge_lb_ext10)) {
   4143 			if (statsp->port_stats.lb_mode == nxge_lb_ext1000) {
   4144 				/* BCM5464R 1000mbps external loopback mode */
   4145 				gcr.value = 0;
   4146 				gcr.bits.ms_mode_en = 1;
   4147 				gcr.bits.master = 1;
   4148 				if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4149 #if defined(__i386)
   4150 				    (uint8_t)(uint32_t)(&mii_regs->gcr),
   4151 #else
   4152 				    (uint8_t)(uint64_t)(&mii_regs->gcr),
   4153 #endif
   4154 				    gcr.value)) != NXGE_OK)
   4155 					goto fail;
   4156 				bmcr.value = 0;
   4157 				bmcr.bits.speed_1000_sel = 1;
   4158 				statsp->mac_stats.link_speed = 1000;
   4159 			} else if (statsp->port_stats.lb_mode
   4160 			    == nxge_lb_ext100) {
   4161 				/* BCM5464R 100mbps external loopback mode */
   4162 				bmcr.value = 0;
   4163 				bmcr.bits.speed_sel = 1;
   4164 				bmcr.bits.duplex_mode = 1;
   4165 				statsp->mac_stats.link_speed = 100;
   4166 			} else if (statsp->port_stats.lb_mode
   4167 			    == nxge_lb_ext10) {
   4168 				/* BCM5464R 10mbps external loopback mode */
   4169 				bmcr.value = 0;
   4170 				bmcr.bits.duplex_mode = 1;
   4171 				statsp->mac_stats.link_speed = 10;
   4172 			}
   4173 		}
   4174 	}
   4175 
   4176 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4177 #if defined(__i386)
   4178 	    (uint8_t)(uint32_t)(&mii_regs->bmcr),
   4179 #else
   4180 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
   4181 #endif
   4182 	    bmcr.value)) != NXGE_OK)
   4183 		goto fail;
   4184 
   4185 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
   4186 #if defined(__i386)
   4187 	    (uint8_t)(uint32_t)(&mii_regs->bmcr),
   4188 #else
   4189 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
   4190 #endif
   4191 	    &bmcr.value)) != NXGE_OK)
   4192 		goto fail;
   4193 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value));
   4194 
   4195 	/*
   4196 	 * Initialize the xcvr status kept in the context structure.
   4197 	 */
   4198 	nxgep->soft_bmsr.value = 0;
   4199 
   4200 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
   4201 #if defined(__i386)
   4202 	    (uint8_t)(uint32_t)(&mii_regs->bmsr),
   4203 #else
   4204 	    (uint8_t)(uint64_t)(&mii_regs->bmsr),
   4205 #endif
   4206 	    &nxgep->bmsr.value)) != NXGE_OK)
   4207 		goto fail;
   4208 
   4209 	statsp->mac_stats.xcvr_inits++;
   4210 	nxgep->bmsr.value = 0;
   4211 
   4212 fail:
   4213 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   4214 	    "<== nxge_mii_xcvr_init status 0x%x", status));
   4215 	return (status);
   4216 }
   4217 
   4218 nxge_status_t
   4219 nxge_mii_xcvr_fiber_init(p_nxge_t nxgep)
   4220 {
   4221 	p_nxge_param_t	param_arr;
   4222 	p_nxge_stats_t	statsp;
   4223 	uint8_t		xcvr_portn;
   4224 	p_mii_regs_t	mii_regs;
   4225 	mii_bmcr_t	bmcr;
   4226 	mii_bmsr_t	bmsr;
   4227 	mii_gcr_t	gcr;
   4228 	mii_esr_t	esr;
   4229 	mii_aux_ctl_t	bcm5464r_aux;
   4230 	int		status = NXGE_OK;
   4231 
   4232 	uint_t delay;
   4233 
   4234 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_fiber_init"));
   4235 
   4236 	param_arr = nxgep->param_arr;
   4237 	statsp = nxgep->statsp;
   4238 	xcvr_portn = statsp->mac_stats.xcvr_portn;
   4239 
   4240 	mii_regs = NULL;
   4241 
   4242 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   4243 	    "nxge_mii_xcvr_fiber_init: "
   4244 	    "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value));
   4245 
   4246 	/*
   4247 	 * Reset the transceiver.
   4248 	 */
   4249 	delay = 0;
   4250 	bmcr.value = 0;
   4251 	bmcr.bits.reset = 1;
   4252 
   4253 #if defined(__i386)
   4254 
   4255 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4256 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
   4257 		goto fail;
   4258 #else
   4259 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4260 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
   4261 		goto fail;
   4262 #endif
   4263 	do {
   4264 		drv_usecwait(500);
   4265 #if defined(__i386)
   4266 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
   4267 		    (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value))
   4268 		    != NXGE_OK)
   4269 			goto fail;
   4270 #else
   4271 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
   4272 		    (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value))
   4273 		    != NXGE_OK)
   4274 			goto fail;
   4275 #endif
   4276 		delay++;
   4277 	} while ((bmcr.bits.reset) && (delay < 1000));
   4278 	if (delay == 1000) {
   4279 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed."));
   4280 		goto fail;
   4281 	}
   4282 
   4283 #if defined(__i386)
   4284 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
   4285 	    (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK)
   4286 		goto fail;
   4287 #else
   4288 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
   4289 	    (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK)
   4290 		goto fail;
   4291 #endif
   4292 
   4293 	param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able;
   4294 	param_arr[param_anar_100T4].value = 0;
   4295 	param_arr[param_anar_100fdx].value = 0;
   4296 	param_arr[param_anar_100hdx].value = 0;
   4297 	param_arr[param_anar_10fdx].value = 0;
   4298 	param_arr[param_anar_10hdx].value = 0;
   4299 
   4300 	/*
   4301 	 * Initialize the xcvr statistics.
   4302 	 */
   4303 	statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able;
   4304 	statsp->mac_stats.cap_100T4 = 0;
   4305 	statsp->mac_stats.cap_100fdx = 0;
   4306 	statsp->mac_stats.cap_100hdx = 0;
   4307 	statsp->mac_stats.cap_10fdx = 0;
   4308 	statsp->mac_stats.cap_10hdx = 0;
   4309 	statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value;
   4310 	statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
   4311 
   4312 	/*
   4313 	 * Initialize the xcvr advertised capability statistics.
   4314 	 */
   4315 	statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value;
   4316 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
   4317 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
   4318 	statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value;
   4319 	statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value;
   4320 	statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value;
   4321 	statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value;
   4322 	statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value;
   4323 	statsp->mac_stats.adv_cap_asmpause =
   4324 	    param_arr[param_anar_asmpause].value;
   4325 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
   4326 
   4327 	/*
   4328 	 * Check for extended status just in case we're
   4329 	 * running a Gigibit phy.
   4330 	 */
   4331 	if (bmsr.bits.extend_status) {
   4332 #if defined(__i386)
   4333 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
   4334 		    (uint8_t)(uint32_t)(&mii_regs->esr), &esr.value)) !=
   4335 		    NXGE_OK)
   4336 			goto fail;
   4337 #else
   4338 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
   4339 		    (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) !=
   4340 		    NXGE_OK)
   4341 			goto fail;
   4342 #endif
   4343 		param_arr[param_anar_1000fdx].value &=
   4344 		    esr.bits.link_1000fdx;
   4345 		param_arr[param_anar_1000hdx].value = 0;
   4346 
   4347 		statsp->mac_stats.cap_1000fdx =
   4348 		    (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx);
   4349 		statsp->mac_stats.cap_1000hdx = 0;
   4350 	} else {
   4351 		param_arr[param_anar_1000fdx].value = 0;
   4352 		param_arr[param_anar_1000hdx].value = 0;
   4353 	}
   4354 
   4355 	/*
   4356 	 * Initialize 1G Statistics once the capability is established.
   4357 	 */
   4358 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
   4359 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
   4360 
   4361 	/*
   4362 	 * Initialize the link statistics.
   4363 	 */
   4364 	statsp->mac_stats.link_T4 = 0;
   4365 	statsp->mac_stats.link_asmpause = 0;
   4366 	statsp->mac_stats.link_pause = 0;
   4367 	statsp->mac_stats.link_speed = 0;
   4368 	statsp->mac_stats.link_duplex = 0;
   4369 	statsp->mac_stats.link_up = 0;
   4370 
   4371 	/*
   4372 	 * Switch off Auto-negotiation, 100M and full duplex.
   4373 	 */
   4374 	bmcr.value = 0;
   4375 #if defined(__i386)
   4376 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4377 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
   4378 		goto fail;
   4379 #else
   4380 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4381 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
   4382 		goto fail;
   4383 #endif
   4384 
   4385 	if ((statsp->port_stats.lb_mode == nxge_lb_phy) ||
   4386 	    (statsp->port_stats.lb_mode == nxge_lb_phy1000)) {
   4387 		bmcr.bits.loopback = 1;
   4388 		bmcr.bits.enable_autoneg = 0;
   4389 		if (statsp->port_stats.lb_mode == nxge_lb_phy1000)
   4390 			bmcr.bits.speed_1000_sel = 1;
   4391 		bmcr.bits.duplex_mode = 1;
   4392 		param_arr[param_autoneg].value = 0;
   4393 	} else {
   4394 		bmcr.bits.loopback = 0;
   4395 	}
   4396 
   4397 	if (statsp->port_stats.lb_mode == nxge_lb_ext1000) {
   4398 		param_arr[param_autoneg].value = 0;
   4399 		bcm5464r_aux.value = 0;
   4400 		bcm5464r_aux.bits.ext_lb = 1;
   4401 		bcm5464r_aux.bits.write_1 = 1;
   4402 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4403 		    BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK)
   4404 			goto fail;
   4405 	}
   4406 
   4407 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode."));
   4408 	bmcr.bits.speed_1000_sel = 1;
   4409 	bmcr.bits.speed_sel = 0;
   4410 	bmcr.bits.duplex_mode = 1;
   4411 	statsp->mac_stats.link_speed = 1000;
   4412 	statsp->mac_stats.link_duplex = 2;
   4413 
   4414 	if ((statsp->port_stats.lb_mode == nxge_lb_ext1000)) {
   4415 		/* BCM5464R 1000mbps external loopback mode */
   4416 		gcr.value = 0;
   4417 		gcr.bits.ms_mode_en = 1;
   4418 		gcr.bits.master = 1;
   4419 #if defined(__i386)
   4420 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4421 		    (uint8_t)(uint32_t)(&mii_regs->gcr),
   4422 		    gcr.value)) != NXGE_OK)
   4423 			goto fail;
   4424 #else
   4425 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4426 		    (uint8_t)(uint64_t)(&mii_regs->gcr),
   4427 		    gcr.value)) != NXGE_OK)
   4428 			goto fail;
   4429 #endif
   4430 		bmcr.value = 0;
   4431 		bmcr.bits.speed_1000_sel = 1;
   4432 		statsp->mac_stats.link_speed = 1000;
   4433 	}
   4434 
   4435 #if defined(__i386)
   4436 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4437 	    (uint8_t)(uint32_t)(&mii_regs->bmcr),
   4438 	    bmcr.value)) != NXGE_OK)
   4439 		goto fail;
   4440 #else
   4441 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
   4442 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
   4443 	    bmcr.value)) != NXGE_OK)
   4444 		goto fail;
   4445 #endif
   4446 
   4447 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   4448 	    "nxge_mii_xcvr_fiber_init: value wrote bmcr = 0x%x",
   4449 	    bmcr.value));
   4450 
   4451 #if defined(__i386)
   4452 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
   4453 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
   4454 		goto fail;
   4455 #else
   4456 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
   4457 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
   4458 		goto fail;
   4459 #endif
   4460 
   4461 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   4462 	    "nxge_mii_xcvr_fiber_init: read bmcr = 0x%04X", bmcr.value));
   4463 
   4464 	/*
   4465 	 * Initialize the xcvr status kept in the context structure.
   4466 	 */
   4467 	nxgep->soft_bmsr.value = 0;
   4468 #if defined(__i386)
   4469 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
   4470 	    (uint8_t)(uint32_t)(&mii_regs->bmsr),
   4471 	    &nxgep->bmsr.value)) != NXGE_OK)
   4472 		goto fail;
   4473 #else
   4474 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
   4475 	    (uint8_t)(uint64_t)(&mii_regs->bmsr),
   4476 	    &nxgep->bmsr.value)) != NXGE_OK)
   4477 		goto fail;
   4478 #endif
   4479 
   4480 	statsp->mac_stats.xcvr_inits++;
   4481 	nxgep->bmsr.value = 0;
   4482 
   4483 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   4484 	    "<== nxge_mii_xcvr_fiber_init status 0x%x", status));
   4485 	return (status);
   4486 
   4487 fail:
   4488 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   4489 	    "<== nxge_mii_xcvr_fiber_init status 0x%x", status));
   4490 	return (status);
   4491 }
   4492 
   4493 /* Read from a MII compliant register */
   4494 
   4495 nxge_status_t
   4496 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
   4497 		uint16_t *value)
   4498 {
   4499 	npi_status_t rs = NPI_SUCCESS;
   4500 
   4501 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>"
   4502 	    "xcvr_reg<%d>", xcvr_portn, xcvr_reg));
   4503 
   4504 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
   4505 
   4506 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
   4507 	    (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) {
   4508 		if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle,
   4509 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
   4510 			goto fail;
   4511 	} else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
   4512 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
   4513 		if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle,
   4514 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
   4515 			goto fail;
   4516 	} else
   4517 		goto fail;
   4518 
   4519 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
   4520 
   4521 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>"
   4522 	    "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, *value));
   4523 	return (NXGE_OK);
   4524 fail:
   4525 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
   4526 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   4527 	    "nxge_mii_read: Failed to read mii on xcvr %d", xcvr_portn));
   4528 
   4529 	return (NXGE_ERROR | rs);
   4530 }
   4531 
   4532 /* Write to a MII compliant Register */
   4533 
   4534 nxge_status_t
   4535 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
   4536 		uint16_t value)
   4537 {
   4538 	npi_status_t rs = NPI_SUCCESS;
   4539 
   4540 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>"
   4541 	    "xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg, value));
   4542 
   4543 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
   4544 
   4545 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
   4546 	    (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) {
   4547 		if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle,
   4548 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
   4549 			goto fail;
   4550 	} else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
   4551 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
   4552 		if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle,
   4553 		    xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
   4554 			goto fail;
   4555 	} else
   4556 		goto fail;
   4557 
   4558 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
   4559 
   4560 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>"
   4561 	    "xcvr_reg<%d>", xcvr_portn, xcvr_reg));
   4562 	return (NXGE_OK);
   4563 fail:
   4564 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
   4565 
   4566 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   4567 	    "nxge_mii_write: Failed to write mii on xcvr %d", xcvr_portn));
   4568 
   4569 	return (NXGE_ERROR | rs);
   4570 }
   4571 
   4572 /*
   4573  * Perform write to Clause45 serdes / transceiver device
   4574  * Arguments:
   4575  *	xcvr_portn: 	The IEEE 802.3 Clause45 PHYAD, it is the same as port
   4576  *			number if nxge_mdio_write is used for accessing the
   4577  *			internal LSIL serdes. Otherwise PHYAD is different
   4578  * 			for different platforms.
   4579  *	device:		With each PHYAD, the driver can use MDIO to control
   4580  *			multiple devices inside the PHY, here "device" is an
   4581  *			MMD (MDIO managable device).
   4582  *	xcvr_reg:	Each device has multiple registers. xcvr_reg specifies
   4583  *			the register which the driver will write value to.
   4584  *	value:		The register value will be filled in.
   4585  */
   4586 nxge_status_t
   4587 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
   4588 		uint16_t xcvr_reg, uint16_t *value)
   4589 {
   4590 	npi_status_t rs = NPI_SUCCESS;
   4591 
   4592 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>",
   4593 	    xcvr_portn));
   4594 
   4595 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
   4596 
   4597 	if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle,
   4598 	    xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
   4599 		goto fail;
   4600 
   4601 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
   4602 
   4603 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>",
   4604 	    xcvr_portn));
   4605 	return (NXGE_OK);
   4606 fail:
   4607 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
   4608 
   4609 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   4610 	    "nxge_mdio_read: Failed to read mdio on xcvr %d", xcvr_portn));
   4611 
   4612 	return (NXGE_ERROR | rs);
   4613 }
   4614 
   4615 /* Perform write to Clause45 serdes / transceiver device */
   4616 
   4617 nxge_status_t
   4618 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
   4619 		uint16_t xcvr_reg, uint16_t value)
   4620 {
   4621 	npi_status_t rs = NPI_SUCCESS;
   4622 
   4623 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>",
   4624 	    xcvr_portn));
   4625 
   4626 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
   4627 
   4628 	if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle,
   4629 	    xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
   4630 		goto fail;
   4631 
   4632 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
   4633 
   4634 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>",
   4635 	    xcvr_portn));
   4636 	return (NXGE_OK);
   4637 fail:
   4638 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
   4639 
   4640 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   4641 	    "nxge_mdio_write: Failed to write mdio on xcvr %d", xcvr_portn));
   4642 
   4643 	return (NXGE_ERROR | rs);
   4644 }
   4645 
   4646 
   4647 /* Check MII to see if there is any link status change */
   4648 
   4649 nxge_status_t
   4650 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints,
   4651 		nxge_link_state_t *link_up)
   4652 {
   4653 	p_nxge_param_t	param_arr;
   4654 	p_nxge_stats_t	statsp;
   4655 	p_mii_regs_t	mii_regs;
   4656 	p_mii_bmsr_t	soft_bmsr;
   4657 	mii_anar_t	anar;
   4658 	mii_anlpar_t	anlpar;
   4659 	mii_anar_t	an_common;
   4660 	mii_aner_t	aner;
   4661 	mii_gsr_t	gsr;
   4662 	nxge_status_t	status = NXGE_OK;
   4663 
   4664 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check"));
   4665 
   4666 	mii_regs = NULL;
   4667 	param_arr = nxgep->param_arr;
   4668 	statsp = nxgep->statsp;
   4669 	soft_bmsr = &nxgep->soft_bmsr;
   4670 	*link_up = LINK_NO_CHANGE;
   4671 
   4672 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   4673 	    "==> nxge_mii_check bmsr 0x%x bmsr_int 0x%x",
   4674 	    bmsr.value, bmsr_ints.value));
   4675 
   4676 	if (bmsr_ints.bits.link_status) {
   4677 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   4678 		    "==> nxge_mii_check (link up) bmsr 0x%x bmsr_int 0x%x",
   4679 		    bmsr.value, bmsr_ints.value));
   4680 		if (bmsr.bits.link_status) {
   4681 			soft_bmsr->bits.link_status = 1;
   4682 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   4683 		    "==> nxge_mii_check (link up) soft bmsr 0x%x bmsr_int "
   4684 		    "0x%x", bmsr.value, bmsr_ints.value));
   4685 		} else {
   4686 			/* Only status change will update *link_up */
   4687 			if (statsp->mac_stats.link_up == 1) {
   4688 				*link_up = LINK_IS_DOWN;
   4689 				/* Will notify, turn off further msg */
   4690 				nxgep->link_notify = B_FALSE;
   4691 			}
   4692 			statsp->mac_stats.link_up = 0;
   4693 			soft_bmsr->bits.link_status = 0;
   4694 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   4695 			    "Link down cable problem"));
   4696 		}
   4697 	}
   4698 
   4699 	if (nxgep->mac.portmode == PORT_1G_COPPER &&
   4700 	    param_arr[param_autoneg].value) {
   4701 		if (bmsr_ints.bits.auto_neg_complete) {
   4702 			if (bmsr.bits.auto_neg_complete)
   4703 				soft_bmsr->bits.auto_neg_complete = 1;
   4704 			else
   4705 				soft_bmsr->bits.auto_neg_complete = 0;
   4706 		}
   4707 		if (soft_bmsr->bits.link_status == 0) {
   4708 			statsp->mac_stats.link_T4 = 0;
   4709 			statsp->mac_stats.link_speed = 0;
   4710 			statsp->mac_stats.link_duplex = 0;
   4711 			statsp->mac_stats.link_asmpause = 0;
   4712 			statsp->mac_stats.link_pause = 0;
   4713 			statsp->mac_stats.lp_cap_autoneg = 0;
   4714 			statsp->mac_stats.lp_cap_100T4 = 0;
   4715 			statsp->mac_stats.lp_cap_1000fdx = 0;
   4716 			statsp->mac_stats.lp_cap_1000hdx = 0;
   4717 			statsp->mac_stats.lp_cap_100fdx = 0;
   4718 			statsp->mac_stats.lp_cap_100hdx = 0;
   4719 			statsp->mac_stats.lp_cap_10fdx = 0;
   4720 			statsp->mac_stats.lp_cap_10hdx = 0;
   4721 			statsp->mac_stats.lp_cap_10gfdx = 0;
   4722 			statsp->mac_stats.lp_cap_10ghdx = 0;
   4723 			statsp->mac_stats.lp_cap_asmpause = 0;
   4724 			statsp->mac_stats.lp_cap_pause = 0;
   4725 		}
   4726 	} else
   4727 		soft_bmsr->bits.auto_neg_complete = 1;
   4728 
   4729 	if ((bmsr_ints.bits.link_status ||
   4730 	    bmsr_ints.bits.auto_neg_complete) &&
   4731 	    soft_bmsr->bits.link_status &&
   4732 	    soft_bmsr->bits.auto_neg_complete) {
   4733 		if (statsp->mac_stats.link_up == 0) {
   4734 			*link_up = LINK_IS_UP;
   4735 			nxgep->link_notify = B_FALSE;
   4736 		}
   4737 		statsp->mac_stats.link_up = 1;
   4738 
   4739 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   4740 		    "==> nxge_mii_check "
   4741 		    "(auto negotiation complete or link up) "
   4742 		    "soft bmsr 0x%x bmsr_int 0x%x",
   4743 		    bmsr.value, bmsr_ints.value));
   4744 
   4745 		if (nxgep->mac.portmode == PORT_1G_COPPER &&
   4746 		    param_arr[param_autoneg].value) {
   4747 			if ((status = nxge_mii_read(nxgep,
   4748 			    statsp->mac_stats.xcvr_portn,
   4749 #if defined(__i386)
   4750 			    (uint8_t)(uint32_t)(&mii_regs->anar),
   4751 #else
   4752 			    (uint8_t)(uint64_t)(&mii_regs->anar),
   4753 #endif
   4754 			    &anar.value)) != NXGE_OK)
   4755 				goto fail;
   4756 			if ((status = nxge_mii_read(nxgep,
   4757 			    statsp->mac_stats.xcvr_portn,
   4758 #if defined(__i386)
   4759 			    (uint8_t)(uint32_t)(&mii_regs->anlpar),
   4760 #else
   4761 			    (uint8_t)(uint64_t)(&mii_regs->anlpar),
   4762 #endif
   4763 			    &anlpar.value)) != NXGE_OK)
   4764 				goto fail;
   4765 			if ((status = nxge_mii_read(nxgep,
   4766 			    statsp->mac_stats.xcvr_portn,
   4767 #if defined(__i386)
   4768 			    (uint8_t)(uint32_t)(&mii_regs->aner),
   4769 #else
   4770 			    (uint8_t)(uint64_t)(&mii_regs->aner),
   4771 #endif
   4772 			    &aner.value)) != NXGE_OK)
   4773 				goto fail;
   4774 			statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able;
   4775 			statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4;
   4776 			statsp->mac_stats.lp_cap_100fdx =
   4777 			    anlpar.bits.cap_100fdx;
   4778 			statsp->mac_stats.lp_cap_100hdx =
   4779 			    anlpar.bits.cap_100hdx;
   4780 			statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx;
   4781 			statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx;
   4782 			statsp->mac_stats.lp_cap_asmpause =
   4783 			    anlpar.bits.cap_asmpause;
   4784 			statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause;
   4785 			an_common.value = anar.value & anlpar.value;
   4786 			if (param_arr[param_anar_1000fdx].value ||
   4787 			    param_arr[param_anar_1000hdx].value) {
   4788 				if ((status = nxge_mii_read(nxgep,
   4789 				    statsp->mac_stats.xcvr_portn,
   4790 #if defined(__i386)
   4791 				    (uint8_t)(uint32_t)(&mii_regs->gsr),
   4792 #else
   4793 				    (uint8_t)(uint64_t)(&mii_regs->gsr),
   4794 #endif
   4795 				    &gsr.value)) != NXGE_OK)
   4796 					goto fail;
   4797 				statsp->mac_stats.lp_cap_1000fdx =
   4798 				    gsr.bits.link_1000fdx;
   4799 				statsp->mac_stats.lp_cap_1000hdx =
   4800 				    gsr.bits.link_1000hdx;
   4801 				if (param_arr[param_anar_1000fdx].value &&
   4802 				    gsr.bits.link_1000fdx) {
   4803 					statsp->mac_stats.link_speed = 1000;
   4804 					statsp->mac_stats.link_duplex = 2;
   4805 				} else if (
   4806 				    param_arr[param_anar_1000hdx].value &&
   4807 				    gsr.bits.link_1000hdx) {
   4808 					statsp->mac_stats.link_speed = 1000;
   4809 					statsp->mac_stats.link_duplex = 1;
   4810 				}
   4811 			}
   4812 			if ((an_common.value != 0) &&
   4813 			    !(statsp->mac_stats.link_speed)) {
   4814 				if (an_common.bits.cap_100T4) {
   4815 					statsp->mac_stats.link_T4 = 1;
   4816 					statsp->mac_stats.link_speed = 100;
   4817 					statsp->mac_stats.link_duplex = 1;
   4818 				} else if (an_common.bits.cap_100fdx) {
   4819 					statsp->mac_stats.link_speed = 100;
   4820 					statsp->mac_stats.link_duplex = 2;
   4821 				} else if (an_common.bits.cap_100hdx) {
   4822 					statsp->mac_stats.link_speed = 100;
   4823 					statsp->mac_stats.link_duplex = 1;
   4824 				} else if (an_common.bits.cap_10fdx) {
   4825 					statsp->mac_stats.link_speed = 10;
   4826 					statsp->mac_stats.link_duplex = 2;
   4827 				} else if (an_common.bits.cap_10hdx) {
   4828 					statsp->mac_stats.link_speed = 10;
   4829 					statsp->mac_stats.link_duplex = 1;
   4830 				} else {
   4831 					goto fail;
   4832 				}
   4833 			}
   4834 			if (statsp->mac_stats.link_duplex != 1) {
   4835 				int	link_pause;
   4836 				int	cp, lcp;
   4837 
   4838 				statsp->mac_stats.link_asmpause =
   4839 				    an_common.bits.cap_asmpause;
   4840 				cp = statsp->mac_stats.cap_pause;
   4841 				lcp = statsp->mac_stats.lp_cap_pause;
   4842 				if (statsp->mac_stats.link_asmpause) {
   4843 					if ((cp == 0) && (lcp == 1)) {
   4844 						link_pause = 0;
   4845 					} else {
   4846 						link_pause = 1;
   4847 					}
   4848 				} else {
   4849 					link_pause = an_common.bits.cap_pause;
   4850 				}
   4851 				statsp->mac_stats.link_pause = link_pause;
   4852 			}
   4853 		} else if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) {
   4854 			statsp->mac_stats.link_speed = 1000;
   4855 			statsp->mac_stats.link_duplex = 2;
   4856 		}
   4857 	}
   4858 	/* Initial link_notify, delay link down msg */
   4859 	if (nxgep->link_notify && nxgep->nxge_mac_state == NXGE_MAC_STARTED &&
   4860 	    (statsp->mac_stats.link_up == 1 || nxgep->link_check_count > 3)) {
   4861 		*link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP :
   4862 		    LINK_IS_DOWN);
   4863 		nxgep->link_notify = B_FALSE;
   4864 	}
   4865 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check"));
   4866 	return (NXGE_OK);
   4867 fail:
   4868 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   4869 	    "nxge_mii_check: Unable to check MII"));
   4870 	return (status);
   4871 }
   4872 
   4873 /*
   4874  * Check PCS to see if there is any link status change.
   4875  * This function is called by PORT_1G_SERDES only.
   4876  */
   4877 void
   4878 nxge_pcs_check(p_nxge_t nxgep, uint8_t portn, nxge_link_state_t *link_up)
   4879 {
   4880 	p_nxge_stats_t	statsp;
   4881 	boolean_t	linkup;
   4882 
   4883 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_check"));
   4884 
   4885 	statsp = nxgep->statsp;
   4886 	*link_up = LINK_NO_CHANGE;
   4887 
   4888 	(void) npi_mac_get_link_status(nxgep->npi_handle, portn, &linkup);
   4889 	if (linkup) {
   4890 		if ((nxgep->link_notify &&
   4891 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
   4892 		    nxgep->statsp->mac_stats.link_up == 0) {
   4893 			statsp->mac_stats.link_up = 1;
   4894 			statsp->mac_stats.link_speed = 1000;
   4895 			statsp->mac_stats.link_duplex = 2;
   4896 			*link_up = LINK_IS_UP;
   4897 			nxgep->link_notify = B_FALSE;
   4898 		}
   4899 	} else {
   4900 		if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
   4901 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
   4902 		    nxgep->statsp->mac_stats.link_up == 1) {
   4903 			statsp->mac_stats.link_up = 0;
   4904 			statsp->mac_stats.link_speed = 0;
   4905 			statsp->mac_stats.link_duplex = 0;
   4906 			*link_up = LINK_IS_DOWN;
   4907 			nxgep->link_notify = B_FALSE;
   4908 		}
   4909 	}
   4910 
   4911 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_check"));
   4912 }
   4913 
   4914 /* Add a multicast address entry into the HW hash table */
   4915 
   4916 nxge_status_t
   4917 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
   4918 {
   4919 	uint32_t mchash;
   4920 	p_hash_filter_t hash_filter;
   4921 	uint16_t hash_bit;
   4922 	boolean_t rx_init = B_FALSE;
   4923 	uint_t j;
   4924 	nxge_status_t status = NXGE_OK;
   4925 
   4926 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr"));
   4927 
   4928 	RW_ENTER_WRITER(&nxgep->filter_lock);
   4929 	mchash = crc32_mchash(addrp);
   4930 	if (nxgep->hash_filter == NULL) {
   4931 		NXGE_DEBUG_MSG((NULL, STR_CTL,
   4932 		    "Allocating hash filter storage."));
   4933 		nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t),
   4934 		    KM_SLEEP);
   4935 	}
   4936 	hash_filter = nxgep->hash_filter;
   4937 	j = mchash / HASH_REG_WIDTH;
   4938 	hash_bit = (1 << (mchash % HASH_REG_WIDTH));
   4939 	hash_filter->hash_filter_regs[j] |= hash_bit;
   4940 	hash_filter->hash_bit_ref_cnt[mchash]++;
   4941 	if (hash_filter->hash_bit_ref_cnt[mchash] == 1) {
   4942 		hash_filter->hash_ref_cnt++;
   4943 		rx_init = B_TRUE;
   4944 	}
   4945 	if (rx_init) {
   4946 		if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
   4947 			goto fail;
   4948 		if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
   4949 			goto fail;
   4950 	}
   4951 
   4952 	RW_EXIT(&nxgep->filter_lock);
   4953 
   4954 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr"));
   4955 
   4956 	return (NXGE_OK);
   4957 fail:
   4958 	RW_EXIT(&nxgep->filter_lock);
   4959 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: "
   4960 	    "Unable to add multicast address"));
   4961 	return (status);
   4962 }
   4963 
   4964 /* Remove a multicast address entry from the HW hash table */
   4965 
   4966 nxge_status_t
   4967 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
   4968 {
   4969 	uint32_t mchash;
   4970 	p_hash_filter_t hash_filter;
   4971 	uint16_t hash_bit;
   4972 	boolean_t rx_init = B_FALSE;
   4973 	uint_t j;
   4974 	nxge_status_t status = NXGE_OK;
   4975 
   4976 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr"));
   4977 	RW_ENTER_WRITER(&nxgep->filter_lock);
   4978 	mchash = crc32_mchash(addrp);
   4979 	if (nxgep->hash_filter == NULL) {
   4980 		NXGE_DEBUG_MSG((NULL, STR_CTL,
   4981 		    "Hash filter already de_allocated."));
   4982 		RW_EXIT(&nxgep->filter_lock);
   4983 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
   4984 		return (NXGE_OK);
   4985 	}
   4986 	hash_filter = nxgep->hash_filter;
   4987 	hash_filter->hash_bit_ref_cnt[mchash]--;
   4988 	if (hash_filter->hash_bit_ref_cnt[mchash] == 0) {
   4989 		j = mchash / HASH_REG_WIDTH;
   4990 		hash_bit = (1 << (mchash % HASH_REG_WIDTH));
   4991 		hash_filter->hash_filter_regs[j] &= ~hash_bit;
   4992 		hash_filter->hash_ref_cnt--;
   4993 		rx_init = B_TRUE;
   4994 	}
   4995 	if (hash_filter->hash_ref_cnt == 0) {
   4996 		NXGE_DEBUG_MSG((NULL, STR_CTL,
   4997 		    "De-allocating hash filter storage."));
   4998 		KMEM_FREE(hash_filter, sizeof (hash_filter_t));
   4999 		nxgep->hash_filter = NULL;
   5000 	}
   5001 
   5002 	if (rx_init) {
   5003 		if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
   5004 			goto fail;
   5005 		if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
   5006 			goto fail;
   5007 	}
   5008 	RW_EXIT(&nxgep->filter_lock);
   5009 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
   5010 
   5011 	return (NXGE_OK);
   5012 fail:
   5013 	RW_EXIT(&nxgep->filter_lock);
   5014 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: "
   5015 	    "Unable to remove multicast address"));
   5016 
   5017 	return (status);
   5018 }
   5019 
   5020 /* Set MAC address into MAC address HW registers */
   5021 
   5022 nxge_status_t
   5023 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp)
   5024 {
   5025 	nxge_status_t status = NXGE_OK;
   5026 
   5027 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr"));
   5028 
   5029 	MUTEX_ENTER(&nxgep->ouraddr_lock);
   5030 	/*
   5031 	 * Exit if the address is same as ouraddr or multicast or broadcast
   5032 	 */
   5033 	if (((addrp->ether_addr_octet[0] & 01) == 1) ||
   5034 	    (ether_cmp(addrp, &etherbroadcastaddr) == 0) ||
   5035 	    (ether_cmp(addrp, &nxgep->ouraddr) == 0)) {
   5036 		goto nxge_set_mac_addr_exit;
   5037 	}
   5038 	nxgep->ouraddr = *addrp;
   5039 	/*
   5040 	 * Set new interface local address and re-init device.
   5041 	 * This is destructive to any other streams attached
   5042 	 * to this device.
   5043 	 */
   5044 	RW_ENTER_WRITER(&nxgep->filter_lock);
   5045 	if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
   5046 		goto fail;
   5047 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
   5048 		goto fail;
   5049 
   5050 	RW_EXIT(&nxgep->filter_lock);
   5051 	MUTEX_EXIT(&nxgep->ouraddr_lock);
   5052 	goto nxge_set_mac_addr_end;
   5053 nxge_set_mac_addr_exit:
   5054 	MUTEX_EXIT(&nxgep->ouraddr_lock);
   5055 nxge_set_mac_addr_end:
   5056 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr"));
   5057 
   5058 	return (NXGE_OK);
   5059 fail:
   5060 	MUTEX_EXIT(&nxgep->ouraddr_lock);
   5061 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: "
   5062 	    "Unable to set mac address"));
   5063 	return (status);
   5064 }
   5065 
   5066 static
   5067 check_link_state_t
   5068 nxge_check_link_stop(nxge_t *nxge)
   5069 {
   5070 	/* If the poll has been cancelled, return STOP. */
   5071 	MUTEX_ENTER(&nxge->poll_lock);
   5072 	if (nxge->suspended || nxge->poll_state == LINK_MONITOR_STOPPING) {
   5073 		nxge->poll_state = LINK_MONITOR_STOP;
   5074 		nxge->nxge_link_poll_timerid = 0;
   5075 		cv_broadcast(&nxge->poll_cv);
   5076 		MUTEX_EXIT(&nxge->poll_lock);
   5077 
   5078 		NXGE_DEBUG_MSG((nxge, MAC_CTL,
   5079 		    "nxge_check_%s_link(port<%d>) stopped.",
   5080 		    nxge->mac.portmode == PORT_10G_FIBER ? "10g" : "mii",
   5081 		    nxge->mac.portnum));
   5082 		return (CHECK_LINK_STOP);
   5083 	}
   5084 	MUTEX_EXIT(&nxge->poll_lock);
   5085 
   5086 	return (CHECK_LINK_RESCHEDULE);
   5087 }
   5088 
   5089 /*
   5090  * Check status of MII (MIF or PCS) link.
   5091  * This function is called once per second, that is because this function
   5092  * calls nxge_link_monitor with LINK_MONITOR_START, which starts a timer to
   5093  * call this function recursively.
   5094  */
   5095 static nxge_status_t
   5096 nxge_check_mii_link(p_nxge_t nxgep)
   5097 {
   5098 	mii_bmsr_t bmsr_ints, bmsr_data;
   5099 	mii_anlpar_t anlpar;
   5100 	mii_gsr_t gsr;
   5101 	p_mii_regs_t mii_regs;
   5102 	nxge_status_t status = NXGE_OK;
   5103 	uint8_t portn;
   5104 	nxge_link_state_t link_up;
   5105 
   5106 	if (nxgep->nxge_magic != NXGE_MAGIC)
   5107 		return (NXGE_ERROR);
   5108 
   5109 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
   5110 		return (NXGE_OK);
   5111 
   5112 	portn = nxgep->mac.portnum;
   5113 
   5114 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>",
   5115 	    portn));
   5116 
   5117 	mii_regs = NULL;
   5118 
   5119 	RW_ENTER_WRITER(&nxgep->filter_lock);
   5120 
   5121 	if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10)
   5122 		goto nxge_check_mii_link_exit;
   5123 
   5124 	switch (nxgep->mac.portmode) {
   5125 	default:
   5126 		bmsr_data.value = 0;
   5127 		if ((status = nxge_mii_read(nxgep,
   5128 		    nxgep->statsp->mac_stats.xcvr_portn,
   5129 #if defined(__i386)
   5130 		    (uint8_t)(uint32_t)(&mii_regs->bmsr),
   5131 #else
   5132 		    (uint8_t)(uint64_t)(&mii_regs->bmsr),
   5133 #endif
   5134 		    &bmsr_data.value)) != NXGE_OK) {
   5135 			goto fail;
   5136 		}
   5137 
   5138 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   5139 		    "==> nxge_check_mii_link port<0x%x> "
   5140 		    "RIGHT AFTER READ bmsr_data 0x%x (nxgep->bmsr 0x%x ",
   5141 		    portn, bmsr_data.value, nxgep->bmsr.value));
   5142 
   5143 		if (nxgep->param_arr[param_autoneg].value) {
   5144 			if ((status = nxge_mii_read(nxgep,
   5145 			    nxgep->statsp->mac_stats.xcvr_portn,
   5146 #if defined(__i386)
   5147 			    (uint8_t)(uint32_t)(&mii_regs->gsr),
   5148 #else
   5149 			    (uint8_t)(uint64_t)(&mii_regs->gsr),
   5150 #endif
   5151 			    &gsr.value)) != NXGE_OK)
   5152 				goto fail;
   5153 			if ((status = nxge_mii_read(nxgep,
   5154 			    nxgep->statsp->mac_stats.xcvr_portn,
   5155 #if defined(__i386)
   5156 			    (uint8_t)(uint32_t)(&mii_regs->anlpar),
   5157 #else
   5158 			    (uint8_t)(uint64_t)(&mii_regs->anlpar),
   5159 #endif
   5160 			    &anlpar.value)) != NXGE_OK)
   5161 				goto fail;
   5162 			if (nxgep->mac.portmode != PORT_1G_RGMII_FIBER) {
   5163 
   5164 				if (nxgep->statsp->mac_stats.link_up &&
   5165 				    ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^
   5166 				    gsr.bits.link_1000fdx) ||
   5167 				    (nxgep->statsp->mac_stats.lp_cap_1000hdx ^
   5168 				    gsr.bits.link_1000hdx) ||
   5169 				    (nxgep->statsp->mac_stats.lp_cap_100T4 ^
   5170 				    anlpar.bits.cap_100T4) ||
   5171 				    (nxgep->statsp->mac_stats.lp_cap_100fdx ^
   5172 				    anlpar.bits.cap_100fdx) ||
   5173 				    (nxgep->statsp->mac_stats.lp_cap_100hdx ^
   5174 				    anlpar.bits.cap_100hdx) ||
   5175 				    (nxgep->statsp->mac_stats.lp_cap_10fdx ^
   5176 				    anlpar.bits.cap_10fdx) ||
   5177 				    (nxgep->statsp->mac_stats.lp_cap_10hdx ^
   5178 				    anlpar.bits.cap_10hdx))) {
   5179 					bmsr_data.bits.link_status = 0;
   5180 				}
   5181 			}
   5182 		}
   5183 
   5184 		/* Workaround for link down issue */
   5185 		if (bmsr_data.value == 0) {
   5186 			cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n");
   5187 			goto nxge_check_mii_link_exit;
   5188 		}
   5189 
   5190 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   5191 		    "==> nxge_check_mii_link port<0x%x> :"
   5192 		    "BEFORE BMSR ^ nxgep->bmsr 0x%x bmsr_data 0x%x",
   5193 		    portn, nxgep->bmsr.value, bmsr_data.value));
   5194 
   5195 		bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value;
   5196 		nxgep->bmsr.value = bmsr_data.value;
   5197 
   5198 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   5199 		    "==> nxge_check_mii_link port<0x%x> CALLING "
   5200 		    "bmsr_data 0x%x bmsr_ints.value 0x%x",
   5201 		    portn, bmsr_data.value, bmsr_ints.value));
   5202 
   5203 		if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints,
   5204 		    &link_up)) != NXGE_OK) {
   5205 			goto fail;
   5206 		}
   5207 		break;
   5208 
   5209 	case PORT_1G_SERDES:
   5210 		/*
   5211 		 * Above default is for all cases except PORT_1G_SERDES.
   5212 		 * The default case gets information from the PHY, but a
   5213 		 * nxge whose portmode equals PORT_1G_SERDES does not
   5214 		 * have a PHY.
   5215 		 */
   5216 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   5217 		    "==> nxge_check_mii_link port<%d> (SERDES)", portn));
   5218 		nxge_pcs_check(nxgep, portn, &link_up);
   5219 		break;
   5220 	}
   5221 
   5222 nxge_check_mii_link_exit:
   5223 	RW_EXIT(&nxgep->filter_lock);
   5224 	if (link_up == LINK_IS_UP) {
   5225 		nxge_link_is_up(nxgep);
   5226 	} else if (link_up == LINK_IS_DOWN) {
   5227 		nxge_link_is_down(nxgep);
   5228 	}
   5229 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
   5230 
   5231 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>",
   5232 	    portn));
   5233 	return (NXGE_OK);
   5234 
   5235 fail:
   5236 	RW_EXIT(&nxgep->filter_lock);
   5237 
   5238 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
   5239 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   5240 	    "nxge_check_mii_link: Failed to check link port<%d>", portn));
   5241 	return (status);
   5242 }
   5243 
   5244 /*ARGSUSED*/
   5245 static nxge_status_t
   5246 nxge_check_10g_link(p_nxge_t nxgep)
   5247 {
   5248 	uint8_t		portn;
   5249 	nxge_status_t	status = NXGE_OK;
   5250 	boolean_t	link_up;
   5251 	uint32_t	val;
   5252 	npi_status_t	rs;
   5253 
   5254 	if (nxgep->nxge_magic != NXGE_MAGIC)
   5255 		return (NXGE_ERROR);
   5256 
   5257 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
   5258 		return (NXGE_OK);
   5259 
   5260 	portn = nxgep->mac.portnum;
   5261 	val = 0;
   5262 	rs = NPI_SUCCESS;
   5263 
   5264 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>",
   5265 	    portn));
   5266 
   5267 	switch (nxgep->mac.portmode) {
   5268 	default:
   5269 		/*
   5270 		 * Check if the phy is present in case of hot swappable phy
   5271 		 */
   5272 		if (nxgep->hot_swappable_phy) {
   5273 			boolean_t phy_present_now = B_FALSE;
   5274 
   5275 			/*
   5276 			 * If this is the 2nd Goa port, then check 2 addresses
   5277 			 * to take care of the Goa NEM card requirements.
   5278 			 */
   5279 			if (portn == 1) {
   5280 				if (nxge_is_phy_present(nxgep,
   5281 				    ALT_GOA_CLAUSE45_PORT1_ADDR,
   5282 				    BCM8706_DEV_ID, BCM_PHY_ID_MASK)) {
   5283 					phy_present_now = B_TRUE;
   5284 					nxgep->xcvr_addr =
   5285 					    ALT_GOA_CLAUSE45_PORT1_ADDR;
   5286 					goto phy_check_done;
   5287 				}
   5288 			}
   5289 			if (nxge_is_phy_present(nxgep,
   5290 			    (GOA_CLAUSE45_PORT_ADDR_BASE) + portn,
   5291 			    BCM8706_DEV_ID, BCM_PHY_ID_MASK)) {
   5292 				nxgep->xcvr_addr =
   5293 				    (GOA_CLAUSE45_PORT_ADDR_BASE) + portn;
   5294 				phy_present_now = B_TRUE;
   5295 			}
   5296 
   5297 phy_check_done:
   5298 			/* Check back-to-back XAUI connect to detect Opus NEM */
   5299 			rs = npi_xmac_xpcs_read(nxgep->npi_handle,
   5300 			    nxgep->mac.portnum, XPCS_REG_STATUS, &val);
   5301 			if (rs != 0)
   5302 				goto fail;
   5303 
   5304 			link_up = B_FALSE;
   5305 			if (val & XPCS_STATUS_LANE_ALIGN) {
   5306 				link_up = B_TRUE;
   5307 			}
   5308 
   5309 			if (nxgep->phy_absent) {
   5310 				if (phy_present_now) {
   5311 				/*
   5312 				 * Detect, Initialize phy and do link up
   5313 				 * set xcvr vals, link_init, nxge_init
   5314 				 */
   5315 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   5316 					    "Hot swappable phy DETECTED!!"));
   5317 					nxgep->phy_absent = B_FALSE;
   5318 					(void) nxge_xcvr_find(nxgep);
   5319 					(void) nxge_link_init(nxgep);
   5320 					if (!(nxgep->drv_state &
   5321 					    STATE_HW_INITIALIZED)) {
   5322 						status = nxge_init(nxgep);
   5323 						if (status != NXGE_OK) {
   5324 							NXGE_ERROR_MSG((nxgep,
   5325 							    NXGE_ERR_CTL,
   5326 							    "Hot swappable "
   5327 							    "phy present, but"
   5328 							    " driver init"
   5329 							    "  failed..."));
   5330 							goto fail;
   5331 						}
   5332 					}
   5333 				} else if (link_up) { /* XAUI linkup, no PHY */
   5334 					/*
   5335 					 * This is the back-to-back XAUI
   5336 					 * connect case for Opus NEM.
   5337 					 */
   5338 					nxgep->statsp->mac_stats.xcvr_inuse =
   5339 					    XPCS_XCVR;
   5340 					nxgep->mac.portmode = PORT_10G_SERDES;
   5341 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   5342 					    "HSP 10G Serdes DETECTED!!"));
   5343 					break;
   5344 				}
   5345 
   5346 				if (nxgep->link_notify &&
   5347 				    nxgep->link_check_count > 3 &&
   5348 				    nxgep->nxge_mac_state == NXGE_MAC_STARTED ||
   5349 				    nxgep->statsp->mac_stats.link_up == 1) {
   5350 					nxgep->statsp->mac_stats.link_up = 0;
   5351 					nxgep->statsp->mac_stats.link_speed = 0;
   5352 					nxgep->statsp->mac_stats.link_duplex =
   5353 					    0;
   5354 
   5355 					nxge_link_is_down(nxgep);
   5356 					nxgep->link_notify = B_FALSE;
   5357 				}
   5358 
   5359 				goto start_link_check;
   5360 
   5361 			} else if (!phy_present_now) {
   5362 				/*
   5363 				 * Phy gone, bring link down reset xcvr vals
   5364 				 */
   5365 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   5366 				    "Hot swappable phy REMOVED!!"));
   5367 				nxgep->phy_absent = B_TRUE;
   5368 				nxgep->statsp->mac_stats.link_up = 0;
   5369 				nxgep->statsp->mac_stats.link_speed = 0;
   5370 				nxgep->statsp->mac_stats.link_duplex = 0;
   5371 				nxge_link_is_down(nxgep);
   5372 				nxgep->link_notify = B_FALSE;
   5373 
   5374 				(void) nxge_xcvr_find(nxgep);
   5375 
   5376 				goto start_link_check;
   5377 
   5378 			}
   5379 		}
   5380 		if (nxgep->chip_id == MRVL88X201X_CHIP_ID) {
   5381 			status = nxge_check_mrvl88x2011_link(nxgep, &link_up);
   5382 		} else {
   5383 			status = nxge_check_bcm8704_link(nxgep, &link_up);
   5384 		}
   5385 		if (status != NXGE_OK)
   5386 			goto fail;
   5387 		break;
   5388 	case PORT_10G_SERDES:
   5389 		rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
   5390 		    XPCS_REG_STATUS, &val);
   5391 		if (rs != 0)
   5392 			goto fail;
   5393 
   5394 		link_up = B_FALSE;
   5395 		if (val & XPCS_STATUS_LANE_ALIGN) {
   5396 			link_up = B_TRUE;
   5397 		}
   5398 
   5399 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   5400 		    "==> nxge_check_10g_link port<%d> "
   5401 		    "XPCS_REG_STATUS2 0x%x link_up %d",
   5402 		    portn, val, link_up));
   5403 
   5404 		break;
   5405 	}
   5406 
   5407 	if (link_up) {
   5408 		if ((nxgep->link_notify &&
   5409 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
   5410 		    nxgep->statsp->mac_stats.link_up == 0) {
   5411 			if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
   5412 				goto fail;
   5413 			nxgep->statsp->mac_stats.link_up = 1;
   5414 			nxgep->statsp->mac_stats.link_speed = 10000;
   5415 			nxgep->statsp->mac_stats.link_duplex = 2;
   5416 
   5417 			nxge_link_is_up(nxgep);
   5418 			nxgep->link_notify = B_FALSE;
   5419 		}
   5420 	} else {
   5421 		if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
   5422 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
   5423 		    nxgep->statsp->mac_stats.link_up == 1) {
   5424 			if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
   5425 				goto fail;
   5426 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   5427 			    "Link down cable problem"));
   5428 			nxgep->statsp->mac_stats.link_up = 0;
   5429 			nxgep->statsp->mac_stats.link_speed = 0;
   5430 			nxgep->statsp->mac_stats.link_duplex = 0;
   5431 
   5432 			nxge_link_is_down(nxgep);
   5433 			nxgep->link_notify = B_FALSE;
   5434 
   5435 			if (nxgep->mac.portmode == PORT_10G_SERDES) {
   5436 				/*
   5437 				 * NEM was unplugged, set up xcvr table
   5438 				 * to find another xcvr in the future.
   5439 				 */
   5440 				(void) nxge_xcvr_find(nxgep);
   5441 			}
   5442 		}
   5443 	}
   5444 
   5445 start_link_check:
   5446 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
   5447 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>",
   5448 	    portn));
   5449 	return (NXGE_OK);
   5450 
   5451 fail:
   5452 	(void) nxge_check_link_stop(nxgep);
   5453 
   5454 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   5455 	    "nxge_check_10g_link: Failed to check link port<%d>",
   5456 	    portn));
   5457 	return (status);
   5458 }
   5459 
   5460 
   5461 /* Declare link down */
   5462 
   5463 void
   5464 nxge_link_is_down(p_nxge_t nxgep)
   5465 {
   5466 	p_nxge_stats_t statsp;
   5467 	char link_stat_msg[64];
   5468 
   5469 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down"));
   5470 
   5471 	statsp = nxgep->statsp;
   5472 	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is down",
   5473 	    statsp->mac_stats.xcvr_portn);
   5474 
   5475 	if (nxge_no_msg == B_FALSE) {
   5476 		NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
   5477 	}
   5478 
   5479 	mac_link_update(nxgep->mach, LINK_STATE_DOWN);
   5480 
   5481 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down"));
   5482 }
   5483 
   5484 /* Declare link up */
   5485 
   5486 void
   5487 nxge_link_is_up(p_nxge_t nxgep)
   5488 {
   5489 	p_nxge_stats_t statsp;
   5490 	char link_stat_msg[64];
   5491 	uint32_t val;
   5492 
   5493 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up"));
   5494 
   5495 	statsp = nxgep->statsp;
   5496 	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is up %d Mbps ",
   5497 	    statsp->mac_stats.xcvr_portn,
   5498 	    statsp->mac_stats.link_speed);
   5499 
   5500 	if (statsp->mac_stats.link_T4)
   5501 		(void) strcat(link_stat_msg, "T4");
   5502 	else if (statsp->mac_stats.link_duplex == 2)
   5503 		(void) strcat(link_stat_msg, "full duplex");
   5504 	else
   5505 		(void) strcat(link_stat_msg, "half duplex");
   5506 
   5507 
   5508 	/* Clean up symbol errors incurred during link transition */
   5509 	if ((nxgep->mac.portmode == PORT_10G_FIBER) ||
   5510 	    (nxgep->mac.portmode == PORT_10G_SERDES)) {
   5511 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
   5512 		    XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
   5513 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
   5514 		    XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
   5515 	}
   5516 
   5517 	/*
   5518 	 * If the driver was plumbed without a link (therefore auto-negotiation
   5519 	 * could not complete), the driver will detect a link up when a cable
   5520 	 * conneting to a link partner is plugged into the port. By the time
   5521 	 * link-up is detected, auto-negotiation should have completed (The
   5522 	 * TN1010 tries to contact a link partner every 8~24ms). Here we re-
   5523 	 * configure the Neptune/NIU according to the newly negotiated speed.
   5524 	 * This is necessary only for the TN1010 basad device because only the
   5525 	 * TN1010 supports dual speeds.
   5526 	 */
   5527 	if (nxgep->mac.portmode == PORT_1G_TN1010 ||
   5528 	    nxgep->mac.portmode == PORT_10G_TN1010) {
   5529 
   5530 		(void) nxge_set_tn1010_param(nxgep);
   5531 
   5532 		/*
   5533 		 * nxge_xcvr_find calls nxge_get_xcvr_type (which sets
   5534 		 * nxgep->portmode) and nxge_setup_xcvr_table (which sets
   5535 		 * the nxgep->xcvr to the proper nxge_xcvr_table_t struct).
   5536 		 */
   5537 		if (nxge_xcvr_find(nxgep) != NXGE_OK) {
   5538 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   5539 			    "nxge_link_is_up: nxge_xcvr_find failed"));
   5540 		}
   5541 
   5542 		/* nxge_link_init calls nxge_xcvr_init and nxge_serdes_init */
   5543 		if (nxge_link_init(nxgep) != NXGE_OK) {
   5544 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   5545 			    "nxge_link_is_up: nxge_link_init failed"));
   5546 		}
   5547 
   5548 		/*
   5549 		 * nxge_mac_init calls many subroutines including
   5550 		 * nxge_xif_init which sets XGMII or GMII mode
   5551 		 */
   5552 		if (nxge_mac_init(nxgep) != NXGE_OK) {
   5553 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   5554 			    "nxge_link_is_up: nxge_mac_init failed"));
   5555 		}
   5556 	} else {
   5557 		(void) nxge_xif_init(nxgep);
   5558 	}
   5559 
   5560 	if (nxge_no_msg == B_FALSE) {
   5561 		NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
   5562 	}
   5563 
   5564 	mac_link_update(nxgep->mach, LINK_STATE_UP);
   5565 
   5566 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up"));
   5567 }
   5568 
   5569 #ifdef NXGE_DEBUG
   5570 /* Dump all TN1010 Status registers */
   5571 static void
   5572 nxge_dump_tn1010_status_regs(p_nxge_t nxgep)
   5573 {
   5574 	uint16_t val;
   5575 
   5576 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5577 	    TN1010_PMA_PMD_DEV_ADDR, 1, &val);
   5578 	cmn_err(CE_NOTE, "PMA status1 = 0x%x", val);
   5579 
   5580 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5581 	    TN1010_PMA_PMD_DEV_ADDR, 8, &val);
   5582 	cmn_err(CE_NOTE, "PMA status2 = 0x%x", val);
   5583 
   5584 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5585 	    TN1010_PMA_PMD_DEV_ADDR, 129, &val);
   5586 	cmn_err(CE_NOTE, "10BASET-T status = 0x%x", val);
   5587 
   5588 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5589 	    TN1010_PCS_DEV_ADDR, 1, &val);
   5590 	cmn_err(CE_NOTE, "PCS status1 = 0x%x", val);
   5591 
   5592 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5593 	    TN1010_PCS_DEV_ADDR, 8, &val);
   5594 	cmn_err(CE_NOTE, "PCS status2 = 0x%x", val);
   5595 
   5596 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5597 	    TN1010_PCS_DEV_ADDR, 32, &val);
   5598 	cmn_err(CE_NOTE, "10GBASE-R status1 = 0x%x", val);
   5599 
   5600 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5601 	    TN1010_PCS_DEV_ADDR, 33, &val);
   5602 	cmn_err(CE_NOTE, "10GBASE-R Status2 = 0x%x", val);
   5603 
   5604 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5605 	    TN1010_PHYXS_DEV_ADDR, 1, &val);
   5606 	cmn_err(CE_NOTE, "PHYXS status1 = 0x%x", val);
   5607 
   5608 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5609 	    TN1010_PHYXS_DEV_ADDR, 8, &val);
   5610 	cmn_err(CE_NOTE, "PHYXS status2 = 0x%x", val);
   5611 
   5612 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5613 	    TN1010_PHYXS_DEV_ADDR, 24, &val);
   5614 	cmn_err(CE_NOTE, "XGXS Lane status = 0x%x", val);
   5615 
   5616 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5617 	    TN1010_AUTONEG_DEV_ADDR, 1, &val);
   5618 	cmn_err(CE_NOTE, "Autoneg status = 0x%x", val);
   5619 
   5620 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5621 	    TN1010_AUTONEG_DEV_ADDR, 33, &val);
   5622 	cmn_err(CE_NOTE, "10Gbase-T An status = 0x%x", val);
   5623 
   5624 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5625 	    TN1010_VENDOR_MMD1_DEV_ADDR, 1, &val);
   5626 	cmn_err(CE_NOTE, "TN1010 status = 0x%x", val);
   5627 
   5628 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5629 	    TN1010_VENDOR_MMD1_DEV_ADDR, 8, &val);
   5630 	cmn_err(CE_NOTE, "Device status = 0x%x", val);
   5631 
   5632 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5633 	    TN1010_VENDOR_MMD1_DEV_ADDR, 16, &val);
   5634 	cmn_err(CE_NOTE, "DDR status = 0x%x", val);
   5635 
   5636 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5637 	    TN1010_VENDOR_MMD1_DEV_ADDR, 17, &val);
   5638 	cmn_err(CE_NOTE, "DDR fault status = 0x%x", val);
   5639 
   5640 	nxge_mdio_read(nxgep, nxgep->xcvr_addr,
   5641 	    TN1010_VENDOR_MMD1_DEV_ADDR, 11, &val);
   5642 	cmn_err(CE_NOTE, "Firmware Revision = 0x%x  Major = 0x%x Minor = 0x%x",
   5643 	    val,  (val & 0xFF00) >> 8, val & 0x00FF);
   5644 }
   5645 #endif
   5646 
   5647 /*
   5648  * Calculate the bit in the multicast address filter
   5649  * that selects the given * address.
   5650  * Note: For GEM, the last 8-bits are used.
   5651  */
   5652 uint32_t
   5653 crc32_mchash(p_ether_addr_t addr)
   5654 {
   5655 	uint8_t *cp;
   5656 	uint32_t crc;
   5657 	uint32_t c;
   5658 	int byte;
   5659 	int bit;
   5660 
   5661 	cp = (uint8_t *)addr;
   5662 	crc = (uint32_t)0xffffffff;
   5663 	for (byte = 0; byte < 6; byte++) {
   5664 		c = (uint32_t)cp[byte];
   5665 		for (bit = 0; bit < 8; bit++) {
   5666 			if ((c & 0x1) ^ (crc & 0x1))
   5667 				crc = (crc >> 1)^0xedb88320;
   5668 			else
   5669 				crc = (crc >> 1);
   5670 			c >>= 1;
   5671 		}
   5672 	}
   5673 	return ((~crc) >> (32 - HASH_BITS));
   5674 }
   5675 
   5676 /* Reset serdes */
   5677 
   5678 nxge_status_t
   5679 nxge_serdes_reset(p_nxge_t nxgep)
   5680 {
   5681 	npi_handle_t		handle;
   5682 
   5683 	handle = nxgep->npi_handle;
   5684 
   5685 	ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1);
   5686 	drv_usecwait(500);
   5687 	ESR_REG_WR(handle, ESR_CONFIG_REG, 0);
   5688 
   5689 	return (NXGE_OK);
   5690 }
   5691 
   5692 /*
   5693  * This function monitors link status using interrupt or polling.
   5694  * It calls nxgep->xcvr.check_link, a member function of
   5695  * nxge_xcvr_table_t. But nxgep->xcvr.check_link calls this
   5696  * function back, that is why the check_link routine is
   5697  * executed periodically.
   5698  */
   5699 nxge_status_t
   5700 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable)
   5701 {
   5702 	nxge_status_t status = NXGE_OK;
   5703 
   5704 	/* If we are a guest domain driver, don't bother. */
   5705 	if (isLDOMguest(nxgep))
   5706 		return (status);
   5707 
   5708 	/*
   5709 	 * Return immediately if this is an imaginary XMAC port.
   5710 	 * (At least, we don't have 4-port XMAC cards yet.)
   5711 	 */
   5712 	if ((nxgep->mac.portmode == PORT_10G_FIBER ||
   5713 	    nxgep->mac.portmode == PORT_10G_SERDES) &&
   5714 	    (nxgep->mac.portnum > 1))
   5715 		return (NXGE_OK);
   5716 
   5717 	if (nxgep->statsp == NULL) {
   5718 		/* stats has not been allocated. */
   5719 		return (NXGE_OK);
   5720 	}
   5721 	/* Don't check link if we're in internal loopback mode */
   5722 	if (nxgep->statsp->port_stats.lb_mode >= nxge_lb_serdes10g)
   5723 		return (NXGE_OK);
   5724 
   5725 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   5726 	    "==> nxge_link_monitor port<%d> enable=%d",
   5727 	    nxgep->mac.portnum, enable));
   5728 	if (enable == LINK_MONITOR_START) {
   5729 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
   5730 			if ((status = nxge_link_intr(nxgep, LINK_INTR_START))
   5731 			    != NXGE_OK)
   5732 				goto fail;
   5733 		} else {
   5734 			timeout_id_t timerid;
   5735 			/*
   5736 			 * check_link_stop means "Stop the link check", so
   5737 			 * we return without starting the timer.
   5738 			 */
   5739 			if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
   5740 				return (NXGE_OK);
   5741 
   5742 			/*
   5743 			 * Otherwise fire the timer for the nxge to check
   5744 			 * the link using the check_link function
   5745 			 * of the nxge_xcvr_table and pass "nxgep" as the
   5746 			 * argument to the check_link function.
   5747 			 */
   5748 			if (nxgep->xcvr.check_link) {
   5749 				timerid = timeout(
   5750 				    (fptrv_t)(nxgep->xcvr.check_link),
   5751 				    nxgep,
   5752 				    drv_usectohz(LINK_MONITOR_PERIOD));
   5753 				MUTEX_ENTER(&nxgep->poll_lock);
   5754 				nxgep->nxge_link_poll_timerid = timerid;
   5755 				MUTEX_EXIT(&nxgep->poll_lock);
   5756 				nxgep->link_check_count ++;
   5757 			} else {
   5758 				return (NXGE_ERROR);
   5759 			}
   5760 		}
   5761 	} else {
   5762 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
   5763 			if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP))
   5764 			    != NXGE_OK)
   5765 				goto fail;
   5766 		} else {
   5767 			clock_t rv;
   5768 
   5769 			MUTEX_ENTER(&nxgep->poll_lock);
   5770 
   5771 			/* If <timerid> == 0, the link monitor has */
   5772 			/* never been started, or just now stopped. */
   5773 			if (nxgep->nxge_link_poll_timerid == 0) {
   5774 				MUTEX_EXIT(&nxgep->poll_lock);
   5775 				return (NXGE_OK);
   5776 			}
   5777 
   5778 			nxgep->poll_state = LINK_MONITOR_STOPPING;
   5779 			rv = cv_reltimedwait(&nxgep->poll_cv, &nxgep->poll_lock,
   5780 			    drv_usectohz(LM_WAIT_MULTIPLIER *
   5781 			    LINK_MONITOR_PERIOD), TR_CLOCK_TICK);
   5782 			if (rv == -1) {
   5783 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   5784 				    "==> stopping port %d: "
   5785 				    "cv_timedwait(%d) timed out",
   5786 				    nxgep->mac.portnum, nxgep->poll_state));
   5787 				nxgep->poll_state = LINK_MONITOR_STOP;
   5788 				nxgep->nxge_link_poll_timerid = 0;
   5789 			}
   5790 
   5791 			MUTEX_EXIT(&nxgep->poll_lock);
   5792 		}
   5793 	}
   5794 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   5795 	    "<== nxge_link_monitor port<%d> enable=%d",
   5796 	    nxgep->mac.portnum, enable));
   5797 
   5798 	return (NXGE_OK);
   5799 fail:
   5800 	return (status);
   5801 
   5802 }
   5803 
   5804 nxge_status_t
   5805 nxge_check_tn1010_link(p_nxge_t nxgep)
   5806 {
   5807 	nxge_status_t	status = NXGE_OK;
   5808 	nxge_link_state_t link_up;
   5809 
   5810 	if (nxgep->nxge_magic != NXGE_MAGIC) {
   5811 		/* magic is 0 if driver is not attached */
   5812 		return (NXGE_ERROR);
   5813 	}
   5814 
   5815 	/* Link has been stopped, no need to continue */
   5816 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP) {
   5817 		return (NXGE_OK);
   5818 	}
   5819 
   5820 	if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10)
   5821 		goto nxge_check_tn1010_link_exit;
   5822 
   5823 	if ((status = nxge_tn1010_check(nxgep, &link_up)) != NXGE_OK)
   5824 		goto fail;
   5825 
   5826 nxge_check_tn1010_link_exit:
   5827 	if (link_up == LINK_IS_UP)
   5828 		nxge_link_is_up(nxgep);
   5829 	else if (link_up == LINK_IS_DOWN)
   5830 		nxge_link_is_down(nxgep);
   5831 
   5832 	/*
   5833 	 * nxge_link_monitor will call (nxgep->xcvr.check_link)
   5834 	 * which could be THIS function.
   5835 	 */
   5836 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
   5837 
   5838 	return (NXGE_OK);
   5839 
   5840 fail:
   5841 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
   5842 
   5843 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   5844 	    "nxge_check_tn1010_link: Failed to check link"));
   5845 	return (status);
   5846 }
   5847 
   5848 
   5849 /*
   5850  * Fill variable "link_up" with either LINK_IS_UP or LINK_IS_DOWN.
   5851  */
   5852 static nxge_status_t
   5853 nxge_tn1010_check(p_nxge_t nxgep, nxge_link_state_t *link_up)
   5854 {
   5855 	nxge_status_t	status = NXGE_OK;
   5856 	p_nxge_stats_t	statsp;
   5857 	uint8_t		phy_port_addr, portn;
   5858 	uint16_t	val;
   5859 
   5860 	*link_up = LINK_NO_CHANGE;
   5861 
   5862 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
   5863 	phy_port_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
   5864 	statsp = nxgep->statsp;
   5865 
   5866 	/* Check if link is up */
   5867 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
   5868 	    TN1010_AUTONEG_DEV_ADDR, TN1010_AUTONEG_STATUS_REG, &val))
   5869 	    != NXGE_OK) {
   5870 		goto fail;
   5871 	}
   5872 	/*
   5873 	 * nxge_link_is_up has called nxge_set_tn1010_param and set
   5874 	 * portmode and link_speed
   5875 	 */
   5876 	if (val & TN1010_AN_LINK_STAT_BIT) {
   5877 		if ((nxgep->link_notify &&
   5878 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
   5879 		    nxgep->statsp->mac_stats.link_up == 0) {
   5880 			statsp->mac_stats.link_up = 1;
   5881 			statsp->mac_stats.link_duplex = 2;
   5882 			*link_up = LINK_IS_UP;
   5883 			nxgep->link_notify = B_FALSE;
   5884 		}
   5885 	} else {
   5886 		if ((nxgep->link_notify && nxgep->link_check_count > 3 &&
   5887 		    nxgep->nxge_mac_state == NXGE_MAC_STARTED) ||
   5888 		    nxgep->statsp->mac_stats.link_up == 1) {
   5889 			statsp->mac_stats.link_up = 0;
   5890 			statsp->mac_stats.link_speed = 0;
   5891 			statsp->mac_stats.link_duplex = 0;
   5892 			*link_up = LINK_IS_DOWN;
   5893 			nxgep->link_notify = B_FALSE;
   5894 		}
   5895 	}
   5896 	return (NXGE_OK);
   5897 
   5898 fail:
   5899 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   5900 	    "nxge_tn1010_check: Unable to check TN1010"));
   5901 	return (status);
   5902 }
   5903 
   5904 
   5905 /* Set promiscous mode */
   5906 
   5907 nxge_status_t
   5908 nxge_set_promisc(p_nxge_t nxgep, boolean_t on)
   5909 {
   5910 	nxge_status_t status = NXGE_OK;
   5911 
   5912 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on));
   5913 
   5914 	nxgep->filter.all_phys_cnt = ((on) ? 1 : 0);
   5915 
   5916 	RW_ENTER_WRITER(&nxgep->filter_lock);
   5917 
   5918 	if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) {
   5919 		goto fail;
   5920 	}
   5921 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) {
   5922 		goto fail;
   5923 	}
   5924 
   5925 	RW_EXIT(&nxgep->filter_lock);
   5926 
   5927 	if (on)
   5928 		nxgep->statsp->mac_stats.promisc = B_TRUE;
   5929 	else
   5930 		nxgep->statsp->mac_stats.promisc = B_FALSE;
   5931 
   5932 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc"));
   5933 
   5934 	return (NXGE_OK);
   5935 fail:
   5936 	RW_EXIT(&nxgep->filter_lock);
   5937 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: "
   5938 	    "Unable to set promisc (%d)", on));
   5939 
   5940 	return (status);
   5941 }
   5942 
   5943 /*ARGSUSED*/
   5944 uint_t
   5945 nxge_mif_intr(void *arg1, void *arg2)
   5946 {
   5947 #ifdef	NXGE_DEBUG
   5948 	p_nxge_t		nxgep = (p_nxge_t)arg2;
   5949 #endif
   5950 #if NXGE_MIF
   5951 	p_nxge_ldv_t		ldvp = (p_nxge_ldv_t)arg1;
   5952 	uint32_t		status;
   5953 	npi_handle_t		handle;
   5954 	uint8_t			portn;
   5955 	p_nxge_stats_t		statsp;
   5956 #endif
   5957 
   5958 #ifdef	NXGE_MIF
   5959 	if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
   5960 		nxgep = ldvp->nxgep;
   5961 	}
   5962 	nxgep = ldvp->nxgep;
   5963 #endif
   5964 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr"));
   5965 
   5966 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
   5967 	return (DDI_INTR_CLAIMED);
   5968 
   5969 mif_intr_fail:
   5970 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
   5971 	return (DDI_INTR_UNCLAIMED);
   5972 }
   5973 
   5974 /*ARGSUSED*/
   5975 uint_t
   5976 nxge_mac_intr(void *arg1, void *arg2)
   5977 {
   5978 	p_nxge_t		nxgep = (p_nxge_t)arg2;
   5979 	p_nxge_ldv_t		ldvp = (p_nxge_ldv_t)arg1;
   5980 	p_nxge_ldg_t		ldgp;
   5981 	uint32_t		status;
   5982 	npi_handle_t		handle;
   5983 	uint8_t			portn;
   5984 	p_nxge_stats_t		statsp;
   5985 	npi_status_t		rs = NPI_SUCCESS;
   5986 
   5987 	if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
   5988 		nxgep = ldvp->nxgep;
   5989 	}
   5990 
   5991 	ldgp = ldvp->ldgp;
   5992 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: "
   5993 	    "group %d", ldgp->ldg));
   5994 
   5995 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
   5996 	/*
   5997 	 * This interrupt handler is for a specific
   5998 	 * mac port.
   5999 	 */
   6000 	statsp = (p_nxge_stats_t)nxgep->statsp;
   6001 	portn = nxgep->mac.portnum;
   6002 
   6003 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
   6004 	    "==> nxge_mac_intr: reading mac stats: port<%d>", portn));
   6005 
   6006 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
   6007 		rs = npi_xmac_tx_get_istatus(handle, portn,
   6008 		    (xmac_tx_iconfig_t *)&status);
   6009 		if (rs != NPI_SUCCESS)
   6010 			goto npi_fail;
   6011 		if (status & ICFG_XMAC_TX_ALL) {
   6012 			if (status & ICFG_XMAC_TX_UNDERRUN) {
   6013 				statsp->xmac_stats.tx_underflow_err++;
   6014 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
   6015 				    NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
   6016 			}
   6017 			if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) {
   6018 				statsp->xmac_stats.tx_maxpktsize_err++;
   6019 				/*
   6020 				 * Do not send FMA ereport because this
   6021 				 * error does not indicate HW failure.
   6022 				 */
   6023 			}
   6024 			if (status & ICFG_XMAC_TX_OVERFLOW) {
   6025 				statsp->xmac_stats.tx_overflow_err++;
   6026 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
   6027 				    NXGE_FM_EREPORT_TXMAC_OVERFLOW);
   6028 			}
   6029 			if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) {
   6030 				statsp->xmac_stats.tx_fifo_xfr_err++;
   6031 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
   6032 				    NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR);
   6033 			}
   6034 			if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) {
   6035 				statsp->xmac_stats.tx_byte_cnt +=
   6036 				    XTXMAC_BYTE_CNT_MASK;
   6037 			}
   6038 			if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) {
   6039 				statsp->xmac_stats.tx_frame_cnt +=
   6040 				    XTXMAC_FRM_CNT_MASK;
   6041 			}
   6042 		}
   6043 
   6044 		rs = npi_xmac_rx_get_istatus(handle, portn,
   6045 		    (xmac_rx_iconfig_t *)&status);
   6046 		if (rs != NPI_SUCCESS)
   6047 			goto npi_fail;
   6048 		if (status & ICFG_XMAC_RX_ALL) {
   6049 			if (status & ICFG_XMAC_RX_OVERFLOW)
   6050 				statsp->xmac_stats.rx_overflow_err++;
   6051 			if (status & ICFG_XMAC_RX_UNDERFLOW) {
   6052 				statsp->xmac_stats.rx_underflow_err++;
   6053 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
   6054 				    NXGE_FM_EREPORT_RXMAC_UNDERFLOW);
   6055 			}
   6056 			/*
   6057 			 * Do not send FMA ereport for the following 3 errors
   6058 			 * because they do not indicate HW failures.
   6059 			 */
   6060 			if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) {
   6061 				statsp->xmac_stats.rx_crc_err_cnt +=
   6062 				    XRXMAC_CRC_ER_CNT_MASK;
   6063 			}
   6064 			if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) {
   6065 				statsp->xmac_stats.rx_len_err_cnt +=
   6066 				    MAC_LEN_ER_CNT_MASK;
   6067 			}
   6068 			if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) {
   6069 				statsp->xmac_stats.rx_viol_err_cnt +=
   6070 				    XRXMAC_CD_VIO_CNT_MASK;
   6071 			}
   6072 			if (status & ICFG_XMAC_RX_OCT_CNT_EXP) {
   6073 				statsp->xmac_stats.rx_byte_cnt +=
   6074 				    XRXMAC_BT_CNT_MASK;
   6075 			}
   6076 			if (status & ICFG_XMAC_RX_HST_CNT1_EXP) {
   6077 				statsp->xmac_stats.rx_hist1_cnt +=
   6078 				    XRXMAC_HIST_CNT1_MASK;
   6079 			}
   6080 			if (status & ICFG_XMAC_RX_HST_CNT2_EXP) {
   6081 				statsp->xmac_stats.rx_hist2_cnt +=
   6082 				    XRXMAC_HIST_CNT2_MASK;
   6083 			}
   6084 			if (status & ICFG_XMAC_RX_HST_CNT3_EXP) {
   6085 				statsp->xmac_stats.rx_hist3_cnt +=
   6086 				    XRXMAC_HIST_CNT3_MASK;
   6087 			}
   6088 			if (status & ICFG_XMAC_RX_HST_CNT4_EXP) {
   6089 				statsp->xmac_stats.rx_hist4_cnt +=
   6090 				    XRXMAC_HIST_CNT4_MASK;
   6091 			}
   6092 			if (status & ICFG_XMAC_RX_HST_CNT5_EXP) {
   6093 				statsp->xmac_stats.rx_hist5_cnt +=
   6094 				    XRXMAC_HIST_CNT5_MASK;
   6095 			}
   6096 			if (status & ICFG_XMAC_RX_HST_CNT6_EXP) {
   6097 				statsp->xmac_stats.rx_hist6_cnt +=
   6098 				    XRXMAC_HIST_CNT6_MASK;
   6099 			}
   6100 			if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) {
   6101 				statsp->xmac_stats.rx_broadcast_cnt +=
   6102 				    XRXMAC_BC_FRM_CNT_MASK;
   6103 			}
   6104 			if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) {
   6105 				statsp->xmac_stats.rx_mult_cnt +=
   6106 				    XRXMAC_MC_FRM_CNT_MASK;
   6107 			}
   6108 			/*
   6109 			 * Do not send FMA ereport for the following 3 errors
   6110 			 * because they do not indicate HW failures.
   6111 			 */
   6112 			if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) {
   6113 				statsp->xmac_stats.rx_frag_cnt +=
   6114 				    XRXMAC_FRAG_CNT_MASK;
   6115 			}
   6116 			if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) {
   6117 				statsp->xmac_stats.rx_frame_align_err_cnt +=
   6118 				    XRXMAC_AL_ER_CNT_MASK;
   6119 			}
   6120 			if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) {
   6121 				statsp->xmac_stats.rx_linkfault_err_cnt +=
   6122 				    XMAC_LINK_FLT_CNT_MASK;
   6123 			}
   6124 			if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) {
   6125 				statsp->xmac_stats.rx_remotefault_err++;
   6126 			}
   6127 			if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) {
   6128 				statsp->xmac_stats.rx_localfault_err++;
   6129 			}
   6130 		}
   6131 
   6132 		rs = npi_xmac_ctl_get_istatus(handle, portn,
   6133 		    (xmac_ctl_iconfig_t *)&status);
   6134 		if (rs != NPI_SUCCESS)
   6135 			goto npi_fail;
   6136 		if (status & ICFG_XMAC_CTRL_ALL) {
   6137 			if (status & ICFG_XMAC_CTRL_PAUSE_RCVD)
   6138 				statsp->xmac_stats.rx_pause_cnt++;
   6139 			if (status & ICFG_XMAC_CTRL_PAUSE_STATE)
   6140 				statsp->xmac_stats.tx_pause_state++;
   6141 			if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE)
   6142 				statsp->xmac_stats.tx_nopause_state++;
   6143 		}
   6144 	} else if (nxgep->mac.porttype == PORT_TYPE_BMAC) {
   6145 		rs = npi_bmac_tx_get_istatus(handle, portn,
   6146 		    (bmac_tx_iconfig_t *)&status);
   6147 		if (rs != NPI_SUCCESS)
   6148 			goto npi_fail;
   6149 		if (status & ICFG_BMAC_TX_ALL) {
   6150 			if (status & ICFG_BMAC_TX_UNDERFLOW) {
   6151 				statsp->bmac_stats.tx_underrun_err++;
   6152 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
   6153 				    NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
   6154 			}
   6155 			if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) {
   6156 				statsp->bmac_stats.tx_max_pkt_err++;
   6157 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
   6158 				    NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR);
   6159 			}
   6160 			if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) {
   6161 				statsp->bmac_stats.tx_byte_cnt +=
   6162 				    BTXMAC_BYTE_CNT_MASK;
   6163 			}
   6164 			if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) {
   6165 				statsp->bmac_stats.tx_frame_cnt +=
   6166 				    BTXMAC_FRM_CNT_MASK;
   6167 			}
   6168 		}
   6169 
   6170 		rs = npi_bmac_rx_get_istatus(handle, portn,
   6171 		    (bmac_rx_iconfig_t *)&status);
   6172 		if (rs != NPI_SUCCESS)
   6173 			goto npi_fail;
   6174 		if (status & ICFG_BMAC_RX_ALL) {
   6175 			if (status & ICFG_BMAC_RX_OVERFLOW) {
   6176 				statsp->bmac_stats.rx_overflow_err++;
   6177 			}
   6178 			if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) {
   6179 				statsp->bmac_stats.rx_frame_cnt +=
   6180 				    RXMAC_FRM_CNT_MASK;
   6181 			}
   6182 			if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) {
   6183 				statsp->bmac_stats.rx_crc_err_cnt +=
   6184 				    BMAC_CRC_ER_CNT_MASK;
   6185 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
   6186 				    NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP);
   6187 			}
   6188 			if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) {
   6189 				statsp->bmac_stats.rx_len_err_cnt +=
   6190 				    MAC_LEN_ER_CNT_MASK;
   6191 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
   6192 				    NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP);
   6193 			}
   6194 			if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP)
   6195 				statsp->bmac_stats.rx_viol_err_cnt +=
   6196 				    BMAC_CD_VIO_CNT_MASK;
   6197 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
   6198 				    NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP);
   6199 			}
   6200 			if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) {
   6201 				statsp->bmac_stats.rx_byte_cnt +=
   6202 				    BRXMAC_BYTE_CNT_MASK;
   6203 			}
   6204 			if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) {
   6205 				statsp->bmac_stats.rx_align_err_cnt +=
   6206 				    BMAC_AL_ER_CNT_MASK;
   6207 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
   6208 				    NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP);
   6209 			}
   6210 
   6211 			rs = npi_bmac_ctl_get_istatus(handle, portn,
   6212 			    (bmac_ctl_iconfig_t *)&status);
   6213 			if (rs != NPI_SUCCESS)
   6214 				goto npi_fail;
   6215 
   6216 			if (status & ICFG_BMAC_CTL_ALL) {
   6217 				if (status & ICFG_BMAC_CTL_RCVPAUSE)
   6218 					statsp->bmac_stats.rx_pause_cnt++;
   6219 				if (status & ICFG_BMAC_CTL_INPAUSE_ST)
   6220 					statsp->bmac_stats.tx_pause_state++;
   6221 				if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST)
   6222 					statsp->bmac_stats.tx_nopause_state++;
   6223 			}
   6224 		}
   6225 
   6226 	if (ldgp->nldvs == 1) {
   6227 		(void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg,
   6228 		    B_TRUE, ldgp->ldg_timer);
   6229 	}
   6230 
   6231 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
   6232 	return (DDI_INTR_CLAIMED);
   6233 
   6234 npi_fail:
   6235 	NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
   6236 	return (DDI_INTR_UNCLAIMED);
   6237 }
   6238 
   6239 nxge_status_t
   6240 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up)
   6241 {
   6242 	uint8_t		phy_port_addr;
   6243 	nxge_status_t	status = NXGE_OK;
   6244 	boolean_t	rx_sig_ok;
   6245 	boolean_t	pcs_blk_lock;
   6246 	boolean_t	link_align;
   6247 	uint16_t	val1, val2, val3;
   6248 #ifdef	NXGE_DEBUG_SYMBOL_ERR
   6249 	uint16_t	val_debug;
   6250 	uint32_t	val;
   6251 #endif
   6252 
   6253 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
   6254 
   6255 #ifdef	NXGE_DEBUG_SYMBOL_ERR
   6256 	/* Check Device 3 Register Device 3 0xC809 */
   6257 	(void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug);
   6258 	if ((val_debug & ~0x200) != 0) {
   6259 		cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n",
   6260 		    nxgep->mac.portnum, val_debug);
   6261 		(void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18,
   6262 		    &val_debug);
   6263 		cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n",
   6264 		    nxgep->mac.portnum, val_debug);
   6265 	}
   6266 
   6267 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
   6268 	    XPCS_REG_DESCWERR_COUNTER, &val);
   6269 	if (val != 0)
   6270 		cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val);
   6271 
   6272 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
   6273 	    XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
   6274 	if (val != 0)
   6275 		cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val);
   6276 
   6277 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
   6278 	    XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
   6279 	if (val != 0)
   6280 		cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val);
   6281 #endif
   6282 
   6283 	/* Check from BCM8704 if 10G link is up or down */
   6284 
   6285 	/* Check Device 1 Register 0xA bit0 */
   6286 	status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PMA_PMD_DEV_ADDR,
   6287 	    BCM8704_PMD_RECEIVE_SIG_DETECT, &val1);
   6288 	if (status != NXGE_OK)
   6289 		goto fail;
   6290 	rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE);
   6291 
   6292 	/* Check Device 3 Register 0x20 bit0 */
   6293 	if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PCS_DEV_ADDR,
   6294 	    BCM8704_10GBASE_R_PCS_STATUS_REG, &val2)) != NPI_SUCCESS)
   6295 		goto fail;
   6296 	pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE);
   6297 
   6298 	/* Check Device 4 Register 0x18 bit12 */
   6299 	status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
   6300 	    BCM8704_PHYXS_XGXS_LANE_STATUS_REG, &val3);
   6301 	if (status != NXGE_OK)
   6302 		goto fail;
   6303 
   6304 	switch (nxgep->chip_id) {
   6305 	case BCM8704_CHIP_ID:
   6306 		link_align = (val3 == (XGXS_LANE_ALIGN_STATUS |
   6307 		    XGXS_LANE3_SYNC | XGXS_LANE2_SYNC | XGXS_LANE1_SYNC |
   6308 		    XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE;
   6309 		break;
   6310 	case BCM8706_CHIP_ID:
   6311 		link_align = ((val3 & XGXS_LANE_ALIGN_STATUS) &&
   6312 		    (val3 & XGXS_LANE3_SYNC) && (val3 & XGXS_LANE2_SYNC) &&
   6313 		    (val3 & XGXS_LANE1_SYNC) && (val3 & XGXS_LANE0_SYNC)) ?
   6314 		    B_TRUE : B_FALSE;
   6315 		break;
   6316 	default:
   6317 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_check_bcm8704_link:"
   6318 		    "Unknown chip ID [0x%x]", nxgep->chip_id));
   6319 		goto fail;
   6320 	}
   6321 
   6322 #ifdef	NXGE_DEBUG_ALIGN_ERR
   6323 	/* Temp workaround for link down issue */
   6324 	if (pcs_blk_lock == B_FALSE) {
   6325 		if (val2 != 0x4) {
   6326 			pcs_blk_lock = B_TRUE;
   6327 			cmn_err(CE_NOTE, "!LINK DEBUG: port%d PHY Dev3 "
   6328 			    "Reg 0x20 = 0x%x\n", nxgep->mac.portnum, val2);
   6329 		}
   6330 	}
   6331 
   6332 	if (link_align == B_FALSE) {
   6333 		if (val3 != 0x140f) {
   6334 			link_align = B_TRUE;
   6335 			cmn_err(CE_NOTE, "!LINK DEBUG: port%d PHY Dev4 "
   6336 			    "Reg 0x18 = 0x%x\n", nxgep->mac.portnum, val3);
   6337 		}
   6338 	}
   6339 
   6340 	if (rx_sig_ok == B_FALSE) {
   6341 		if ((val2 == 0) || (val3 == 0)) {
   6342 			rx_sig_ok = B_TRUE;
   6343 			cmn_err(CE_NOTE,
   6344 			    "!LINK DEBUG: port %d Dev3 or Dev4 read zero\n",
   6345 			    nxgep->mac.portnum);
   6346 		}
   6347 	}
   6348 #endif
   6349 
   6350 	*link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) &&
   6351 	    (link_align == B_TRUE)) ? B_TRUE : B_FALSE;
   6352 
   6353 	return (NXGE_OK);
   6354 fail:
   6355 	return (status);
   6356 }
   6357 
   6358 static nxge_status_t
   6359 nxge_check_mrvl88x2011_link(p_nxge_t nxgep, boolean_t *link_up)
   6360 {
   6361 	uint8_t		phy;
   6362 	nxge_status_t   status = NXGE_OK;
   6363 	boolean_t	pma_status;
   6364 	boolean_t	pcs_status;
   6365 	boolean_t	xgxs_status;
   6366 	uint16_t	val;
   6367 
   6368 	phy = nxgep->statsp->mac_stats.xcvr_portn;
   6369 
   6370 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR,
   6371 	    MRVL_88X2011_10G_PMD_STAT_2, &val);
   6372 
   6373 	*link_up = B_FALSE;
   6374 
   6375 	/* Check from Marvell 88X2011 if 10G link is up or down */
   6376 
   6377 	/* Check PMA/PMD Register: 1.0001.2 == 1 */
   6378 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV1_ADDR,
   6379 	    MRVL_88X2011_PMA_PMD_STAT_1, &val);
   6380 
   6381 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6382 	    "nxge_check_mrvl88x2011_link: pmd=0x%x", val));
   6383 
   6384 	pma_status = ((val & MRVL_88X2011_LNK_STATUS_OK) ? B_TRUE : B_FALSE);
   6385 
   6386 	/* Check PMC Register : 3.0001.2 == 1: read twice */
   6387 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
   6388 	    MRVL_88X2011_PMA_PMD_STAT_1, &val);
   6389 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV3_ADDR,
   6390 	    MRVL_88X2011_PMA_PMD_STAT_1, &val);
   6391 
   6392 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6393 	    "nxge_check_mrvl88x2011_link: pcs=0x%x", val));
   6394 
   6395 	pcs_status = ((val & MRVL_88X2011_LNK_STATUS_OK) ? B_TRUE : B_FALSE);
   6396 
   6397 	/* Check XGXS Register : 4.0018.[0-3,12] */
   6398 	MRVL88X2011_RD(nxgep, phy, MRVL_88X2011_USER_DEV4_ADDR,
   6399 	    MRVL_88X2011_10G_XGXS_LANE_STAT, &val);
   6400 
   6401 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6402 	    "nxge_check_mrvl88x2011_link: xgxs=0x%x", val));
   6403 
   6404 	xgxs_status = (val == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC |
   6405 	    XGXS_LANE2_SYNC | XGXS_LANE1_SYNC |
   6406 	    XGXS_LANE0_SYNC | XGXS_PATTERN_TEST_ABILITY |
   6407 	    XGXS_LANE_STAT_MAGIC)) ? B_TRUE : B_FALSE;
   6408 
   6409 	*link_up = (pma_status && pcs_status && xgxs_status) ?
   6410 	    B_TRUE : B_FALSE;
   6411 
   6412 fail:
   6413 
   6414 	if (*link_up == B_FALSE) {
   6415 		/* PCS OFF */
   6416 		nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_CTL_OFF);
   6417 	} else {
   6418 		/* PCS Activity */
   6419 		nxge_mrvl88x2011_led(nxgep, MRVL_88X2011_LED_CTL_PCS_ACT);
   6420 	}
   6421 
   6422 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6423 	    " <== nxge_check_mrvl88x2011_link: up=%d", *link_up));
   6424 
   6425 	return (status);
   6426 }
   6427 
   6428 nxge_status_t
   6429 nxge_10g_link_led_on(p_nxge_t nxgep)
   6430 {
   6431 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE)
   6432 	    != NPI_SUCCESS)
   6433 		return (NXGE_ERROR);
   6434 	else
   6435 		return (NXGE_OK);
   6436 }
   6437 
   6438 nxge_status_t
   6439 nxge_10g_link_led_off(p_nxge_t nxgep)
   6440 {
   6441 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE)
   6442 	    != NPI_SUCCESS)
   6443 		return (NXGE_ERROR);
   6444 	else
   6445 		return (NXGE_OK);
   6446 }
   6447 
   6448 static boolean_t
   6449 nxge_is_phy_present(p_nxge_t nxgep, int addr, uint32_t id, uint32_t mask)
   6450 {
   6451 	uint32_t pma_pmd_id = 0;
   6452 	uint32_t pcs_id = 0;
   6453 	uint32_t phy_id = 0;
   6454 
   6455 	pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, addr);
   6456 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6457 	    "nxge_is_phy_present: pma_pmd_id[0x%x]", pma_pmd_id));
   6458 	if ((pma_pmd_id & mask) == (id & mask))
   6459 		goto found_phy;
   6460 	pcs_id = nxge_get_cl45_pcs_id(nxgep, addr);
   6461 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6462 	    "nxge_is_phy_present: pcs_id[0x%x]", pcs_id));
   6463 	if ((pcs_id & mask) == (id & mask))
   6464 		goto found_phy;
   6465 	phy_id = nxge_get_cl22_phy_id(nxgep, addr);
   6466 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6467 	    "nxge_is_phy_present: phy_id[0x%x]", phy_id));
   6468 	if ((phy_id & mask) == (id & mask))
   6469 		goto found_phy;
   6470 
   6471 	return (B_FALSE);
   6472 
   6473 found_phy:
   6474 	return (B_TRUE);
   6475 }
   6476 
   6477 /* Check if the given id read using the given MDIO Clause is supported */
   6478 
   6479 static boolean_t
   6480 nxge_is_supported_phy(uint32_t id, uint8_t type)
   6481 {
   6482 	int		i;
   6483 	boolean_t	found = B_FALSE;
   6484 
   6485 	switch (type) {
   6486 	case CLAUSE_45_TYPE:
   6487 		for (i = 0; i < NUM_CLAUSE_45_IDS; i++) {
   6488 			if (((nxge_supported_cl45_ids[i] & BCM_PHY_ID_MASK) ==
   6489 			    (id & BCM_PHY_ID_MASK)) ||
   6490 			    (TN1010_DEV_ID == (id & TN1010_DEV_ID_MASK))) {
   6491 				found = B_TRUE;
   6492 				break;
   6493 			}
   6494 		}
   6495 		break;
   6496 	case CLAUSE_22_TYPE:
   6497 		for (i = 0; i < NUM_CLAUSE_22_IDS; i++) {
   6498 			if ((nxge_supported_cl22_ids[i] & BCM_PHY_ID_MASK) ==
   6499 			    (id & BCM_PHY_ID_MASK)) {
   6500 				found = B_TRUE;
   6501 				break;
   6502 			}
   6503 		}
   6504 		break;
   6505 	default:
   6506 		break;
   6507 	}
   6508 
   6509 	return (found);
   6510 }
   6511 
   6512 static uint32_t
   6513 nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep, int phy_port)
   6514 {
   6515 	uint16_t	val1 = 0;
   6516 	uint16_t	val2 = 0;
   6517 	uint32_t	pma_pmd_dev_id = 0;
   6518 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
   6519 
   6520 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
   6521 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR,
   6522 	    NXGE_DEV_ID_REG_1, &val1);
   6523 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR,
   6524 	    NXGE_DEV_ID_REG_2, &val2);
   6525 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
   6526 
   6527 	/* Concatenate the Device ID stored in two registers. */
   6528 	pma_pmd_dev_id = val1;
   6529 	pma_pmd_dev_id = (pma_pmd_dev_id << 16);
   6530 	pma_pmd_dev_id |= val2;
   6531 
   6532 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PMA/PMD "
   6533 	    "devid[0x%llx]", phy_port, pma_pmd_dev_id));
   6534 
   6535 	return (pma_pmd_dev_id);
   6536 }
   6537 
   6538 static uint32_t
   6539 nxge_get_cl45_pcs_id(p_nxge_t nxgep, int phy_port)
   6540 {
   6541 	uint16_t	val1 = 0;
   6542 	uint16_t	val2 = 0;
   6543 	uint32_t	pcs_dev_id = 0;
   6544 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
   6545 
   6546 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
   6547 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR,
   6548 	    NXGE_DEV_ID_REG_1, &val1);
   6549 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR,
   6550 	    NXGE_DEV_ID_REG_2, &val2);
   6551 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
   6552 
   6553 	pcs_dev_id = val1;
   6554 	pcs_dev_id = (pcs_dev_id << 16);
   6555 	pcs_dev_id |= val2;
   6556 
   6557 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS "
   6558 	    "devid[0x%llx]", phy_port, pcs_dev_id));
   6559 
   6560 	return (pcs_dev_id);
   6561 }
   6562 
   6563 static uint32_t
   6564 nxge_get_cl22_phy_id(p_nxge_t nxgep, int phy_port)
   6565 {
   6566 	uint16_t	val1 = 0;
   6567 	uint16_t	val2 = 0;
   6568 	uint32_t	phy_id = 0;
   6569 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
   6570 	npi_status_t	npi_status = NPI_SUCCESS;
   6571 
   6572 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
   6573 	npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_1,
   6574 	    &val1);
   6575 	if (npi_status != NPI_SUCCESS) {
   6576 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
   6577 		    "clause 22 read to reg 2 failed!!!"));
   6578 		goto exit;
   6579 	}
   6580 	npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_2,
   6581 	    &val2);
   6582 	if (npi_status != 0) {
   6583 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
   6584 		    "clause 22 read to reg 3 failed!!!"));
   6585 		goto exit;
   6586 	}
   6587 	phy_id = val1;
   6588 	phy_id = (phy_id << 16);
   6589 	phy_id |= val2;
   6590 
   6591 exit:
   6592 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
   6593 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID [0x%llx]",
   6594 	    phy_port, phy_id));
   6595 
   6596 	return (phy_id);
   6597 }
   6598 
   6599 /*
   6600  * Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO
   6601  * read and the PMA/PMD device ID and the PCS device ID using Clause 45 MDIO
   6602  * read. Then use the values obtained to determine the phy type of each port
   6603  * and the Neptune type.
   6604  *
   6605  * This function sets hw_p->xcvr_addr[i] for future MDIO access and set
   6606  * hw_p->niu_type for each nxge instance to figure out nxgep->mac.portmode
   6607  * in case the portmode information is not available via OBP, nxge.conf,
   6608  * VPD or SEEPROM.
   6609  */
   6610 nxge_status_t
   6611 nxge_scan_ports_phy(p_nxge_t nxgep, p_nxge_hw_list_t hw_p)
   6612 {
   6613 	int		i, j, l;
   6614 	uint32_t	pma_pmd_dev_id = 0;
   6615 	uint32_t	pcs_dev_id = 0;
   6616 	uint32_t	phy_id = 0;
   6617 	uint32_t	port_pma_pmd_dev_id[NXGE_PORTS_NEPTUNE];
   6618 	uint32_t	port_pcs_dev_id[NXGE_PORTS_NEPTUNE];
   6619 	uint32_t	port_phy_id[NXGE_PORTS_NEPTUNE];
   6620 	uint8_t		pma_pmd_dev_fd[NXGE_MAX_PHY_PORTS];
   6621 	uint8_t		pcs_dev_fd[NXGE_MAX_PHY_PORTS];
   6622 	uint8_t		phy_fd_arr[NXGE_MAX_PHY_PORTS];
   6623 	uint8_t		port_fd_arr[NXGE_MAX_PHY_PORTS];
   6624 	uint8_t		total_port_fd, total_phy_fd;
   6625 	uint8_t		num_xaui;
   6626 	nxge_status_t	status = NXGE_OK;
   6627 
   6628 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: "));
   6629 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6630 	    "==> nxge_scan_ports_phy: nxge niu_type[0x%x]",
   6631 	    nxgep->niu_type));
   6632 
   6633 	if (isLDOMguest(nxgep)) {
   6634 		hw_p->niu_type = NIU_TYPE_NONE;
   6635 		hw_p->platform_type = P_NEPTUNE_NONE;
   6636 		return (NXGE_OK);
   6637 	}
   6638 
   6639 	j = l = 0;
   6640 	total_port_fd = total_phy_fd = 0;
   6641 	/*
   6642 	 * Clause 45 and Clause 22 port/phy addresses 0 through 5 are reserved
   6643 	 * for on chip serdes usages. "i" in the following for loop starts at 6.
   6644 	 */
   6645 	for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) {
   6646 
   6647 		pma_pmd_dev_id = nxge_get_cl45_pma_pmd_id(nxgep, i);
   6648 
   6649 		if (nxge_is_supported_phy(pma_pmd_dev_id, CLAUSE_45_TYPE)) {
   6650 			pma_pmd_dev_fd[i] = 1;
   6651 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
   6652 			    "PMA/PMD dev %x found", i, pma_pmd_dev_id));
   6653 			if (j < NXGE_PORTS_NEPTUNE) {
   6654 				if ((pma_pmd_dev_id & TN1010_DEV_ID_MASK)
   6655 				    == TN1010_DEV_ID) {
   6656 					port_pma_pmd_dev_id[j] = TN1010_DEV_ID;
   6657 				} else {
   6658 					port_pma_pmd_dev_id[j] =
   6659 					    pma_pmd_dev_id & BCM_PHY_ID_MASK;
   6660 				}
   6661 				port_fd_arr[j] = (uint8_t)i;
   6662 				j++;
   6663 			}
   6664 		} else {
   6665 			pma_pmd_dev_fd[i] = 0;
   6666 		}
   6667 
   6668 		pcs_dev_id = nxge_get_cl45_pcs_id(nxgep, i);
   6669 
   6670 		if (nxge_is_supported_phy(pcs_dev_id, CLAUSE_45_TYPE)) {
   6671 			pcs_dev_fd[i] = 1;
   6672 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS "
   6673 			    "dev %x found", i, pcs_dev_id));
   6674 			if (pma_pmd_dev_fd[i] == 1) {
   6675 				if ((pcs_dev_id & TN1010_DEV_ID_MASK)
   6676 				    == TN1010_DEV_ID) {
   6677 					port_pcs_dev_id[j - 1] =
   6678 					    TN1010_DEV_ID;
   6679 				} else {
   6680 					port_pcs_dev_id[j - 1] =
   6681 					    pcs_dev_id &
   6682 					    BCM_PHY_ID_MASK;
   6683 				}
   6684 			} else {
   6685 				if (j < NXGE_PORTS_NEPTUNE) {
   6686 					if ((pcs_dev_id & TN1010_DEV_ID_MASK)
   6687 					    == TN1010_DEV_ID) {
   6688 						port_pcs_dev_id[j] =
   6689 						    TN1010_DEV_ID;
   6690 					} else {
   6691 						port_pcs_dev_id[j] =
   6692 						    pcs_dev_id &
   6693 						    BCM_PHY_ID_MASK;
   6694 					}
   6695 					port_fd_arr[j] = (uint8_t)i;
   6696 					j++;
   6697 				}
   6698 			}
   6699 		} else {
   6700 			pcs_dev_fd[i] = 0;
   6701 		}
   6702 
   6703 		if (pcs_dev_fd[i] || pma_pmd_dev_fd[i]) {
   6704 			total_port_fd ++;
   6705 		}
   6706 
   6707 		phy_id = nxge_get_cl22_phy_id(nxgep, i);
   6708 		if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) {
   6709 			total_phy_fd ++;
   6710 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID"
   6711 			    "%x found", i, phy_id));
   6712 			if (l < NXGE_PORTS_NEPTUNE) {
   6713 				if ((phy_id & TN1010_DEV_ID_MASK)
   6714 				    == TN1010_DEV_ID) {
   6715 					port_phy_id[l] = TN1010_DEV_ID;
   6716 				} else {
   6717 					port_phy_id[l]
   6718 					    = phy_id & BCM_PHY_ID_MASK;
   6719 				}
   6720 				phy_fd_arr[l] = (uint8_t)i;
   6721 				l++;
   6722 			}
   6723 		}
   6724 	}
   6725 
   6726 	switch (total_port_fd) {
   6727 	case 2:
   6728 		switch (total_phy_fd) {
   6729 		case 2:
   6730 			/* 2 10G, 2 1G RGMII Fiber / copper */
   6731 			if ((((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) &&
   6732 			    (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) ||
   6733 			    ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) &&
   6734 			    (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) &&
   6735 			    ((port_phy_id[0] == PHY_BCM5482_FAMILY) &&
   6736 			    (port_phy_id[1] == PHY_BCM5482_FAMILY))) {
   6737 
   6738 				switch (hw_p->platform_type) {
   6739 				case P_NEPTUNE_ROCK:
   6740 					hw_p->niu_type = NEPTUNE_2_10GF_2_1GC;
   6741 					/*
   6742 					 * ROCK platform has assigned a lower
   6743 					 * addr to port 1. (port 0 = 0x9 and
   6744 					 * port 1 = 0x8).
   6745 					 */
   6746 					hw_p->xcvr_addr[1] = port_fd_arr[0];
   6747 					hw_p->xcvr_addr[0] = port_fd_arr[1];
   6748 
   6749 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6750 					    "Rock with 2 10G, 2 1GC"));
   6751 					break;
   6752 
   6753 				case P_NEPTUNE_NONE:
   6754 				default:
   6755 					hw_p->platform_type =
   6756 					    P_NEPTUNE_GENERIC;
   6757 					hw_p->niu_type = NEPTUNE_2_10GF_2_1GRF;
   6758 
   6759 					hw_p->xcvr_addr[0] = port_fd_arr[0];
   6760 					hw_p->xcvr_addr[1] = port_fd_arr[1];
   6761 
   6762 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6763 					    "ARTM card with 2 10G, 2 1GF"));
   6764 					break;
   6765 				}
   6766 
   6767 				hw_p->xcvr_addr[2] = phy_fd_arr[0];
   6768 				hw_p->xcvr_addr[3] = phy_fd_arr[1];
   6769 
   6770 			} else {
   6771 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   6772 				    "Unsupported neptune type 1"));
   6773 				goto error_exit;
   6774 			}
   6775 			break;
   6776 
   6777 		case 1:
   6778 			/* TODO - 2 10G, 1 1G */
   6779 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6780 			    "Unsupported neptune type 2 10G, 1 1G"));
   6781 			goto error_exit;
   6782 		case 0:
   6783 			/*
   6784 			 * 2 10G: 2XGF NIC, Marvell, Goa, Huron with 2 XAUI
   6785 			 * cards, etc.
   6786 			 */
   6787 			if (((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) &&
   6788 			    (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) ||
   6789 			    ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) &&
   6790 			    (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY)) ||
   6791 			    ((port_pcs_dev_id[0] == MARVELL_88X201X_PHY_ID) &&
   6792 			    (port_pcs_dev_id[1] == MARVELL_88X201X_PHY_ID)) ||
   6793 			    ((port_pma_pmd_dev_id[0] ==
   6794 			    MARVELL_88X201X_PHY_ID) &&
   6795 			    (port_pma_pmd_dev_id[1] ==
   6796 			    MARVELL_88X201X_PHY_ID))) {
   6797 
   6798 				/*
   6799 				 * Check the first phy port address against
   6800 				 * the known phy start addresses to determine
   6801 				 * the platform type.
   6802 				 */
   6803 
   6804 				switch (port_fd_arr[0]) {
   6805 				case NEPTUNE_CLAUSE45_PORT_ADDR_BASE:
   6806 					/*
   6807 					 * The Marvell case also falls into
   6808 					 * this case as
   6809 					 * MRVL88X2011_NEPTUNE_PORT_ADDR_BASE
   6810 					 * == NEPTUNE_CLAUSE45_PORT_ADDR_BASE.
   6811 					 * This is OK for the 2 10G case.
   6812 					 */
   6813 					hw_p->niu_type = NEPTUNE_2_10GF;
   6814 					hw_p->platform_type =
   6815 					    P_NEPTUNE_ATLAS_2PORT;
   6816 					break;
   6817 				case GOA_CLAUSE45_PORT_ADDR_BASE:
   6818 					if (hw_p->platform_type !=
   6819 					    P_NEPTUNE_NIU) {
   6820 						hw_p->platform_type =
   6821 						    P_NEPTUNE_GENERIC;
   6822 						hw_p->niu_type =
   6823 						    NEPTUNE_2_10GF;
   6824 					}
   6825 					break;
   6826 				default:
   6827 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   6828 					    "Unsupported neptune type 2 - 1"));
   6829 					goto error_exit;
   6830 				}
   6831 
   6832 				for (i = 0; i < 2; i++) {
   6833 					hw_p->xcvr_addr[i] = port_fd_arr[i];
   6834 				}
   6835 
   6836 			/* Both XAUI slots have copper XAUI cards */
   6837 			} else if ((((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
   6838 			    == TN1010_DEV_ID) &&
   6839 			    ((port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
   6840 			    == TN1010_DEV_ID)) ||
   6841 			    (((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
   6842 			    == TN1010_DEV_ID) &&
   6843 			    ((port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK)
   6844 			    == TN1010_DEV_ID))) {
   6845 				hw_p->niu_type = NEPTUNE_2_TN1010;
   6846 				hw_p->xcvr_addr[0] = port_fd_arr[0];
   6847 				hw_p->xcvr_addr[1] = port_fd_arr[1];
   6848 
   6849 			/* Slot0 has fiber XAUI, slot1 has copper XAUI */
   6850 			} else if ((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
   6851 			    (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
   6852 			    == TN1010_DEV_ID) ||
   6853 			    (port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY &&
   6854 			    (port_pma_pmd_dev_id[1] & TN1010_DEV_ID_MASK) ==
   6855 			    TN1010_DEV_ID)) {
   6856 				hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010;
   6857 				hw_p->xcvr_addr[0] = port_fd_arr[0];
   6858 				hw_p->xcvr_addr[1] = port_fd_arr[1];
   6859 
   6860 			/* Slot0 has copper XAUI, slot1 has fiber XAUI */
   6861 			} else if ((port_pcs_dev_id[1] == PHY_BCM8704_FAMILY &&
   6862 			    (port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
   6863 			    == TN1010_DEV_ID) ||
   6864 			    (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY &&
   6865 			    (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
   6866 			    == TN1010_DEV_ID)) {
   6867 				hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF;
   6868 				hw_p->xcvr_addr[0] = port_fd_arr[0];
   6869 				hw_p->xcvr_addr[1] = port_fd_arr[1];
   6870 
   6871 			} else {
   6872 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6873 				    "Unsupported neptune type 2"));
   6874 				goto error_exit;
   6875 			}
   6876 			break;
   6877 
   6878 		case 4:
   6879 			if (nxge_get_num_of_xaui(
   6880 			    port_pma_pmd_dev_id, port_pcs_dev_id,
   6881 			    port_phy_id, &num_xaui) == NXGE_ERROR) {
   6882 				goto error_exit;
   6883 			}
   6884 			if (num_xaui != 2)
   6885 				goto error_exit;
   6886 
   6887 			/*
   6888 			 *  Maramba with 2 XAUIs (either fiber or copper)
   6889 			 *
   6890 			 * Check the first phy port address against
   6891 			 * the known phy start addresses to determine
   6892 			 * the platform type.
   6893 			 */
   6894 			switch (phy_fd_arr[0]) {
   6895 			case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE:
   6896 				hw_p->platform_type =
   6897 				    P_NEPTUNE_MARAMBA_P0;
   6898 				break;
   6899 			case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
   6900 				hw_p->platform_type =
   6901 				    P_NEPTUNE_MARAMBA_P1;
   6902 				break;
   6903 			default:
   6904 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   6905 				    "Unknown port %d...Cannot "
   6906 				    "determine platform type", i));
   6907 				goto error_exit;
   6908 			}
   6909 
   6910 			hw_p->xcvr_addr[0] = port_fd_arr[0];
   6911 			hw_p->xcvr_addr[1] = port_fd_arr[1];
   6912 			hw_p->xcvr_addr[2] = phy_fd_arr[2];
   6913 			hw_p->xcvr_addr[3] = phy_fd_arr[3];
   6914 
   6915 			/* slot0 has fiber XAUI, slot1 has Cu XAUI */
   6916 			if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
   6917 			    (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
   6918 			    == TN1010_DEV_ID) {
   6919 				hw_p->niu_type = NEPTUNE_1_10GF_1_TN1010_2_1GC;
   6920 
   6921 			/* slot0 has Cu XAUI, slot1 has fiber XAUI */
   6922 			} else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
   6923 			    == TN1010_DEV_ID) &&
   6924 			    port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) {
   6925 				hw_p->niu_type = NEPTUNE_1_TN1010_1_10GF_2_1GC;
   6926 
   6927 			/* Both slots have fiber XAUI */
   6928 			} else if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY &&
   6929 			    port_pcs_dev_id[1] == PHY_BCM8704_FAMILY) {
   6930 				hw_p->niu_type = NEPTUNE_2_10GF_2_1GC;
   6931 
   6932 			/* Both slots have copper XAUI */
   6933 			} else if (((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
   6934 			    == TN1010_DEV_ID) &&
   6935 			    (port_pcs_dev_id[1] & TN1010_DEV_ID_MASK)
   6936 			    == TN1010_DEV_ID) {
   6937 				hw_p->niu_type = NEPTUNE_2_TN1010_2_1GC;
   6938 
   6939 			} else {
   6940 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6941 				    "Unsupported neptune type 3"));
   6942 				goto error_exit;
   6943 			}
   6944 			break;
   6945 		default:
   6946 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6947 			    "Unsupported neptune type 5"));
   6948 			goto error_exit;
   6949 		}
   6950 		break;
   6951 	case 1: 	/* Only one clause45 port */
   6952 		switch (total_phy_fd) {	/* Number of clause22 ports */
   6953 		case 3:
   6954 			/*
   6955 			 * TODO 3 1G, 1 10G mode.
   6956 			 * Differentiate between 1_1G_1_10G_2_1G and
   6957 			 * 1_10G_3_1G
   6958 			 */
   6959 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6960 			    "Unsupported neptune type 7"));
   6961 			goto error_exit;
   6962 		case 2:
   6963 			/*
   6964 			 * TODO 2 1G, 1 10G mode.
   6965 			 * Differentiate between 1_1G_1_10G_1_1G and
   6966 			 * 1_10G_2_1G
   6967 			 */
   6968 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6969 			    "Unsupported neptune type 8"));
   6970 			goto error_exit;
   6971 		case 1:
   6972 			/*
   6973 			 * TODO 1 1G, 1 10G mode.
   6974 			 * Differentiate between 1_1G_1_10G and
   6975 			 * 1_10G_1_1G
   6976 			 */
   6977 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   6978 			    "Unsupported neptune type 9"));
   6979 			goto error_exit;
   6980 		case 0:	/* N2 with 1 XAUI (fiber or copper) */
   6981 			/* Fiber XAUI */
   6982 			if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY ||
   6983 			    port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) {
   6984 
   6985 				/*
   6986 				 * Check the first phy port address against
   6987 				 * the known phy start addresses to determine
   6988 				 * the platform type.
   6989 				 */
   6990 
   6991 				switch (port_fd_arr[0]) {
   6992 				case N2_CLAUSE45_PORT_ADDR_BASE:
   6993 				case (N2_CLAUSE45_PORT_ADDR_BASE + 1):
   6994 				case ALT_GOA_CLAUSE45_PORT1_ADDR:
   6995 					/*
   6996 					 * If hw_p->platform_type ==
   6997 					 * P_NEPTUNE_NIU, then portmode
   6998 					 * is already known, so there is
   6999 					 * no need to figure out hw_p->
   7000 					 * platform_type because
   7001 					 * platform_type is only for
   7002 					 * figuring out portmode.
   7003 					 */
   7004 					if (hw_p->platform_type !=
   7005 					    P_NEPTUNE_NIU) {
   7006 						hw_p->platform_type =
   7007 						    P_NEPTUNE_GENERIC;
   7008 						hw_p->niu_type =
   7009 						    NEPTUNE_2_10GF;
   7010 					}
   7011 					break;
   7012 				default:
   7013 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   7014 					    "Unsupported neptune type 10"));
   7015 					goto error_exit;
   7016 				}
   7017 				/*
   7018 				 * For GOA, which is a hot swappable PHY, the
   7019 				 * phy address to function number mapping
   7020 				 * should be preserved, i.e., addr 16 is
   7021 				 * assigned to function 0 and 20 to function 1
   7022 				 * But for Huron XAUI, the assignment should
   7023 				 * be by function number, i.e., whichever
   7024 				 * function number attaches should be
   7025 				 * assigned the available PHY (this is required
   7026 				 * primarily to support pre-production Huron
   7027 				 * boards where function 0 is mapped to addr 17
   7028 				 */
   7029 				if (port_fd_arr[0] ==
   7030 				    ALT_GOA_CLAUSE45_PORT1_ADDR) {
   7031 					hw_p->xcvr_addr[1] = port_fd_arr[0];
   7032 				} else {
   7033 					hw_p->xcvr_addr[nxgep->function_num] =
   7034 					    port_fd_arr[0];
   7035 				}
   7036 
   7037 			/* A 10G copper XAUI in either slot0 or slot1 */
   7038 			} else if ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
   7039 			    == TN1010_DEV_ID ||
   7040 			    (port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
   7041 			    == TN1010_DEV_ID) {
   7042 				switch (port_fd_arr[0]) {
   7043 				/* The XAUI is in slot0 */
   7044 				case N2_CLAUSE45_PORT_ADDR_BASE:
   7045 					hw_p->niu_type = NEPTUNE_1_TN1010;
   7046 					break;
   7047 
   7048 				/* The XAUI is in slot1 */
   7049 				case (N2_CLAUSE45_PORT_ADDR_BASE + 1):
   7050 					hw_p->niu_type
   7051 					    = NEPTUNE_1_NONE_1_TN1010;
   7052 					break;
   7053 				default:
   7054 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   7055 					    "Unsupported XAUI port address"));
   7056 					goto error_exit;
   7057 				}
   7058 				hw_p->xcvr_addr[nxgep->function_num]
   7059 				    = port_fd_arr[0];
   7060 
   7061 			} else {
   7062 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   7063 				    "Unsupported PHY type"));
   7064 				goto error_exit;
   7065 			}
   7066 			break;
   7067 		case 4: /* Maramba always have 4 clause 45 ports */
   7068 
   7069 			/* Maramba with 1 XAUI */
   7070 			if ((port_pcs_dev_id[0] != PHY_BCM8704_FAMILY) &&
   7071 			    (port_pma_pmd_dev_id[0] != PHY_BCM8704_FAMILY) &&
   7072 			    ((port_pcs_dev_id[0] & TN1010_DEV_ID_MASK)
   7073 			    != TN1010_DEV_ID) &&
   7074 			    ((port_pma_pmd_dev_id[0] & TN1010_DEV_ID_MASK)
   7075 			    != TN1010_DEV_ID)) {
   7076 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   7077 				    "Unsupported neptune type 12"));
   7078 				goto error_exit;
   7079 			}
   7080 
   7081 			/*
   7082 			 * Check the first phy port address against
   7083 			 * the known phy start addresses to determine
   7084 			 * the platform type.
   7085 			 */
   7086 			switch (phy_fd_arr[0]) {
   7087 			case MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE:
   7088 				hw_p->platform_type =
   7089 				    P_NEPTUNE_MARAMBA_P0;
   7090 				break;
   7091 			case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
   7092 				hw_p->platform_type =
   7093 				    P_NEPTUNE_MARAMBA_P1;
   7094 				break;
   7095 			default:
   7096 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   7097 				    "Unknown port %d...Cannot "
   7098 				    "determine platform type 10 - 2",
   7099 				    i));
   7100 				goto error_exit;
   7101 			}
   7102 
   7103 			/*
   7104 			 * Check the clause45 address to determine
   7105 			 * if XAUI is in port 0 or port 1.
   7106 			 */
   7107 			switch (port_fd_arr[0]) {
   7108 			case MARAMBA_CLAUSE45_PORT_ADDR_BASE:
   7109 				if (port_pcs_dev_id[0]
   7110 				    == PHY_BCM8704_FAMILY ||
   7111 				    port_pma_pmd_dev_id[0]
   7112 				    == PHY_BCM8704_FAMILY) {
   7113 					hw_p->niu_type
   7114 					    = NEPTUNE_1_10GF_3_1GC;
   7115 				} else {
   7116 					hw_p->niu_type
   7117 					    = NEPTUNE_1_TN1010_3_1GC;
   7118 				}
   7119 				hw_p->xcvr_addr[0] = port_fd_arr[0];
   7120 				for (i = 1; i < NXGE_MAX_PORTS; i++) {
   7121 					hw_p->xcvr_addr[i] =
   7122 					    phy_fd_arr[i];
   7123 				}
   7124 				break;
   7125 			case (MARAMBA_CLAUSE45_PORT_ADDR_BASE + 1):
   7126 				if (port_pcs_dev_id[0]
   7127 				    == PHY_BCM8704_FAMILY ||
   7128 				    port_pma_pmd_dev_id[0]
   7129 				    == PHY_BCM8704_FAMILY) {
   7130 					hw_p->niu_type =
   7131 					    NEPTUNE_1_1GC_1_10GF_2_1GC;
   7132 				} else {
   7133 					hw_p->niu_type =
   7134 					    NEPTUNE_1_1GC_1_TN1010_2_1GC;
   7135 				}
   7136 				hw_p->xcvr_addr[0] = phy_fd_arr[0];
   7137 				hw_p->xcvr_addr[1] = port_fd_arr[0];
   7138 				hw_p->xcvr_addr[2] = phy_fd_arr[2];
   7139 				hw_p->xcvr_addr[3] = phy_fd_arr[3];
   7140 				break;
   7141 			default:
   7142 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   7143 				    "Unsupported neptune type 11"));
   7144 				goto error_exit;
   7145 			}
   7146 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   7147 			    "Maramba with 1 XAUI (fiber or copper)"));
   7148 			break;
   7149 		default:
   7150 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   7151 			    "Unsupported neptune type 13"));
   7152 			goto error_exit;
   7153 		}
   7154 		break;
   7155 	case 0: /* 4 ports Neptune based NIC */
   7156 		switch (total_phy_fd) {
   7157 		case 4:
   7158 			if ((port_phy_id[0] == PHY_BCM5464R_FAMILY) &&
   7159 			    (port_phy_id[1] == PHY_BCM5464R_FAMILY) &&
   7160 			    (port_phy_id[2] == PHY_BCM5464R_FAMILY) &&
   7161 			    (port_phy_id[3] == PHY_BCM5464R_FAMILY)) {
   7162 
   7163 				/*
   7164 				 * Check the first phy port address against
   7165 				 * the known phy start addresses to determine
   7166 				 * the platform type.
   7167 				 */
   7168 				switch (phy_fd_arr[0]) {
   7169 				case MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE:
   7170 					hw_p->platform_type =
   7171 					    P_NEPTUNE_MARAMBA_P1;
   7172 					break;
   7173 				case NEPTUNE_CLAUSE22_PORT_ADDR_BASE:
   7174 					hw_p->platform_type =
   7175 					    P_NEPTUNE_ATLAS_4PORT;
   7176 					break;
   7177 				default:
   7178 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   7179 					    "Unknown port %d...Cannot "
   7180 					    "determine platform type", i));
   7181 					goto error_exit;
   7182 				}
   7183 				hw_p->niu_type = NEPTUNE_4_1GC;
   7184 				for (i = 0; i < NXGE_MAX_PORTS; i++) {
   7185 					hw_p->xcvr_addr[i] = phy_fd_arr[i];
   7186 				}
   7187 			} else {
   7188 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   7189 				    "Unsupported neptune type 14"));
   7190 				goto error_exit;
   7191 			}
   7192 			break;
   7193 		case 3:
   7194 			/* TODO 3 1G mode */
   7195 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   7196 			    "Unsupported neptune type 15"));
   7197 			goto error_exit;
   7198 		case 2:
   7199 			/* TODO 2 1G mode */
   7200 			if ((port_phy_id[0] == PHY_BCM5482_FAMILY) &&
   7201 			    (port_phy_id[1] == PHY_BCM5482_FAMILY)) {
   7202 				hw_p->platform_type = P_NEPTUNE_GENERIC;
   7203 				hw_p->niu_type = NEPTUNE_2_1GRF;
   7204 				hw_p->xcvr_addr[2] = phy_fd_arr[0];
   7205 				hw_p->xcvr_addr[3] = phy_fd_arr[1];
   7206 			} else {
   7207 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   7208 				    "Unsupported neptune type 16"));
   7209 				goto error_exit;
   7210 			}
   7211 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   7212 			    "2 RGMII Fiber ports - RTM"));
   7213 			break;
   7214 
   7215 		case 1:
   7216 			/* TODO 1 1G mode */
   7217 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   7218 			    "Unsupported neptune type 17"));
   7219 			goto error_exit;
   7220 		default:
   7221 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   7222 			    "Unsupported neptune type 18, total phy fd %d",
   7223 			    total_phy_fd));
   7224 			goto error_exit;
   7225 		}
   7226 		break;
   7227 	default:
   7228 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
   7229 		    "Unsupported neptune type 19"));
   7230 		goto error_exit;
   7231 	}
   7232 
   7233 scan_exit:
   7234 
   7235 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, "
   7236 	    "niu type [0x%x]\n", hw_p->niu_type));
   7237 	return (status);
   7238 
   7239 error_exit:
   7240 	return (NXGE_ERROR);
   7241 }
   7242 
   7243 boolean_t
   7244 nxge_is_valid_local_mac(ether_addr_st mac_addr)
   7245 {
   7246 	if ((mac_addr.ether_addr_octet[0] & 0x01) ||
   7247 	    (ether_cmp(&mac_addr, &etherbroadcastaddr) == 0) ||
   7248 	    (ether_cmp(&mac_addr, &etherzeroaddr) == 0))
   7249 		return (B_FALSE);
   7250 	else
   7251 		return (B_TRUE);
   7252 }
   7253 
   7254 static void
   7255 nxge_bcm5464_link_led_off(p_nxge_t nxgep) {
   7256 
   7257 	npi_status_t rs = NPI_SUCCESS;
   7258 	uint8_t xcvr_portn;
   7259 	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
   7260 
   7261 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_bcm5464_link_led_off"));
   7262 
   7263 	if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P1) {
   7264 		xcvr_portn = MARAMBA_P1_CLAUSE22_PORT_ADDR_BASE;
   7265 	} else if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P0) {
   7266 		xcvr_portn = MARAMBA_P0_CLAUSE22_PORT_ADDR_BASE;
   7267 	}
   7268 	/*
   7269 	 * For Altas 4-1G copper, Xcvr port numbers are
   7270 	 * swapped with ethernet port number. This is
   7271 	 * designed for better signal integrity in routing.
   7272 	 */
   7273 	switch (portn) {
   7274 	case 0:
   7275 		xcvr_portn += 3;
   7276 		break;
   7277 	case 1:
   7278 		xcvr_portn += 2;
   7279 		break;
   7280 	case 2:
   7281 		xcvr_portn += 1;
   7282 		break;
   7283 	case 3:
   7284 	default:
   7285 		break;
   7286 	}
   7287 
   7288 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
   7289 	rs = npi_mac_mif_mii_write(nxgep->npi_handle,
   7290 	    xcvr_portn, BCM5464R_MISC, 0xb4ee);
   7291 	if (rs != NPI_SUCCESS) {
   7292 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   7293 		    "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
   7294 		    "returned error 0x[%x]", rs));
   7295 		MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
   7296 		return;
   7297 	}
   7298 
   7299 	rs = npi_mac_mif_mii_write(nxgep->npi_handle,
   7300 	    xcvr_portn, BCM5464R_MISC, 0xb8ee);
   7301 	if (rs != NPI_SUCCESS) {
   7302 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
   7303 		    "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
   7304 		    "returned error 0x[%x]", rs));
   7305 	}
   7306 
   7307 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
   7308 }
   7309 
   7310 static nxge_status_t
   7311 nxge_mii_get_link_mode(p_nxge_t nxgep)
   7312 {
   7313