xref: /titanic_51/usr/src/uts/common/io/nxge/nxge_mac.c (revision 7b209c2cc5ea45251aba06dcc6181d3f23da807a)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/nxge/nxge_impl.h>
29 #include <sys/nxge/nxge_mac.h>
30 
31 #define	LINK_MONITOR_PERIOD	(1000 * 1000)
32 #define	LM_WAIT_MULTIPLIER	8
33 
34 extern uint32_t nxge_no_link_notify;
35 extern boolean_t nxge_no_msg;
36 extern uint32_t nxge_lb_dbg;
37 extern boolean_t nxge_jumbo_enable;
38 extern uint32_t nxge_jumbo_mtu;
39 
40 typedef enum {
41 	CHECK_LINK_RESCHEDULE,
42 	CHECK_LINK_STOP
43 } check_link_state_t;
44 
45 static check_link_state_t nxge_check_link_stop(nxge_t *);
46 
47 /*
48  * Ethernet broadcast address definition.
49  */
50 static ether_addr_st etherbroadcastaddr =
51 				{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
52 /*
53  * Ethernet zero address definition.
54  */
55 static ether_addr_st etherzeroaddr =
56 				{{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
57 /*
58  * Supported chip types
59  */
60 static uint32_t nxge_supported_cl45_ids[] = {BCM8704_DEV_ID, BCM8706_DEV_ID};
61 static uint32_t nxge_supported_cl22_ids[] = {BCM5464R_PHY_ID};
62 
63 #define	NUM_CLAUSE_45_IDS	(sizeof (nxge_supported_cl45_ids) /	\
64 				sizeof (uint32_t))
65 #define	NUM_CLAUSE_22_IDS	(sizeof (nxge_supported_cl22_ids) /	\
66 				sizeof (uint32_t))
67 /*
68  * static functions
69  */
70 static uint32_t nxge_get_cl45_pma_pmd_id(p_nxge_t, int);
71 static uint32_t nxge_get_cl45_pcs_id(p_nxge_t, int);
72 static uint32_t nxge_get_cl22_phy_id(p_nxge_t, int);
73 static boolean_t nxge_is_supported_phy(uint32_t, uint8_t);
74 static boolean_t nxge_is_phy_present(p_nxge_t, int, uint32_t, uint32_t);
75 static nxge_status_t nxge_n2_serdes_init(p_nxge_t);
76 static nxge_status_t nxge_neptune_10G_serdes_init(p_nxge_t);
77 static nxge_status_t nxge_1G_serdes_init(p_nxge_t);
78 static nxge_status_t nxge_10G_link_intr_stop(p_nxge_t);
79 static nxge_status_t nxge_10G_link_intr_start(p_nxge_t);
80 static nxge_status_t nxge_1G_copper_link_intr_stop(p_nxge_t);
81 static nxge_status_t nxge_1G_copper_link_intr_start(p_nxge_t);
82 static nxge_status_t nxge_1G_fiber_link_intr_stop(p_nxge_t);
83 static nxge_status_t nxge_1G_fiber_link_intr_start(p_nxge_t);
84 static nxge_status_t nxge_check_mii_link(p_nxge_t);
85 static nxge_status_t nxge_check_10g_link(p_nxge_t);
86 static nxge_status_t nxge_10G_xcvr_init(p_nxge_t);
87 static nxge_status_t nxge_BCM8704_xcvr_init(p_nxge_t);
88 static nxge_status_t nxge_BCM8706_xcvr_init(p_nxge_t);
89 static nxge_status_t nxge_1G_xcvr_init(p_nxge_t);
90 static void nxge_bcm5464_link_led_off(p_nxge_t);
91 
92 /*
93  * xcvr tables for supported transceivers
94  */
95 
96 static nxge_xcvr_table_t nxge_n2_10G_table = {
97 	nxge_n2_serdes_init,
98 	nxge_10G_xcvr_init,
99 	nxge_10G_link_intr_stop,
100 	nxge_10G_link_intr_start,
101 	nxge_check_10g_link,
102 	PCS_XCVR
103 };
104 
105 static nxge_xcvr_table_t nxge_n2_1G_table = {
106 	nxge_n2_serdes_init,
107 	nxge_1G_xcvr_init,
108 	nxge_1G_fiber_link_intr_stop,
109 	nxge_1G_fiber_link_intr_start,
110 	nxge_check_mii_link,
111 	PCS_XCVR
112 };
113 
114 static nxge_xcvr_table_t nxge_10G_fiber_table = {
115 	nxge_neptune_10G_serdes_init,
116 	nxge_10G_xcvr_init,
117 	nxge_10G_link_intr_stop,
118 	nxge_10G_link_intr_start,
119 	nxge_check_10g_link,
120 	PCS_XCVR
121 };
122 
123 static nxge_xcvr_table_t nxge_1G_copper_table = {
124 	NULL,
125 	nxge_1G_xcvr_init,
126 	nxge_1G_copper_link_intr_stop,
127 	nxge_1G_copper_link_intr_start,
128 	nxge_check_mii_link,
129 	INT_MII_XCVR
130 };
131 
132 static nxge_xcvr_table_t nxge_1G_fiber_table = {
133 	nxge_1G_serdes_init,
134 	nxge_1G_xcvr_init,
135 	nxge_1G_fiber_link_intr_stop,
136 	nxge_1G_fiber_link_intr_start,
137 	nxge_check_mii_link,
138 	PCS_XCVR
139 };
140 
141 static nxge_xcvr_table_t nxge_10G_copper_table = {
142 	nxge_neptune_10G_serdes_init,
143 	NULL,
144 	NULL,
145 	NULL,
146 	NULL,
147 	PCS_XCVR
148 };
149 
150 nxge_status_t nxge_mac_init(p_nxge_t);
151 
152 #ifdef NXGE_DEBUG
153 static void nxge_mii_dump(p_nxge_t);
154 #endif
155 static nxge_status_t nxge_mii_get_link_mode(p_nxge_t);
156 
157 nxge_status_t
158 nxge_get_xcvr_type(p_nxge_t nxgep)
159 {
160 	nxge_status_t status = NXGE_OK;
161 	char *phy_type;
162 	char *prop_val;
163 
164 	nxgep->mac.portmode = 0;
165 	nxgep->xcvr_addr = 0;
166 
167 	/*
168 	 * First check for hot swappable phy property.
169 	 */
170 	if (nxgep->hot_swappable_phy == B_TRUE) {
171 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
172 		nxgep->mac.portmode = PORT_HSP_MODE;
173 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Other: Hot Swappable"));
174 	} else if (ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip,
175 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
176 	    "hot-swappable-phy") == 1) {
177 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
178 		nxgep->mac.portmode = PORT_HSP_MODE;
179 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, ".conf: Hot Swappable"));
180 	} else if (nxgep->niu_type == N2_NIU &&
181 	    ddi_prop_exists(DDI_DEV_T_ANY, nxgep->dip, 0,
182 	    "hot-swappable-phy") == 1) {
183 		nxgep->statsp->mac_stats.xcvr_inuse = HSP_XCVR;
184 		nxgep->mac.portmode = PORT_HSP_MODE;
185 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "OBP: Hot Swappable"));
186 	}
187 
188 	/*
189 	 * MDIO polling support for Monza RTM card, Goa NEM card
190 	 */
191 	if (nxgep->mac.portmode == PORT_HSP_MODE) {
192 
193 		uint8_t portn = NXGE_GET_PORT_NUM(nxgep->function_num);
194 
195 		nxgep->hot_swappable_phy = B_TRUE;
196 		/*
197 		 * If this is the 2nd NIU port, then check 2 addresses
198 		 * to take care of the Goa NEM card. Port 1 can have addr 17
199 		 * (in the eval board) or 20 (in the P0 board).
200 		 */
201 		if (portn == 1) {
202 			if (nxge_is_phy_present(nxgep,
203 			    BCM8706_ALT_GOA_PORT1_ADDR, BCM8706_DEV_ID,
204 			    BCM_PHY_ID_MASK)) {
205 				nxgep->xcvr_addr =
206 				    BCM8706_ALT_GOA_PORT1_ADDR;
207 				goto found_phy;
208 			}
209 		}
210 		if (nxge_is_phy_present(nxgep,
211 		    (BCM8706_GOA_PORT_ADDR_BASE) + portn,
212 		    BCM8706_DEV_ID, BCM_PHY_ID_MASK)) {
213 			nxgep->xcvr_addr = (BCM8706_GOA_PORT_ADDR_BASE) +
214 			    portn;
215 			goto found_phy;
216 		}
217 
218 		nxgep->phy_absent = B_TRUE;
219 		goto check_phy_done;
220 found_phy:
221 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
222 		nxgep->mac.portmode = PORT_10G_FIBER;
223 		nxgep->phy_absent = B_FALSE;
224 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Fiber Xcvr "
225 		    "found for hot swappable phy"));
226 check_phy_done:
227 		return (status);
228 	}
229 
230 	/* Get phy-type property from the driver conf. file */
231 	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip,
232 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
233 	    "phy-type", &prop_val)) == DDI_PROP_SUCCESS) {
234 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
235 		    "found  conf file: phy-type %s", prop_val));
236 		if (strcmp("xgsd", prop_val) == 0) {
237 			nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
238 			nxgep->mac.portmode = PORT_10G_SERDES;
239 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
240 			    "found: 10G Serdes"));
241 		} else if (strcmp("gsd", prop_val) == 0) {
242 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
243 			nxgep->mac.portmode = PORT_1G_SERDES;
244 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Serdes"));
245 		} else if (strcmp("mif", prop_val) == 0) {
246 			nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
247 			nxgep->mac.portmode = PORT_1G_COPPER;
248 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr"));
249 		} else if (strcmp("pcs", prop_val) == 0) {
250 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
251 			nxgep->mac.portmode = PORT_1G_FIBER;
252 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G FIBER Xcvr"));
253 		}
254 
255 		(void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip,
256 		    "phy-type", prop_val);
257 		ddi_prop_free(prop_val);
258 
259 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
260 		    "Got phy type [0x%x] from conf file",
261 		    nxgep->mac.portmode));
262 
263 		return (NXGE_OK);
264 	}
265 
266 	/* Get phy-type property from OBP */
267 	if (nxgep->niu_type == N2_NIU) {
268 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0,
269 		    "phy-type", &prop_val) == DDI_PROP_SUCCESS) {
270 			if (strcmp("xgf", prop_val) == 0) {
271 				nxgep->statsp->mac_stats.xcvr_inuse =
272 				    XPCS_XCVR;
273 				nxgep->mac.portmode = PORT_10G_FIBER;
274 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
275 				    "10G Fiber Xcvr"));
276 			} else if (strcmp("mif", prop_val) == 0) {
277 				nxgep->statsp->mac_stats.xcvr_inuse =
278 				    INT_MII_XCVR;
279 				nxgep->mac.portmode = PORT_1G_COPPER;
280 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
281 				    "1G Copper Xcvr"));
282 			} else if (strcmp("pcs", prop_val) == 0) {
283 				nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
284 				nxgep->mac.portmode = PORT_1G_FIBER;
285 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
286 				    "1G Fiber Xcvr"));
287 			} else if (strcmp("xgc", prop_val) == 0) {
288 				nxgep->statsp->mac_stats.xcvr_inuse =
289 				    XPCS_XCVR;
290 				nxgep->mac.portmode = PORT_10G_COPPER;
291 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
292 				    "10G Copper Xcvr"));
293 			} else if (strcmp("xgsd", prop_val) == 0) {
294 				nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
295 				nxgep->mac.portmode = PORT_10G_SERDES;
296 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
297 				    "OBP: 10G Serdes"));
298 			} else if (strcmp("gsd", prop_val) == 0) {
299 				nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
300 				nxgep->mac.portmode = PORT_1G_SERDES;
301 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
302 				    "OBP: 1G Serdes"));
303 			} else {
304 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
305 				    "Unknown phy-type: %s", prop_val));
306 				ddi_prop_free(prop_val);
307 				return (NXGE_ERROR);
308 			}
309 			status = NXGE_OK;
310 			(void) ddi_prop_update_string(DDI_DEV_T_NONE,
311 			    nxgep->dip, "phy-type", prop_val);
312 			ddi_prop_free(prop_val);
313 
314 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
315 			    "Got phy type [0x%x] from OBP",
316 			    nxgep->mac.portmode));
317 
318 			return (status);
319 		} else {
320 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
321 			    "Exiting...phy-type property not found"));
322 			return (NXGE_ERROR);
323 		}
324 	}
325 
326 
327 	if (!nxgep->vpd_info.present) {
328 		return (NXGE_OK);
329 	}
330 
331 	if (!nxgep->vpd_info.ver_valid) {
332 		goto read_seeprom;
333 	}
334 
335 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
336 	    "Reading phy type from expansion ROM"));
337 	/*
338 	 * Try to read the phy type from the vpd data read off the
339 	 * expansion ROM.
340 	 */
341 	phy_type = nxgep->vpd_info.phy_type;
342 
343 	if (strncmp(phy_type, "mif", 3) == 0) {
344 		nxgep->mac.portmode = PORT_1G_COPPER;
345 		nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
346 	} else if (strncmp(phy_type, "xgf", 3) == 0) {
347 		nxgep->mac.portmode = PORT_10G_FIBER;
348 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
349 	} else if (strncmp(phy_type, "pcs", 3) == 0) {
350 		nxgep->mac.portmode = PORT_1G_FIBER;
351 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
352 	} else if (strncmp(phy_type, "xgc", 3) == 0) {
353 		nxgep->mac.portmode = PORT_10G_COPPER;
354 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
355 	} else if (strncmp(phy_type, "xgsd", 4) == 0) {
356 		nxgep->mac.portmode = PORT_10G_SERDES;
357 		nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
358 	} else if (strncmp(phy_type, "gsd", 3) == 0) {
359 		nxgep->mac.portmode = PORT_1G_SERDES;
360 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
361 	} else {
362 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
363 		    "nxge_get_xcvr_type: Unknown phy type [%c%c%c] in EEPROM",
364 		    phy_type[0], phy_type[1], phy_type[2]));
365 		goto read_seeprom;
366 	}
367 
368 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_get_xcvr_type: "
369 	    "Got phy type [0x%x] from VPD", nxgep->mac.portmode));
370 
371 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type"));
372 	return (status);
373 
374 read_seeprom:
375 	/*
376 	 * read the phy type from the SEEPROM - NCR registers
377 	 */
378 	status = nxge_espc_phy_type_get(nxgep);
379 	if (status != NXGE_OK) {
380 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
381 		    "Failed to get phy type"));
382 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version "
383 		    "[%s] invalid...please update", nxgep->vpd_info.ver));
384 	}
385 
386 	return (status);
387 
388 }
389 
390 /* Set up the PHY specific values. */
391 
392 nxge_status_t
393 nxge_setup_xcvr_table(p_nxge_t nxgep)
394 {
395 	nxge_status_t	status = NXGE_OK;
396 	uint32_t	port_type;
397 	uint8_t		portn = NXGE_GET_PORT_NUM(nxgep->function_num);
398 	uint32_t	pcs_id = 0;
399 	uint32_t	pma_pmd_id = 0;
400 	uint32_t	phy_id = 0;
401 	uint16_t	chip_id = 0;
402 
403 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_setup_xcvr_table: port<%d>",
404 	    portn));
405 
406 	switch (nxgep->niu_type) {
407 	case N2_NIU:
408 		switch (nxgep->mac.portmode) {
409 		case PORT_1G_FIBER:
410 		case PORT_1G_SERDES:
411 			nxgep->xcvr = nxge_n2_1G_table;
412 			nxgep->xcvr_addr = portn;
413 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 1G %s Xcvr",
414 			    (nxgep->mac.portmode == PORT_1G_FIBER) ? "Fiber" :
415 			    "Serdes"));
416 			break;
417 		case PORT_10G_FIBER:
418 		case PORT_10G_SERDES:
419 			nxgep->xcvr = nxge_n2_10G_table;
420 			if (nxgep->nxge_hw_p->xcvr_addr[portn]) {
421 				nxgep->xcvr_addr =
422 				    nxgep->nxge_hw_p->xcvr_addr[portn];
423 			}
424 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G %s Xcvr",
425 			    (nxgep->mac.portmode == PORT_10G_FIBER) ? "Fiber" :
426 			    "Serdes"));
427 			break;
428 		case PORT_HSP_MODE:
429 			nxgep->xcvr = nxge_n2_10G_table;
430 			nxgep->xcvr.xcvr_inuse = HSP_XCVR;
431 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "NIU 10G Hot "
432 			    "Swappable Xcvr (not present)"));
433 			break;
434 		default:
435 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
436 			    "<== nxge_setup_xcvr_table: "
437 			    "Unable to determine NIU portmode"));
438 			return (NXGE_ERROR);
439 		}
440 		break;
441 	default:
442 		if (nxgep->mac.portmode == 0) {
443 			/*
444 			 * Would be the case for platforms like Maramba
445 			 * in which the phy type could not be got from conf
446 			 * file, OBP, VPD or Serial PROM.
447 			 */
448 			if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
449 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
450 				    "<== nxge_setup_xcvr_table:"
451 				    " Invalid Neptune type [0x%x]",
452 				    nxgep->niu_type));
453 				return (NXGE_ERROR);
454 			}
455 
456 			port_type = nxgep->niu_type >>
457 			    (NXGE_PORT_TYPE_SHIFT * portn);
458 			port_type = port_type & (NXGE_PORT_TYPE_MASK);
459 
460 			switch (port_type) {
461 
462 			case NXGE_PORT_1G_COPPER:
463 				nxgep->mac.portmode = PORT_1G_COPPER;
464 				break;
465 			case NXGE_PORT_10G_COPPER:
466 				nxgep->mac.portmode = PORT_10G_COPPER;
467 				break;
468 			case NXGE_PORT_1G_FIBRE:
469 				nxgep->mac.portmode = PORT_1G_FIBER;
470 				break;
471 			case NXGE_PORT_10G_FIBRE:
472 				nxgep->mac.portmode = PORT_10G_FIBER;
473 				break;
474 			case NXGE_PORT_1G_SERDES:
475 				nxgep->mac.portmode = PORT_1G_SERDES;
476 				break;
477 			case NXGE_PORT_10G_SERDES:
478 				nxgep->mac.portmode = PORT_10G_SERDES;
479 				break;
480 			case NXGE_PORT_1G_RGMII_FIBER:
481 				nxgep->mac.portmode = PORT_1G_RGMII_FIBER;
482 				break;
483 			default:
484 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
485 				    "<== nxge_setup_xcvr_table: "
486 				    "Unknown port-type: 0x%x", port_type));
487 				return (NXGE_ERROR);
488 			}
489 		}
490 
491 		switch (nxgep->mac.portmode) {
492 		case PORT_1G_COPPER:
493 		case PORT_1G_RGMII_FIBER:
494 			nxgep->xcvr = nxge_1G_copper_table;
495 			nxgep->xcvr_addr = nxgep->nxge_hw_p->xcvr_addr[portn];
496 			/*
497 			 * For Altas 4-1G copper, Xcvr port numbers are
498 			 * swapped with ethernet port number. This is
499 			 * designed for better signal integrity in
500 			 * routing. This is also the case for the
501 			 * on-board Neptune copper ports on the Maramba
502 			 * platform.
503 			 */
504 			switch (nxgep->platform_type) {
505 			case P_NEPTUNE_ATLAS_4PORT:
506 			case P_NEPTUNE_MARAMBA_P0:
507 			case P_NEPTUNE_MARAMBA_P1:
508 				switch (portn) {
509 				case 0:
510 					nxgep->xcvr_addr += 3;
511 					break;
512 				case 1:
513 					nxgep->xcvr_addr += 1;
514 					break;
515 				case 2:
516 					nxgep->xcvr_addr -= 1;
517 					break;
518 				case 3:
519 					nxgep->xcvr_addr -= 3;
520 					break;
521 				default:
522 					return (NXGE_ERROR);
523 				}
524 				break;
525 			case P_NEPTUNE_ALONSO:
526 			/*
527 			 * The Alonso Neptune, xcvr port numbers for
528 			 * ports 2 and 3 are not swapped. Port 2 has
529 			 * the BCM5464_PORT_BASE_ADDR and port 3 has
530 			 * next address.
531 			 */
532 				nxgep->xcvr_addr =
533 				    BCM5464_NEPTUNE_PORT_ADDR_BASE;
534 				if (portn == 3) {
535 					nxgep->xcvr_addr += 1;
536 				}
537 				break;
538 			default:
539 				break;
540 			}
541 
542 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
543 			    (nxgep->mac.portmode == PORT_1G_COPPER) ?
544 			    "Copper" : "RGMII Fiber"));
545 			break;
546 		case PORT_10G_COPPER:
547 			nxgep->xcvr = nxge_10G_copper_table;
548 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr"));
549 			break;
550 		case PORT_1G_FIBER:
551 		case PORT_1G_SERDES:
552 			nxgep->xcvr = nxge_1G_fiber_table;
553 			nxgep->xcvr_addr = portn;
554 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G %s Xcvr",
555 			    (nxgep->mac.portmode == PORT_1G_FIBER) ?
556 			    "Fiber" : "Serdes"));
557 			break;
558 		case PORT_10G_FIBER:
559 		case PORT_10G_SERDES:
560 			nxgep->xcvr = nxge_10G_fiber_table;
561 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G xcvr "
562 			    "nxgep->nxge_hw_p->xcvr_addr[portn] = [%d] "
563 			    "nxgep->xcvr_addr = [%d]",
564 			    nxgep->nxge_hw_p->xcvr_addr[portn],
565 			    nxgep->xcvr_addr));
566 			if (nxgep->nxge_hw_p->xcvr_addr[portn]) {
567 				nxgep->xcvr_addr =
568 				    nxgep->nxge_hw_p->xcvr_addr[portn];
569 			}
570 			switch (nxgep->platform_type) {
571 			case P_NEPTUNE_MARAMBA_P0:
572 			case P_NEPTUNE_MARAMBA_P1:
573 				/*
574 				 * Switch off LED for corresponding copper
575 				 * port
576 				 */
577 				nxge_bcm5464_link_led_off(nxgep);
578 				break;
579 			default:
580 				break;
581 			}
582 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G %s Xcvr",
583 			    (nxgep->mac.portmode == PORT_10G_FIBER) ?
584 			    "Fiber" : "Serdes"));
585 			break;
586 
587 		case PORT_HSP_MODE:
588 			nxgep->xcvr = nxge_10G_fiber_table;
589 			nxgep->xcvr.xcvr_inuse = HSP_XCVR;
590 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Neptune 10G Hot "
591 			    "Swappable Xcvr (not present)"));
592 			break;
593 		default:
594 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
595 			    "Unknown port-type: 0x%x", port_type));
596 			return (NXGE_ERROR);
597 		}
598 	}
599 
600 	if (nxgep->mac.portmode == PORT_10G_FIBER) {
601 		if ((status = nxge_mdio_read(nxgep, nxgep->xcvr_addr,
602 		    BCM8704_PCS_DEV_ADDR, BCM8704_CHIP_ID_REG,
603 		    &chip_id)) == NXGE_OK) {
604 
605 			switch (chip_id) {
606 			case BCM8704_CHIP_ID:
607 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
608 				    "nxge_setup_xcvr_table: "
609 				    "Chip ID 8704 [0x%x] for 10G xcvr",
610 				    chip_id));
611 				break;
612 			case BCM8706_CHIP_ID:
613 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
614 				    "nxge_setup_xcvr_table: "
615 				    "Chip ID 8706 [0x%x] for 10G xcvr",
616 				    chip_id));
617 				break;
618 			default:
619 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
620 				    "nxge_setup_xcvr_table: "
621 				    "Unknown Chip ID [0x%x] for 10G xcvr",
622 				    chip_id));
623 				break;
624 			}
625 		}
626 	}
627 
628 	nxgep->statsp->mac_stats.xcvr_inuse = nxgep->xcvr.xcvr_inuse;
629 	nxgep->statsp->mac_stats.xcvr_portn = nxgep->xcvr_addr;
630 	nxgep->chip_id = chip_id;
631 
632 	/*
633 	 * Get the actual device ID value returned by MDIO read.
634 	 */
635 	nxgep->statsp->mac_stats.xcvr_id = 0;
636 
637 	pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, nxgep->xcvr_addr);
638 	if (nxge_is_supported_phy(pma_pmd_id, CLAUSE_45_TYPE)) {
639 		nxgep->statsp->mac_stats.xcvr_id = pma_pmd_id;
640 	} else {
641 		pcs_id = nxge_get_cl45_pcs_id(nxgep, nxgep->xcvr_addr);
642 		if (nxge_is_supported_phy(pcs_id, CLAUSE_45_TYPE)) {
643 			nxgep->statsp->mac_stats.xcvr_id = pcs_id;
644 		} else {
645 			phy_id = nxge_get_cl22_phy_id(nxgep,
646 			    nxgep->xcvr_addr);
647 			if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) {
648 				nxgep->statsp->mac_stats.xcvr_id = phy_id;
649 			}
650 		}
651 	}
652 
653 	nxgep->mac.linkchkmode = LINKCHK_TIMER;
654 
655 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_setup_xcvr_table: niu_type"
656 	    "[0x%x] platform type[0x%x] xcvr_arr[%d]", nxgep->niu_type,
657 	    nxgep->platform_type, nxgep->xcvr_addr));
658 
659 	return (status);
660 }
661 
662 /* Initialize the entire MAC and physical layer */
663 
664 nxge_status_t
665 nxge_mac_init(p_nxge_t nxgep)
666 {
667 	uint8_t			portn;
668 	nxge_status_t		status = NXGE_OK;
669 
670 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
671 
672 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn));
673 
674 	nxgep->mac.portnum = portn;
675 	nxgep->mac.porttype = PORT_TYPE_XMAC;
676 
677 	if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1))
678 		nxgep->mac.porttype = PORT_TYPE_BMAC;
679 
680 	/* Initialize XIF to configure a network mode */
681 	if ((status = nxge_xif_init(nxgep)) != NXGE_OK) {
682 		goto fail;
683 	}
684 
685 	if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) {
686 		goto fail;
687 	}
688 
689 	/* Initialize TX and RX MACs */
690 	/*
691 	 * Always perform XIF init first, before TX and RX MAC init
692 	 */
693 	if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK)
694 		goto fail;
695 
696 	if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
697 		goto fail;
698 
699 	if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK)
700 		goto fail;
701 
702 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
703 		goto fail;
704 
705 	if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK)
706 		goto fail;
707 
708 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
709 		goto fail;
710 
711 	/* Initialize MAC control configuration */
712 	if ((status = nxge_mac_ctrl_init(nxgep)) != NXGE_OK) {
713 		goto fail;
714 	}
715 
716 	nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize;
717 
718 	/* The Neptune Serdes needs to be reinitialized again */
719 	if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
720 	    ((nxgep->mac.portmode == PORT_1G_SERDES) ||
721 	    (nxgep->mac.portmode == PORT_1G_FIBER)) &&
722 	    ((portn == 0) || (portn == 1))) {
723 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
724 		    "nxge_mac_init: reinit Neptune 1G Serdes "));
725 		if ((status = nxge_1G_serdes_init(nxgep)) != NXGE_OK) {
726 			goto fail;
727 		}
728 	}
729 
730 
731 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn));
732 
733 	return (NXGE_OK);
734 fail:
735 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
736 			"nxge_mac_init: failed to initialize MAC port<%d>",
737 			portn));
738 	return (status);
739 }
740 
741 /* Initialize the Ethernet Link */
742 
743 nxge_status_t
744 nxge_link_init(p_nxge_t nxgep)
745 {
746 	nxge_status_t		status = NXGE_OK;
747 	nxge_port_mode_t	portmode;
748 #ifdef	NXGE_DEBUG
749 	uint8_t			portn;
750 
751 	portn = nxgep->mac.portnum;
752 
753 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn));
754 #endif
755 	if (nxgep->hot_swappable_phy && nxgep->phy_absent) {
756 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: "
757 		    "Phy not present, cannot initialize link"));
758 		return (status);
759 	}
760 
761 	portmode = nxgep->mac.portmode;
762 
763 	if (nxgep->niu_type == N2_NIU && (portmode != PORT_10G_SERDES) &&
764 	    (portmode != PORT_1G_SERDES)) {
765 		/* Workaround to get link up in both NIU ports */
766 		if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK) {
767 			goto fail;
768 		}
769 	}
770 	NXGE_DELAY(200000);
771 	/* Initialize internal serdes */
772 	if ((status = nxge_serdes_init(nxgep)) != NXGE_OK)
773 		goto fail;
774 	NXGE_DELAY(200000);
775 	if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK)
776 		goto fail;
777 
778 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn));
779 
780 	return (NXGE_OK);
781 
782 fail:
783 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
784 		"nxge_link_init: ",
785 		"failed to initialize Ethernet link on port<%d>",
786 		portn));
787 
788 	return (status);
789 }
790 
791 
792 /* Initialize the XIF sub-block within the MAC */
793 
794 nxge_status_t
795 nxge_xif_init(p_nxge_t nxgep)
796 {
797 	uint32_t		xif_cfg = 0;
798 	npi_attr_t		ap;
799 	uint8_t			portn;
800 	nxge_port_t		portt;
801 	nxge_port_mode_t	portmode;
802 	p_nxge_stats_t		statsp;
803 	npi_status_t		rs = NPI_SUCCESS;
804 	npi_handle_t		handle;
805 
806 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
807 
808 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn));
809 
810 	handle = nxgep->npi_handle;
811 	portmode = nxgep->mac.portmode;
812 	portt = nxgep->mac.porttype;
813 	statsp = nxgep->statsp;
814 
815 	if ((NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) &&
816 	    ((nxgep->mac.portmode == PORT_1G_SERDES) ||
817 	    (nxgep->mac.portmode == PORT_1G_FIBER)) &&
818 	    ((portn == 0) || (portn == 1))) {
819 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
820 		    "nxge_xcvr_init: set ATCA mode"));
821 		npi_mac_mif_set_atca_mode(nxgep->npi_handle, B_TRUE);
822 	}
823 
824 	if (portt == PORT_TYPE_XMAC) {
825 
826 		/* Setup XIF Configuration for XMAC */
827 
828 		if ((portmode == PORT_10G_FIBER) ||
829 		    (portmode == PORT_10G_COPPER) ||
830 		    (portmode == PORT_10G_SERDES))
831 			xif_cfg |= CFG_XMAC_XIF_LFS;
832 
833 		if (portmode == PORT_1G_COPPER) {
834 			xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS;
835 		}
836 
837 		/* Set MAC Internal Loopback if necessary */
838 		if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
839 			xif_cfg |= CFG_XMAC_XIF_LOOPBACK;
840 
841 		if (statsp->mac_stats.link_speed == 100)
842 			xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ;
843 
844 		xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT;
845 
846 		if ((portmode == PORT_10G_FIBER) ||
847 		    (portmode == PORT_10G_SERDES)) {
848 			if (statsp->mac_stats.link_up) {
849 				xif_cfg |= CFG_XMAC_XIF_LED_POLARITY;
850 			} else {
851 				xif_cfg |= CFG_XMAC_XIF_LED_FORCE;
852 			}
853 		}
854 
855 		rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg);
856 		if (rs != NPI_SUCCESS)
857 			goto fail;
858 
859 		nxgep->mac.xif_config = xif_cfg;
860 
861 		/* Set Port Mode */
862 		if ((portmode == PORT_10G_FIBER) ||
863 		    (portmode == PORT_10G_COPPER) ||
864 		    (portmode == PORT_10G_SERDES)) {
865 			SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
866 						MAC_XGMII_MODE, rs);
867 			if (rs != NPI_SUCCESS)
868 				goto fail;
869 			if (statsp->mac_stats.link_up) {
870 				if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
871 					goto fail;
872 			} else {
873 				if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
874 					goto fail;
875 			}
876 		} else if ((portmode == PORT_1G_FIBER) ||
877 		    (portmode == PORT_1G_COPPER) ||
878 		    (portmode == PORT_1G_SERDES) ||
879 		    (portmode == PORT_1G_RGMII_FIBER)) {
880 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
881 			    "nxge_xif_init: Port[%d] Mode[%d] Speed[%d]",
882 			    portn, portmode, statsp->mac_stats.link_speed));
883 			if (statsp->mac_stats.link_speed == 1000) {
884 				SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
885 							MAC_GMII_MODE, rs);
886 			} else {
887 				SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
888 							MAC_MII_MODE, rs);
889 			}
890 			if (rs != NPI_SUCCESS)
891 				goto fail;
892 		} else {
893 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
894 					"nxge_xif_init: Unknown port mode (%d)"
895 					" for port<%d>", portmode, portn));
896 			goto fail;
897 		}
898 
899 		/* Enable ATCA mode */
900 
901 	} else if (portt == PORT_TYPE_BMAC) {
902 
903 		/* Setup XIF Configuration for BMAC */
904 
905 		if ((portmode == PORT_1G_COPPER) ||
906 		    (portmode == PORT_1G_RGMII_FIBER)) {
907 			if (statsp->mac_stats.link_speed == 100)
908 				xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ;
909 		}
910 
911 		if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
912 			xif_cfg |= CFG_BMAC_XIF_LOOPBACK;
913 
914 		if (statsp->mac_stats.link_speed == 1000)
915 			xif_cfg |= CFG_BMAC_XIF_GMII_MODE;
916 
917 		xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT;
918 
919 		rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg);
920 		if (rs != NPI_SUCCESS)
921 			goto fail;
922 		nxgep->mac.xif_config = xif_cfg;
923 	}
924 
925 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn));
926 	return (NXGE_OK);
927 fail:
928 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
929 			"nxge_xif_init: Failed to initialize XIF port<%d>",
930 			portn));
931 	return (NXGE_ERROR | rs);
932 }
933 
934 /* Initialize the PCS sub-block in the MAC */
935 
936 nxge_status_t
937 nxge_pcs_init(p_nxge_t nxgep)
938 {
939 	pcs_cfg_t		pcs_cfg;
940 	uint32_t		val;
941 	uint8_t			portn;
942 	nxge_port_mode_t	portmode;
943 	npi_handle_t		handle;
944 	p_nxge_stats_t		statsp;
945 	npi_status_t		rs = NPI_SUCCESS;
946 
947 	handle = nxgep->npi_handle;
948 	portmode = nxgep->mac.portmode;
949 	portn = nxgep->mac.portnum;
950 	statsp = nxgep->statsp;
951 
952 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn));
953 
954 	if ((portmode == PORT_1G_FIBER) || (portmode == PORT_1G_SERDES)) {
955 		if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS) {
956 			goto fail;
957 		}
958 
959 		/* Initialize port's PCS */
960 		pcs_cfg.value = 0;
961 		pcs_cfg.bits.w0.enable = 1;
962 		pcs_cfg.bits.w0.mask = 1;
963 		PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value);
964 		PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0);
965 
966 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
967 		    "==> nxge_pcs_init: (1G) port<%d> write config 0x%llx",
968 		    portn, pcs_cfg.value));
969 	} else if ((portmode == PORT_10G_FIBER) ||
970 	    (portmode == PORT_10G_COPPER) || (portmode == PORT_10G_SERDES)) {
971 		/* Use internal XPCS, bypass 1G PCS */
972 		XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val);
973 		val &= ~XMAC_XIF_XPCS_BYPASS;
974 		XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val);
975 
976 		if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS)
977 			goto fail;
978 
979 		/* Set XPCS Internal Loopback if necessary */
980 		if ((rs = npi_xmac_xpcs_read(handle, portn,
981 						XPCS_REG_CONTROL1, &val))
982 						!= NPI_SUCCESS)
983 			goto fail;
984 		if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) ||
985 			(statsp->port_stats.lb_mode == nxge_lb_mac1000))
986 			val |= XPCS_CTRL1_LOOPBK;
987 		else
988 			val &= ~XPCS_CTRL1_LOOPBK;
989 		if ((rs = npi_xmac_xpcs_write(handle, portn,
990 						XPCS_REG_CONTROL1, val))
991 						!= NPI_SUCCESS)
992 			goto fail;
993 
994 		/* Clear descw errors */
995 		if ((rs = npi_xmac_xpcs_write(handle, portn,
996 						XPCS_REG_DESCWERR_COUNTER, 0))
997 						!= NPI_SUCCESS)
998 			goto fail;
999 		/* Clear symbol errors */
1000 		if ((rs = npi_xmac_xpcs_read(handle, portn,
1001 					XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val))
1002 					!= NPI_SUCCESS)
1003 			goto fail;
1004 		if ((rs = npi_xmac_xpcs_read(handle, portn,
1005 					XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val))
1006 					!= NPI_SUCCESS)
1007 			goto fail;
1008 
1009 	} else if ((portmode == PORT_1G_COPPER) ||
1010 	    (portmode == PORT_1G_RGMII_FIBER)) {
1011 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1012 		    "==> nxge_pcs_init: (1G) copper port<%d>", portn));
1013 		if (portn < 4) {
1014 			PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG,
1015 					PCS_DATAPATH_MODE_MII);
1016 		}
1017 		if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS)
1018 			goto fail;
1019 
1020 	} else {
1021 		goto fail;
1022 	}
1023 pass:
1024 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn));
1025 	return (NXGE_OK);
1026 fail:
1027 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1028 			"nxge_pcs_init: Failed to initialize PCS port<%d>",
1029 			portn));
1030 	return (NXGE_ERROR | rs);
1031 }
1032 
1033 /*
1034  * Initialize the MAC CTRL sub-block within the MAC
1035  * Only the receive-pause-cap is supported.
1036  */
1037 nxge_status_t
1038 nxge_mac_ctrl_init(p_nxge_t nxgep)
1039 {
1040 	uint8_t			portn;
1041 	nxge_port_t		portt;
1042 	p_nxge_stats_t		statsp;
1043 	npi_handle_t		handle;
1044 	uint32_t		val;
1045 
1046 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
1047 
1048 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_ctrl_init: port<%d>",
1049 	    portn));
1050 
1051 	handle = nxgep->npi_handle;
1052 	portt = nxgep->mac.porttype;
1053 	statsp = nxgep->statsp;
1054 
1055 	if (portt == PORT_TYPE_XMAC) {
1056 		/* Readin the current XMAC Config Register for XMAC */
1057 		XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val);
1058 
1059 		/*
1060 		 * Setup XMAC Configuration for XMAC
1061 		 * XMAC only supports receive-pause
1062 		 */
1063 		if (statsp->mac_stats.adv_cap_asmpause) {
1064 			if (!statsp->mac_stats.adv_cap_pause) {
1065 				/*
1066 				 * If adv_cap_asmpause is 1 and adv_cap_pause
1067 				 * is 0, enable receive pause.
1068 				 */
1069 				val |= XMAC_RX_CFG_RX_PAUSE_EN;
1070 			} else {
1071 				/*
1072 				 * If adv_cap_asmpause is 1 and adv_cap_pause
1073 				 * is 1, disable receive pause.  Send pause is
1074 				 * not supported.
1075 				 */
1076 				val &= ~XMAC_RX_CFG_RX_PAUSE_EN;
1077 			}
1078 		} else {
1079 			if (statsp->mac_stats.adv_cap_pause) {
1080 				/*
1081 				 * If adv_cap_asmpause is 0 and adv_cap_pause
1082 				 * is 1, enable receive pause.
1083 				 */
1084 				val |= XMAC_RX_CFG_RX_PAUSE_EN;
1085 			} else {
1086 				/*
1087 				 * If adv_cap_asmpause is 0 and adv_cap_pause
1088 				 * is 0, disable receive pause. Send pause is
1089 				 * not supported
1090 				 */
1091 				val &= ~XMAC_RX_CFG_RX_PAUSE_EN;
1092 			}
1093 		}
1094 		XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val);
1095 	} else if (portt == PORT_TYPE_BMAC) {
1096 		/* Readin the current MAC CTRL Config Register for BMAC */
1097 		BMAC_REG_RD(handle, portn, MAC_CTRL_CONFIG_REG, &val);
1098 
1099 		/* Setup MAC CTRL Configuration for BMAC */
1100 		if (statsp->mac_stats.adv_cap_asmpause) {
1101 			if (statsp->mac_stats.adv_cap_pause) {
1102 				/*
1103 				 * If adv_cap_asmpause is 1 and adv_cap_pause
1104 				 * is 1, disable receive pause. Send pause
1105 				 * is not supported
1106 				 */
1107 				val &= ~MAC_CTRL_CFG_RECV_PAUSE_EN;
1108 			} else {
1109 				/*
1110 				 * If adv_cap_asmpause is 1 and adv_cap_pause
1111 				 * is 0, enable receive pause and disable
1112 				 * send pause.
1113 				 */
1114 				val |= MAC_CTRL_CFG_RECV_PAUSE_EN;
1115 				val &= ~MAC_CTRL_CFG_SEND_PAUSE_EN;
1116 			}
1117 		} else {
1118 			if (statsp->mac_stats.adv_cap_pause) {
1119 				/*
1120 				 * If adv_cap_asmpause is 0 and adv_cap_pause
1121 				 * is 1, enable receive pause. Send pause is
1122 				 * not supported.
1123 				 */
1124 				val |= MAC_CTRL_CFG_RECV_PAUSE_EN;
1125 			} else {
1126 				/*
1127 				 * If adv_cap_asmpause is 0 and adv_cap_pause
1128 				 * is 0, pause capability is not available in
1129 				 * either direction.
1130 				 */
1131 				val &= (~MAC_CTRL_CFG_SEND_PAUSE_EN &
1132 					~MAC_CTRL_CFG_RECV_PAUSE_EN);
1133 			}
1134 		}
1135 		BMAC_REG_WR(handle, portn, MAC_CTRL_CONFIG_REG, val);
1136 	}
1137 
1138 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_ctrl_init: port<%d>",
1139 	    portn));
1140 
1141 	return (NXGE_OK);
1142 }
1143 
1144 /* Initialize the Internal Serdes */
1145 
1146 nxge_status_t
1147 nxge_serdes_init(p_nxge_t nxgep)
1148 {
1149 	p_nxge_stats_t		statsp;
1150 #ifdef	NXGE_DEBUG
1151 	uint8_t			portn;
1152 #endif
1153 	nxge_status_t		status = NXGE_OK;
1154 
1155 #ifdef	NXGE_DEBUG
1156 	portn = nxgep->mac.portnum;
1157 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1158 	    "==> nxge_serdes_init port<%d>", portn));
1159 #endif
1160 
1161 	if (nxgep->xcvr.serdes_init) {
1162 		statsp = nxgep->statsp;
1163 		status = nxgep->xcvr.serdes_init(nxgep);
1164 		if (status != NXGE_OK)
1165 			goto fail;
1166 		statsp->mac_stats.serdes_inits++;
1167 	}
1168 
1169 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>",
1170 	    portn));
1171 
1172 	return (NXGE_OK);
1173 
1174 fail:
1175 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1176 	    "nxge_serdes_init: Failed to initialize serdes for port<%d>",
1177 	    portn));
1178 
1179 	return (status);
1180 }
1181 
1182 /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */
1183 
1184 static nxge_status_t
1185 nxge_n2_serdes_init(p_nxge_t nxgep)
1186 {
1187 	uint8_t portn;
1188 	int chan;
1189 	esr_ti_cfgpll_l_t pll_cfg_l;
1190 	esr_ti_cfgpll_l_t pll_sts_l;
1191 	esr_ti_cfgrx_l_t rx_cfg_l;
1192 	esr_ti_cfgrx_h_t rx_cfg_h;
1193 	esr_ti_cfgtx_l_t tx_cfg_l;
1194 	esr_ti_cfgtx_h_t tx_cfg_h;
1195 #ifdef NXGE_DEBUG
1196 	esr_ti_testcfg_t cfg;
1197 #endif
1198 	esr_ti_testcfg_t test_cfg;
1199 	nxge_status_t status = NXGE_OK;
1200 
1201 	portn = nxgep->mac.portnum;
1202 
1203 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>",
1204 			portn));
1205 
1206 	tx_cfg_l.value = 0;
1207 	tx_cfg_h.value = 0;
1208 	rx_cfg_l.value = 0;
1209 	rx_cfg_h.value = 0;
1210 	pll_cfg_l.value = 0;
1211 	pll_sts_l.value = 0;
1212 	test_cfg.value = 0;
1213 
1214 	if ((nxgep->mac.portmode == PORT_10G_FIBER) ||
1215 	    (nxgep->mac.portmode == PORT_10G_SERDES)) {
1216 		/* 0x0E01 */
1217 		tx_cfg_l.bits.entx = 1;
1218 		tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
1219 
1220 		/* 0x9101 */
1221 		rx_cfg_l.bits.enrx = 1;
1222 		rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
1223 		rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
1224 		rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
1225 
1226 		/* 0x0008 */
1227 		rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
1228 
1229 		/* Set loopback mode if necessary */
1230 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
1231 			tx_cfg_l.bits.entest = 1;
1232 			rx_cfg_l.bits.entest = 1;
1233 			test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
1234 			if ((status = nxge_mdio_write(nxgep, portn,
1235 				ESR_N2_DEV_ADDR,
1236 				ESR_N2_TEST_CFG_REG, test_cfg.value))
1237 				!= NXGE_OK)
1238 			goto fail;
1239 		}
1240 
1241 		/* Use default PLL value */
1242 
1243 	} else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
1244 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
1245 
1246 		/* 0x0E21 */
1247 		tx_cfg_l.bits.entx = 1;
1248 		tx_cfg_l.bits.rate = CFGTX_RATE_HALF;
1249 		tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
1250 
1251 		/* 0x9121 */
1252 		rx_cfg_l.bits.enrx = 1;
1253 		rx_cfg_l.bits.rate = CFGRX_RATE_HALF;
1254 		rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
1255 		rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
1256 		rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
1257 
1258 		if (portn == 0) {
1259 			/* 0x8 */
1260 			rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
1261 		}
1262 
1263 		/* MPY = 0x100 */
1264 		pll_cfg_l.bits.mpy = CFGPLL_MPY_8X;
1265 
1266 		/* Set PLL */
1267 		pll_cfg_l.bits.enpll = 1;
1268 		pll_sts_l.bits.enpll = 1;
1269 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
1270 				ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value))
1271 				!= NXGE_OK)
1272 			goto fail;
1273 
1274 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
1275 		    ESR_N2_PLL_STS_L_REG, pll_sts_l.value)) != NXGE_OK)
1276 			goto fail;
1277 
1278 #ifdef  NXGE_DEBUG
1279 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
1280 		    ESR_N2_PLL_CFG_L_REG, &cfg.value);
1281 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1282 		    "==> nxge_n2_serdes_init port<%d>: PLL cfg.l 0x%x (0x%x)",
1283 		    portn, pll_cfg_l.value, cfg.value));
1284 
1285 		nxge_mdio_read(nxgep, portn, ESR_N2_DEV_ADDR,
1286 		    ESR_N2_PLL_STS_L_REG, &cfg.value);
1287 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1288 		    "==> nxge_n2_serdes_init port<%d>: PLL sts.l 0x%x (0x%x)",
1289 		    portn, pll_sts_l.value, cfg.value));
1290 #endif
1291 
1292 		/* Set loopback mode if necessary */
1293 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
1294 			tx_cfg_l.bits.entest = 1;
1295 			rx_cfg_l.bits.entest = 1;
1296 			test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
1297 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1298 			    "==> nxge_n2_serdes_init port<%d>: loopback 0x%x",
1299 			    portn, test_cfg.value));
1300 			if ((status = nxge_mdio_write(nxgep, portn,
1301 			    ESR_N2_DEV_ADDR,
1302 			    ESR_N2_TEST_CFG_REG, test_cfg.value)) != NXGE_OK) {
1303 				goto fail;
1304 			}
1305 		}
1306 	} else {
1307 		goto fail;
1308 	}
1309 
1310 	/*   MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */
1311 
1312 	NXGE_DELAY(20);
1313 
1314 	/* init TX channels */
1315 	for (chan = 0; chan < 4; chan++) {
1316 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
1317 				ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value))
1318 				!= NXGE_OK)
1319 			goto fail;
1320 
1321 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
1322 				ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value))
1323 				!= NXGE_OK)
1324 			goto fail;
1325 
1326 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1327 		    "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_l 0x%x",
1328 		    portn, chan, tx_cfg_l.value));
1329 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1330 		    "==> nxge_n2_serdes_init port<%d>: chan %d tx_cfg_h 0x%x",
1331 		    portn, chan, tx_cfg_h.value));
1332 	}
1333 
1334 	/* init RX channels */
1335 	for (chan = 0; chan < 4; chan++) {
1336 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
1337 				ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value))
1338 				!= NXGE_OK)
1339 			goto fail;
1340 
1341 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
1342 				ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value))
1343 				!= NXGE_OK)
1344 			goto fail;
1345 
1346 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1347 		    "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_l 0x%x",
1348 		    portn, chan, rx_cfg_l.value));
1349 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1350 		    "==> nxge_n2_serdes_init port<%d>: chan %d rx_cfg_h 0x%x",
1351 		    portn, chan, rx_cfg_h.value));
1352 	}
1353 
1354 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>",
1355 			portn));
1356 
1357 	return (NXGE_OK);
1358 fail:
1359 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1360 	    "nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>",
1361 	    portn));
1362 
1363 	return (status);
1364 }
1365 
1366 /* Initialize the Neptune Internal Serdes for 10G (Neptune only) */
1367 
1368 static nxge_status_t
1369 nxge_neptune_10G_serdes_init(p_nxge_t nxgep)
1370 {
1371 	npi_handle_t		handle;
1372 	uint8_t			portn;
1373 	int			chan;
1374 	sr_rx_tx_ctrl_l_t	rx_tx_ctrl_l;
1375 	sr_rx_tx_ctrl_h_t	rx_tx_ctrl_h;
1376 	sr_glue_ctrl0_l_t	glue_ctrl0_l;
1377 	sr_glue_ctrl0_h_t	glue_ctrl0_h;
1378 	uint64_t		val;
1379 	uint16_t		val16l;
1380 	uint16_t		val16h;
1381 	nxge_status_t		status = NXGE_OK;
1382 
1383 	portn = nxgep->mac.portnum;
1384 
1385 	if ((portn != 0) && (portn != 1))
1386 		return (NXGE_OK);
1387 
1388 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1389 	    "==> nxge_neptune_10G_serdes_init port<%d>", portn));
1390 
1391 	handle = nxgep->npi_handle;
1392 	switch (portn) {
1393 	case 0:
1394 		/* Reset Serdes */
1395 		ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0);
1396 		NXGE_DELAY(20);
1397 		ESR_REG_WR(handle, ESR_RESET_REG, 0x0);
1398 		NXGE_DELAY(2000);
1399 
1400 		/* Configure Serdes to 10G mode */
1401 		ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG,
1402 		    ESR_PLL_CFG_10G_SERDES);
1403 
1404 		ESR_REG_WR(handle, ESR_0_CONTROL_REG,
1405 		    ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
1406 		    ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
1407 		    (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
1408 		    (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
1409 		    (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
1410 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
1411 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
1412 		    (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
1413 		    (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
1414 		    (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
1415 		    (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
1416 
1417 		/* Set Serdes0 Internal Loopback if necessary */
1418 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
1419 			ESR_REG_WR(handle,
1420 			    ESR_0_TEST_CONFIG_REG,
1421 			    ESR_PAD_LOOPBACK_CH3 |
1422 			    ESR_PAD_LOOPBACK_CH2 |
1423 			    ESR_PAD_LOOPBACK_CH1 |
1424 			    ESR_PAD_LOOPBACK_CH0);
1425 		} else {
1426 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0);
1427 		}
1428 		break;
1429 	case 1:
1430 		/* Reset Serdes */
1431 		ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_1);
1432 		NXGE_DELAY(20);
1433 		ESR_REG_WR(handle, ESR_RESET_REG, 0x0);
1434 		NXGE_DELAY(2000);
1435 
1436 		/* Configure Serdes to 10G mode */
1437 		ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG,
1438 		    ESR_PLL_CFG_10G_SERDES);
1439 
1440 		ESR_REG_WR(handle, ESR_1_CONTROL_REG,
1441 		    ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
1442 		    ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
1443 		    (0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
1444 		    (0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
1445 		    (0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
1446 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
1447 		    (0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
1448 		    (0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
1449 		    (0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
1450 		    (0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
1451 		    (0x1 << ESR_CTL_LOSADJ_3_SHIFT));
1452 
1453 		/* Set Serdes1 Internal Loopback if necessary */
1454 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
1455 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG,
1456 			    ESR_PAD_LOOPBACK_CH3 | ESR_PAD_LOOPBACK_CH2 |
1457 			    ESR_PAD_LOOPBACK_CH1 | ESR_PAD_LOOPBACK_CH0);
1458 		} else {
1459 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0);
1460 		}
1461 		break;
1462 	default:
1463 		/* Nothing to do here */
1464 		goto done;
1465 	}
1466 
1467 	/* init TX RX channels */
1468 	for (chan = 0; chan < 4; chan++) {
1469 		if ((status = nxge_mdio_read(nxgep, portn,
1470 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
1471 		    &rx_tx_ctrl_l.value)) != NXGE_OK)
1472 			goto fail;
1473 		if ((status = nxge_mdio_read(nxgep, portn,
1474 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
1475 		    &rx_tx_ctrl_h.value)) != NXGE_OK)
1476 			goto fail;
1477 		if ((status = nxge_mdio_read(nxgep, portn,
1478 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
1479 		    &glue_ctrl0_l.value)) != NXGE_OK)
1480 			goto fail;
1481 		if ((status = nxge_mdio_read(nxgep, portn,
1482 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
1483 		    &glue_ctrl0_h.value)) != NXGE_OK)
1484 			goto fail;
1485 		rx_tx_ctrl_l.bits.enstretch = 1;
1486 		rx_tx_ctrl_h.bits.vmuxlo = 2;
1487 		rx_tx_ctrl_h.bits.vpulselo = 2;
1488 		glue_ctrl0_l.bits.rxlosenable = 1;
1489 		glue_ctrl0_l.bits.samplerate = 0xF;
1490 		glue_ctrl0_l.bits.thresholdcount = 0xFF;
1491 		glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
1492 		if ((status = nxge_mdio_write(nxgep, portn,
1493 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
1494 		    rx_tx_ctrl_l.value)) != NXGE_OK)
1495 			goto fail;
1496 		if ((status = nxge_mdio_write(nxgep, portn,
1497 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
1498 		    rx_tx_ctrl_h.value)) != NXGE_OK)
1499 			goto fail;
1500 		if ((status = nxge_mdio_write(nxgep, portn,
1501 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
1502 		    glue_ctrl0_l.value)) != NXGE_OK)
1503 			goto fail;
1504 		if ((status = nxge_mdio_write(nxgep, portn,
1505 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
1506 		    glue_ctrl0_h.value)) != NXGE_OK)
1507 			goto fail;
1508 		}
1509 
1510 	/* Apply Tx core reset */
1511 	if ((status = nxge_mdio_write(nxgep, portn,
1512 	    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
1513 	    (uint16_t)0)) != NXGE_OK)
1514 		goto fail;
1515 
1516 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
1517 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) !=
1518 	    NXGE_OK)
1519 		goto fail;
1520 
1521 	NXGE_DELAY(200);
1522 
1523 	/* Apply Rx core reset */
1524 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
1525 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) !=
1526 	    NXGE_OK)
1527 		goto fail;
1528 
1529 	NXGE_DELAY(200);
1530 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
1531 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK)
1532 		goto fail;
1533 
1534 	NXGE_DELAY(200);
1535 	if ((status = nxge_mdio_read(nxgep, portn,
1536 	    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
1537 	    &val16l)) != NXGE_OK)
1538 		goto fail;
1539 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
1540 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK)
1541 		goto fail;
1542 	if ((val16l != 0) || (val16h != 0)) {
1543 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1544 		    "Failed to reset port<%d> XAUI Serdes "
1545 		    "(val16l 0x%x val16h 0x%x)",
1546 		    portn, val16l, val16h));
1547 	}
1548 
1549 	ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
1550 
1551 	if (portn == 0) {
1552 		if ((val & ESR_SIG_P0_BITS_MASK) !=
1553 				(ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 |
1554 					ESR_SIG_XSERDES_RDY_P0 |
1555 					ESR_SIG_XDETECT_P0_CH3 |
1556 					ESR_SIG_XDETECT_P0_CH2 |
1557 					ESR_SIG_XDETECT_P0_CH1 |
1558 					ESR_SIG_XDETECT_P0_CH0)) {
1559 			goto fail;
1560 		}
1561 	} else if (portn == 1) {
1562 		if ((val & ESR_SIG_P1_BITS_MASK) !=
1563 				(ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 |
1564 					ESR_SIG_XSERDES_RDY_P1 |
1565 					ESR_SIG_XDETECT_P1_CH3 |
1566 					ESR_SIG_XDETECT_P1_CH2 |
1567 					ESR_SIG_XDETECT_P1_CH1 |
1568 					ESR_SIG_XDETECT_P1_CH0)) {
1569 			goto fail;
1570 		}
1571 	}
1572 
1573 done:
1574 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1575 	    "<== nxge_neptune_10G_serdes_init port<%d>", portn));
1576 
1577 	return (NXGE_OK);
1578 fail:
1579 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1580 	    "nxge_neptune_10G_serdes_init: "
1581 	    "Failed to initialize Neptune serdes for port<%d>", portn));
1582 
1583 	return (status);
1584 }
1585 
1586 /* Initialize Neptune Internal Serdes for 1G (Neptune only) */
1587 
1588 static nxge_status_t
1589 nxge_1G_serdes_init(p_nxge_t nxgep)
1590 {
1591 	npi_handle_t		handle;
1592 	uint8_t			portn;
1593 	int			chan;
1594 	sr_rx_tx_ctrl_l_t	rx_tx_ctrl_l;
1595 	sr_rx_tx_ctrl_h_t	rx_tx_ctrl_h;
1596 	sr_glue_ctrl0_l_t	glue_ctrl0_l;
1597 	sr_glue_ctrl0_h_t	glue_ctrl0_h;
1598 	uint64_t		val;
1599 	uint16_t		val16l;
1600 	uint16_t		val16h;
1601 	nxge_status_t		status = NXGE_OK;
1602 
1603 	portn = nxgep->mac.portnum;
1604 
1605 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1606 	    "==> nxge_1G_serdes_init port<%d>", portn));
1607 
1608 	handle = nxgep->npi_handle;
1609 
1610 	switch (portn) {
1611 	case 0:
1612 		/* Assert the reset register */
1613 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
1614 		val |= ESR_RESET_0;
1615 		ESR_REG_WR(handle, ESR_RESET_REG, val);
1616 
1617 		/* Set the PLL register to 0x79 */
1618 		ESR_REG_WR(handle, ESR_0_PLL_CONFIG_REG,
1619 		    ESR_PLL_CFG_1G_SERDES);
1620 
1621 		/* Set the control register to 0x249249f */
1622 		ESR_REG_WR(handle, ESR_0_CONTROL_REG, ESR_CTL_1G_SERDES);
1623 
1624 		/* Set Serdes0 Internal Loopback if necessary */
1625 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
1626 			/* Set pad loopback modes 0xaa */
1627 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG,
1628 			    ESR_TSTCFG_LBTEST_PAD);
1629 		} else {
1630 			ESR_REG_WR(handle, ESR_0_TEST_CONFIG_REG, 0);
1631 		}
1632 
1633 		/* Deassert the reset register */
1634 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
1635 		val &= ~ESR_RESET_0;
1636 		ESR_REG_WR(handle, ESR_RESET_REG, val);
1637 		break;
1638 
1639 	case 1:
1640 		/* Assert the reset register */
1641 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
1642 		val |= ESR_RESET_1;
1643 		ESR_REG_WR(handle, ESR_RESET_REG, val);
1644 
1645 		/* Set PLL register to 0x79 */
1646 		ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG,
1647 		    ESR_PLL_CFG_1G_SERDES);
1648 
1649 		/* Set the control register to 0x249249f */
1650 		ESR_REG_WR(handle, ESR_1_CONTROL_REG, ESR_CTL_1G_SERDES);
1651 
1652 		/* Set Serdes1 Internal Loopback if necessary */
1653 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes1000) {
1654 			/* Set pad loopback mode 0xaa */
1655 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG,
1656 			    ESR_TSTCFG_LBTEST_PAD);
1657 		} else {
1658 			ESR_REG_WR(handle, ESR_1_TEST_CONFIG_REG, 0);
1659 		}
1660 
1661 		/* Deassert the reset register */
1662 		ESR_REG_RD(handle, ESR_RESET_REG, &val);
1663 		val &= ~ESR_RESET_1;
1664 		ESR_REG_WR(handle, ESR_RESET_REG, val);
1665 		break;
1666 
1667 	default:
1668 		/* Nothing to do here */
1669 		goto done;
1670 	}
1671 
1672 	/* init TX RX channels */
1673 	for (chan = 0; chan < 4; chan++) {
1674 		if ((status = nxge_mdio_read(nxgep, portn,
1675 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
1676 		    &rx_tx_ctrl_l.value)) != NXGE_OK) {
1677 			goto fail;
1678 		}
1679 		if ((status = nxge_mdio_read(nxgep, portn,
1680 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
1681 		    &rx_tx_ctrl_h.value)) != NXGE_OK) {
1682 			goto fail;
1683 		}
1684 		if ((status = nxge_mdio_read(nxgep, portn,
1685 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
1686 		    &glue_ctrl0_l.value)) != NXGE_OK) {
1687 			goto fail;
1688 		}
1689 		if ((status = nxge_mdio_read(nxgep, portn,
1690 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
1691 		    &glue_ctrl0_h.value)) != NXGE_OK) {
1692 			goto fail;
1693 		}
1694 
1695 		rx_tx_ctrl_l.bits.enstretch = 1;
1696 		rx_tx_ctrl_h.bits.vmuxlo = 2;
1697 		rx_tx_ctrl_h.bits.vpulselo = 2;
1698 		glue_ctrl0_l.bits.rxlosenable = 1;
1699 		glue_ctrl0_l.bits.samplerate = 0xF;
1700 		glue_ctrl0_l.bits.thresholdcount = 0xFF;
1701 		glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
1702 		if ((status = nxge_mdio_write(nxgep, portn,
1703 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
1704 		    rx_tx_ctrl_l.value)) != NXGE_OK) {
1705 			goto fail;
1706 		}
1707 		if ((status = nxge_mdio_write(nxgep, portn,
1708 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
1709 		    rx_tx_ctrl_h.value)) != NXGE_OK) {
1710 			goto fail;
1711 		}
1712 		if ((status = nxge_mdio_write(nxgep, portn,
1713 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
1714 		    glue_ctrl0_l.value)) != NXGE_OK) {
1715 			goto fail;
1716 		}
1717 		if ((status = nxge_mdio_write(nxgep, portn,
1718 		    ESR_NEPTUNE_DEV_ADDR, ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
1719 		    glue_ctrl0_h.value)) != NXGE_OK) {
1720 			goto fail;
1721 		}
1722 	}
1723 
1724 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
1725 	    ESR_NEP_RX_POWER_CONTROL_L_ADDR(), 0xfff)) != NXGE_OK) {
1726 		goto fail;
1727 	}
1728 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
1729 	    ESR_NEP_RX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) {
1730 		goto fail;
1731 	}
1732 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
1733 	    ESR_NEP_TX_POWER_CONTROL_L_ADDR(), 0x70)) != NXGE_OK) {
1734 		goto fail;
1735 	}
1736 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
1737 	    ESR_NEP_TX_POWER_CONTROL_H_ADDR(), 0xfff)) != NXGE_OK) {
1738 		goto fail;
1739 	}
1740 
1741 	/* Apply Tx core reset */
1742 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
1743 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0)) != NXGE_OK) {
1744 		goto fail;
1745 	}
1746 
1747 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
1748 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0xffff)) !=
1749 	    NXGE_OK) {
1750 		goto fail;
1751 	}
1752 
1753 	NXGE_DELAY(200);
1754 
1755 	/* Apply Rx core reset */
1756 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
1757 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), (uint16_t)0xffff)) !=
1758 	    NXGE_OK) {
1759 		goto fail;
1760 	}
1761 
1762 	NXGE_DELAY(200);
1763 	if ((status = nxge_mdio_write(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
1764 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), (uint16_t)0)) != NXGE_OK) {
1765 		goto fail;
1766 	}
1767 
1768 	NXGE_DELAY(200);
1769 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
1770 	    ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(), &val16l)) != NXGE_OK) {
1771 		goto fail;
1772 	}
1773 	if ((status = nxge_mdio_read(nxgep, portn, ESR_NEPTUNE_DEV_ADDR,
1774 	    ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(), &val16h)) != NXGE_OK) {
1775 		goto fail;
1776 	}
1777 	if ((val16l != 0) || (val16h != 0)) {
1778 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1779 		    "Failed to reset port<%d> XAUI Serdes "
1780 		    "(val16l 0x%x val16h 0x%x)", portn, val16l, val16h));
1781 		status = NXGE_ERROR;
1782 		goto fail;
1783 	}
1784 
1785 	NXGE_DELAY(200);
1786 	ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
1787 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1788 	    "nxge_neptune_serdes_init: read internal signal reg port<%d> "
1789 	    "val 0x%x", portn, val));
1790 	if (portn == 0) {
1791 		if ((val & ESR_SIG_P0_BITS_MASK_1G) !=
1792 		    (ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0)) {
1793 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1794 			    "nxge_neptune_serdes_init: "
1795 			    "Failed to get Serdes up for port<%d> val 0x%x",
1796 			    portn, (val & ESR_SIG_P0_BITS_MASK)));
1797 			status = NXGE_ERROR;
1798 			goto fail;
1799 		}
1800 	} else if (portn == 1) {
1801 		if ((val & ESR_SIG_P1_BITS_MASK_1G) !=
1802 		    (ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1)) {
1803 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1804 			    "nxge_neptune_serdes_init: "
1805 			    "Failed to get Serdes up for port<%d> val 0x%x",
1806 			    portn, (val & ESR_SIG_P1_BITS_MASK)));
1807 			status = NXGE_ERROR;
1808 			goto fail;
1809 		}
1810 	}
1811 done:
1812 
1813 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1814 	    "<== nxge_1G_serdes_init port<%d>", portn));
1815 	return (NXGE_OK);
1816 fail:
1817 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1818 	    "nxge_1G_serdes_init: "
1819 	    "Failed to initialize Neptune serdes for port<%d>",
1820 	    portn));
1821 
1822 	return (status);
1823 }
1824 
1825 /* Initialize the BCM 8704 xcvr */
1826 
1827 static nxge_status_t
1828 nxge_BCM8704_xcvr_init(p_nxge_t nxgep)
1829 {
1830 	uint16_t		val;
1831 #ifdef	NXGE_DEBUG
1832 	uint8_t			portn;
1833 	uint16_t		val1;
1834 #endif
1835 	uint8_t			phy_port_addr;
1836 	pmd_tx_control_t	tx_ctl;
1837 	control_t		ctl;
1838 	phyxs_control_t		phyxs_ctl;
1839 	pcs_control_t		pcs_ctl;
1840 	uint32_t		delay = 0;
1841 	optics_dcntr_t		op_ctr;
1842 	nxge_status_t		status = NXGE_OK;
1843 #ifdef	NXGE_DEBUG
1844 	portn = nxgep->mac.portnum;
1845 #endif
1846 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>",
1847 	    portn));
1848 
1849 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
1850 
1851 	/* Reset the transceiver */
1852 	if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
1853 	    BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK)
1854 		goto fail;
1855 
1856 	phyxs_ctl.bits.reset = 1;
1857 	if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
1858 	    BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK)
1859 		goto fail;
1860 
1861 	do {
1862 		drv_usecwait(500);
1863 		if ((status = nxge_mdio_read(nxgep, phy_port_addr,
1864 		    BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG,
1865 		    &phyxs_ctl.value)) != NXGE_OK)
1866 			goto fail;
1867 		delay++;
1868 	} while ((phyxs_ctl.bits.reset) && (delay < 100));
1869 	if (delay == 100) {
1870 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
1871 		    "failed to reset Transceiver on port<%d>", portn));
1872 		status = NXGE_ERROR;
1873 		goto fail;
1874 	}
1875 
1876 	/* Set to 0x7FBF */
1877 	ctl.value = 0;
1878 	ctl.bits.res1 = 0x3F;
1879 	ctl.bits.optxon_lvl = 1;
1880 	ctl.bits.oprxflt_lvl = 1;
1881 	ctl.bits.optrxlos_lvl = 1;
1882 	ctl.bits.optxflt_lvl = 1;
1883 	ctl.bits.opprflt_lvl = 1;
1884 	ctl.bits.obtmpflt_lvl = 1;
1885 	ctl.bits.opbiasflt_lvl = 1;
1886 	ctl.bits.optxrst_lvl = 1;
1887 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
1888 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, ctl.value))
1889 	    != NXGE_OK)
1890 		goto fail;
1891 
1892 	/* Set to 0x164 */
1893 	tx_ctl.value = 0;
1894 	tx_ctl.bits.tsck_lpwren = 1;
1895 	tx_ctl.bits.tx_dac_txck = 0x2;
1896 	tx_ctl.bits.tx_dac_txd = 0x1;
1897 	tx_ctl.bits.xfp_clken = 1;
1898 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
1899 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG,
1900 	    tx_ctl.value)) != NXGE_OK)
1901 		goto fail;
1902 	/*
1903 	 * According to Broadcom's instruction, SW needs to read
1904 	 * back these registers twice after written.
1905 	 */
1906 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
1907 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
1908 	    != NXGE_OK)
1909 		goto fail;
1910 
1911 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
1912 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_CONTROL_REG, &val))
1913 	    != NXGE_OK)
1914 		goto fail;
1915 
1916 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
1917 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
1918 	    != NXGE_OK)
1919 		goto fail;
1920 
1921 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
1922 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_PMD_TX_CONTROL_REG, &val))
1923 	    != NXGE_OK)
1924 		goto fail;
1925 
1926 	/* Enable Tx and Rx LEDs to be driven by traffic */
1927 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
1928 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
1929 	    &op_ctr.value)) != NXGE_OK)
1930 		goto fail;
1931 	if (NXGE_IS_XAUI_PLATFORM(nxgep)) {
1932 		op_ctr.bits.gpio_sel = 0x1;
1933 	} else {
1934 		op_ctr.bits.gpio_sel = 0x3;
1935 	}
1936 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
1937 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
1938 	    op_ctr.value)) != NXGE_OK)
1939 		goto fail;
1940 
1941 	NXGE_DELAY(1000000);
1942 
1943 	/* Set BCM8704 Internal Loopback mode if necessary */
1944 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
1945 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value))
1946 	    != NXGE_OK)
1947 		goto fail;
1948 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
1949 		pcs_ctl.bits.loopback = 1;
1950 	else
1951 		pcs_ctl.bits.loopback = 0;
1952 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
1953 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value))
1954 	    != NXGE_OK)
1955 		goto fail;
1956 
1957 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x1, 0xA, &val);
1958 	if (status != NXGE_OK)
1959 		goto fail;
1960 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1961 	    "BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n", portn, val));
1962 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val);
1963 	if (status != NXGE_OK)
1964 		goto fail;
1965 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1966 	    "BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n", portn, val));
1967 	status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val);
1968 	if (status != NXGE_OK)
1969 		goto fail;
1970 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1971 	    "BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n", portn, val));
1972 
1973 #ifdef	NXGE_DEBUG
1974 	/* Diagnose link issue if link is not up */
1975 	status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_USER_DEV3_ADDR,
1976 	    BCM8704_USER_ANALOG_STATUS0_REG,
1977 	    &val);
1978 	if (status != NXGE_OK)
1979 		goto fail;
1980 
1981 	status = nxge_mdio_read(nxgep, phy_port_addr,
1982 				BCM8704_USER_DEV3_ADDR,
1983 				BCM8704_USER_ANALOG_STATUS0_REG,
1984 				&val);
1985 	if (status != NXGE_OK)
1986 		goto fail;
1987 
1988 	status = nxge_mdio_read(nxgep, phy_port_addr,
1989 				BCM8704_USER_DEV3_ADDR,
1990 				BCM8704_USER_TX_ALARM_STATUS_REG,
1991 				&val1);
1992 	if (status != NXGE_OK)
1993 		goto fail;
1994 
1995 	status = nxge_mdio_read(nxgep, phy_port_addr,
1996 				BCM8704_USER_DEV3_ADDR,
1997 				BCM8704_USER_TX_ALARM_STATUS_REG,
1998 				&val1);
1999 	if (status != NXGE_OK)
2000 		goto fail;
2001 
2002 	if (val != 0x3FC) {
2003 		if ((val == 0x43BC) && (val1 != 0)) {
2004 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2005 			    "Cable not connected to peer or bad"
2006 			    " cable on port<%d>\n", portn));
2007 		} else if (val == 0x639C) {
2008 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2009 			    "Optical module (XFP) is bad or absent"
2010 			    " on port<%d>\n", portn));
2011 		}
2012 	}
2013 #endif
2014 
2015 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8704_xcvr_init: port<%d>",
2016 	    portn));
2017 	return (NXGE_OK);
2018 
2019 fail:
2020 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2021 	    "nxge_BCM8704_xcvr_init: failed to initialize transceiver for "
2022 	    "port<%d>", nxgep->mac.portnum));
2023 	return (NXGE_ERROR);
2024 }
2025 
2026 /* Initialize the BCM 8706 Transceiver */
2027 
2028 static nxge_status_t
2029 nxge_BCM8706_xcvr_init(p_nxge_t nxgep)
2030 {
2031 	uint8_t			phy_port_addr;
2032 	phyxs_control_t		phyxs_ctl;
2033 	pcs_control_t		pcs_ctl;
2034 	uint32_t		delay = 0;
2035 	optics_dcntr_t		op_ctr;
2036 	nxge_status_t		status = NXGE_OK;
2037 #ifdef	NXGE_DEBUG
2038 	uint8_t			portn = nxgep->mac.portnum;
2039 #endif
2040 
2041 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>",
2042 	    portn));
2043 
2044 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
2045 
2046 	/* Reset the transceiver */
2047 	if ((status = nxge_mdio_read(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
2048 	    BCM8704_PHYXS_CONTROL_REG, &phyxs_ctl.value)) != NXGE_OK)
2049 		goto fail;
2050 
2051 	phyxs_ctl.bits.reset = 1;
2052 	if ((status = nxge_mdio_write(nxgep, phy_port_addr, BCM8704_PHYXS_ADDR,
2053 	    BCM8704_PHYXS_CONTROL_REG, phyxs_ctl.value)) != NXGE_OK)
2054 		goto fail;
2055 	do {
2056 		drv_usecwait(500);
2057 		if ((status = nxge_mdio_read(nxgep, phy_port_addr,
2058 		    BCM8704_PHYXS_ADDR, BCM8704_PHYXS_CONTROL_REG,
2059 		    &phyxs_ctl.value)) != NXGE_OK)
2060 			goto fail;
2061 		delay++;
2062 	} while ((phyxs_ctl.bits.reset) && (delay < 100));
2063 
2064 	if (delay == 100) {
2065 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
2066 		    "failed to reset Transceiver on port<%d>", portn));
2067 		status = NXGE_ERROR;
2068 		goto fail;
2069 	}
2070 
2071 	NXGE_DELAY(1000000);
2072 
2073 	/* Set BCM8706 Internal Loopback mode if necessary */
2074 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
2075 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, &pcs_ctl.value))
2076 	    != NXGE_OK)
2077 		goto fail;
2078 	if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
2079 		pcs_ctl.bits.loopback = 1;
2080 	else
2081 		pcs_ctl.bits.loopback = 0;
2082 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
2083 	    BCM8704_PCS_DEV_ADDR, BCM8704_PCS_CONTROL_REG, pcs_ctl.value))
2084 	    != NXGE_OK)
2085 		goto fail;
2086 
2087 	/* Enable Tx and Rx LEDs to be driven by traffic */
2088 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
2089 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
2090 	    &op_ctr.value)) != NXGE_OK)
2091 		goto fail;
2092 	op_ctr.bits.gpio_sel = 0x3;
2093 	op_ctr.bits.res2 = 0x1;
2094 
2095 	if ((status = nxge_mdio_write(nxgep, phy_port_addr,
2096 	    BCM8704_USER_DEV3_ADDR, BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
2097 	    op_ctr.value)) != NXGE_OK)
2098 		goto fail;
2099 
2100 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_BCM8706_xcvr_init: port<%d>",
2101 	    portn));
2102 	return (NXGE_OK);
2103 
2104 fail:
2105 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2106 	    "nxge_BCM8706_xcvr_init: failed to initialize transceiver for "
2107 	    "port<%d>", nxgep->mac.portnum));
2108 	return (status);
2109 }
2110 
2111 /* Initialize the 10G Transceiver */
2112 
2113 static nxge_status_t
2114 nxge_10G_xcvr_init(p_nxge_t nxgep)
2115 {
2116 	p_nxge_stats_t		statsp;
2117 	nxge_status_t		status = NXGE_OK;
2118 #ifdef	NXGE_DEBUG
2119 	uint8_t			portn = nxgep->mac.portnum;
2120 #endif
2121 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
2122 	    portn));
2123 
2124 	statsp = nxgep->statsp;
2125 
2126 	if (nxgep->mac.portmode == PORT_10G_SERDES) {
2127 		goto done;
2128 	}
2129 
2130 	/* Disable Link LEDs */
2131 	if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
2132 		goto fail;
2133 
2134 	/* Set Clause 45 */
2135 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
2136 
2137 	switch (nxgep->chip_id) {
2138 	case BCM8704_CHIP_ID:
2139 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
2140 		    "Chip ID 8704 [0x%x] for 10G xcvr", nxgep->chip_id));
2141 		status = nxge_BCM8704_xcvr_init(nxgep);
2142 		break;
2143 	case BCM8706_CHIP_ID:
2144 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "nxge_xcvr_init: "
2145 		    "Chip ID 8706 [0x%x] for 10G xcvr", nxgep->chip_id));
2146 		status = nxge_BCM8706_xcvr_init(nxgep);
2147 		break;
2148 	default:
2149 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_xcvr_init: "
2150 		    "Unknown chip ID 0x%x for 10G xcvr addr[%d]",
2151 		    nxgep->chip_id, nxgep->statsp->mac_stats.xcvr_portn));
2152 		goto fail;
2153 	}
2154 
2155 	if (status != NXGE_OK) {
2156 		goto fail;
2157 	}
2158 done:
2159 	statsp->mac_stats.cap_10gfdx = 1;
2160 	statsp->mac_stats.lp_cap_10gfdx = 1;
2161 
2162 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_10G_xcvr_init: port<%d>",
2163 	    portn));
2164 	return (NXGE_OK);
2165 
2166 fail:
2167 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2168 	    "nxge_10G_xcvr_init: failed to initialize transceiver for "
2169 	    "port<%d>", nxgep->mac.portnum));
2170 	return (NXGE_ERROR);
2171 }
2172 
2173 /* Initialize the 1G copper (BCM 5464) Transceiver */
2174 
2175 static nxge_status_t
2176 nxge_1G_xcvr_init(p_nxge_t nxgep)
2177 {
2178 	p_nxge_param_t		param_arr = nxgep->param_arr;
2179 	p_nxge_stats_t		statsp = nxgep->statsp;
2180 	nxge_status_t		status = NXGE_OK;
2181 
2182 	if (nxgep->mac.portmode == PORT_1G_SERDES) {
2183 		statsp->mac_stats.cap_1000fdx =
2184 		    param_arr[param_anar_1000fdx].value;
2185 		goto done;
2186 	}
2187 
2188 	/* Set Clause 22 */
2189 	npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE);
2190 
2191 	/* Set capability flags */
2192 	statsp->mac_stats.cap_1000fdx = param_arr[param_anar_1000fdx].value;
2193 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
2194 	    (nxgep->mac.portmode == PORT_1G_FIBER)) {
2195 		statsp->mac_stats.cap_100fdx =
2196 		    param_arr[param_anar_100fdx].value;
2197 		statsp->mac_stats.cap_10fdx =
2198 		    param_arr[param_anar_10fdx].value;
2199 	}
2200 
2201 	status = nxge_mii_xcvr_init(nxgep);
2202 done:
2203 	return (status);
2204 }
2205 
2206 /* Initialize transceiver */
2207 
2208 nxge_status_t
2209 nxge_xcvr_init(p_nxge_t nxgep)
2210 {
2211 	p_nxge_stats_t		statsp;
2212 #ifdef	NXGE_DEBUG
2213 	uint8_t			portn;
2214 #endif
2215 
2216 	nxge_status_t		status = NXGE_OK;
2217 #ifdef	NXGE_DEBUG
2218 	portn = nxgep->mac.portnum;
2219 #endif
2220 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn));
2221 	statsp = nxgep->statsp;
2222 
2223 	/*
2224 	 * Initialize the xcvr statistics.
2225 	 */
2226 	statsp->mac_stats.cap_autoneg = 0;
2227 	statsp->mac_stats.cap_100T4 = 0;
2228 	statsp->mac_stats.cap_100fdx = 0;
2229 	statsp->mac_stats.cap_100hdx = 0;
2230 	statsp->mac_stats.cap_10fdx = 0;
2231 	statsp->mac_stats.cap_10hdx = 0;
2232 	statsp->mac_stats.cap_asmpause = 0;
2233 	statsp->mac_stats.cap_pause = 0;
2234 	statsp->mac_stats.cap_1000fdx = 0;
2235 	statsp->mac_stats.cap_1000hdx = 0;
2236 	statsp->mac_stats.cap_10gfdx = 0;
2237 	statsp->mac_stats.cap_10ghdx = 0;
2238 
2239 	/*
2240 	 * Initialize the link statistics.
2241 	 */
2242 	statsp->mac_stats.link_T4 = 0;
2243 	statsp->mac_stats.link_asmpause = 0;
2244 	statsp->mac_stats.link_pause = 0;
2245 
2246 	if (nxgep->xcvr.xcvr_init) {
2247 		status = nxgep->xcvr.xcvr_init(nxgep);
2248 		if (status != NXGE_OK)
2249 			goto fail;
2250 		statsp->mac_stats.xcvr_inits++;
2251 	}
2252 
2253 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>",
2254 	    portn));
2255 	return (NXGE_OK);
2256 
2257 fail:
2258 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2259 	    "nxge_xcvr_init: failed to initialize transceiver for port<%d>",
2260 	    portn));
2261 	return (status);
2262 }
2263 
2264 /* Look for transceiver type */
2265 
2266 nxge_status_t
2267 nxge_xcvr_find(p_nxge_t nxgep)
2268 {
2269 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_find: port<%d>",
2270 	    nxgep->mac.portnum));
2271 
2272 	if (nxge_get_xcvr_type(nxgep) != NXGE_OK)
2273 		return (NXGE_ERROR);
2274 
2275 	if (nxge_setup_xcvr_table(nxgep) != NXGE_OK)
2276 		return (NXGE_ERROR);
2277 
2278 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xcvr_find: xcvr_inuse = %d",
2279 	    nxgep->statsp->mac_stats.xcvr_inuse));
2280 	return (NXGE_OK);
2281 }
2282 
2283 /* Initialize the TxMAC sub-block */
2284 
2285 nxge_status_t
2286 nxge_tx_mac_init(p_nxge_t nxgep)
2287 {
2288 	npi_attr_t		ap;
2289 	uint8_t			portn;
2290 	nxge_port_mode_t	portmode;
2291 	nxge_port_t		portt;
2292 	npi_handle_t		handle;
2293 	npi_status_t		rs = NPI_SUCCESS;
2294 
2295 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
2296 	portt    = nxgep->mac.porttype;
2297 	handle   = nxgep->npi_handle;
2298 	portmode = nxgep->mac.portmode;
2299 
2300 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>",
2301 			portn));
2302 
2303 	/* Set Max and Min Frame Size */
2304 	if (nxgep->param_arr[param_accept_jumbo].value || nxge_jumbo_enable) {
2305 		SET_MAC_ATTR2(handle, ap, portn,
2306 		    MAC_PORT_FRAME_SIZE, 64, nxge_jumbo_mtu, rs);
2307 	} else {
2308 		/*
2309 		 * Set the maxframe size to 1522 (1518 + 4) to account for
2310 		 * VLAN tagged packets
2311 		 */
2312 		SET_MAC_ATTR2(handle, ap, portn,
2313 		    MAC_PORT_FRAME_SIZE, 64, 0x5EE + 4, rs);
2314 	}
2315 
2316 	if (rs != NPI_SUCCESS)
2317 		goto fail;
2318 	if (nxgep->param_arr[param_accept_jumbo].value ||
2319 		nxgep->mac.is_jumbo == B_TRUE)
2320 		nxgep->mac.maxframesize = (uint16_t)nxge_jumbo_mtu;
2321 	else
2322 		nxgep->mac.maxframesize = 0x5EE + 4;
2323 	nxgep->mac.minframesize = 64;
2324 
2325 	if (portt == PORT_TYPE_XMAC) {
2326 		if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn,
2327 				0)) != NPI_SUCCESS)
2328 			goto fail;
2329 		nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS;
2330 		if ((portmode == PORT_10G_FIBER) ||
2331 		    (portmode == PORT_10G_COPPER) ||
2332 		    (portmode == PORT_10G_SERDES)) {
2333 			SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG,
2334 					XGMII_IPG_12_15, rs);
2335 			if (rs != NPI_SUCCESS)
2336 				goto fail;
2337 			nxgep->mac.ipg[0] = XGMII_IPG_12_15;
2338 		} else {
2339 			SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG,
2340 					MII_GMII_IPG_12, rs);
2341 			if (rs != NPI_SUCCESS)
2342 				goto fail;
2343 			nxgep->mac.ipg[0] = MII_GMII_IPG_12;
2344 		}
2345 		if ((rs = npi_xmac_tx_config(handle, INIT, portn,
2346 				CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS)
2347 			goto fail;
2348 		nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX;
2349 		nxgep->mac.maxburstsize = 0;	/* not programmable */
2350 		nxgep->mac.ctrltype = 0;	/* not programmable */
2351 		nxgep->mac.pa_size = 0;		/* not programmable */
2352 
2353 		if ((rs = npi_xmac_zap_tx_counters(handle, portn))
2354 							!= NPI_SUCCESS)
2355 			goto fail;
2356 
2357 	} else {
2358 		if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn,
2359 				0)) != NPI_SUCCESS)
2360 			goto fail;
2361 		nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS;
2362 
2363 		SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808,
2364 				rs);
2365 		if (rs != NPI_SUCCESS)
2366 			goto fail;
2367 		nxgep->mac.ctrltype = 0x8808;
2368 
2369 		SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs);
2370 		if (rs != NPI_SUCCESS)
2371 			goto fail;
2372 		nxgep->mac.pa_size = 0x7;
2373 
2374 		if ((rs = npi_bmac_tx_config(handle, INIT, portn,
2375 				CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS)
2376 			goto fail;
2377 		nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX;
2378 	}
2379 
2380 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>",
2381 			portn));
2382 
2383 	return (NXGE_OK);
2384 fail:
2385 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2386 		"nxge_tx_mac_init: failed to initialize port<%d> TXMAC",
2387 					portn));
2388 
2389 	return (NXGE_ERROR | rs);
2390 }
2391 
2392 /* Initialize the RxMAC sub-block */
2393 
2394 nxge_status_t
2395 nxge_rx_mac_init(p_nxge_t nxgep)
2396 {
2397 	npi_attr_t		ap;
2398 	uint32_t		i;
2399 	uint16_t		hashtab_e;
2400 	p_hash_filter_t		hash_filter;
2401 	nxge_port_t		portt;
2402 	uint8_t			portn;
2403 	npi_handle_t		handle;
2404 	npi_status_t		rs = NPI_SUCCESS;
2405 	uint16_t 		*addr16p;
2406 	uint16_t 		addr0, addr1, addr2;
2407 	xmac_rx_config_t	xconfig;
2408 	bmac_rx_config_t	bconfig;
2409 
2410 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
2411 
2412 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n",
2413 			portn));
2414 	handle = nxgep->npi_handle;
2415 	portt = nxgep->mac.porttype;
2416 
2417 	addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet;
2418 	addr0 = ntohs(addr16p[2]);
2419 	addr1 = ntohs(addr16p[1]);
2420 	addr2 = ntohs(addr16p[0]);
2421 	SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR, addr0, addr1, addr2,
2422 		rs);
2423 
2424 	if (rs != NPI_SUCCESS)
2425 		goto fail;
2426 	SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs);
2427 	if (rs != NPI_SUCCESS)
2428 		goto fail;
2429 	SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs);
2430 	if (rs != NPI_SUCCESS)
2431 		goto fail;
2432 
2433 	/*
2434 	 * Load the multicast hash filter bits.
2435 	 */
2436 	hash_filter = nxgep->hash_filter;
2437 	for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) {
2438 		if (hash_filter != NULL) {
2439 			hashtab_e = (uint16_t)hash_filter->hash_filter_regs[
2440 				(NMCFILTER_REGS - 1) - i];
2441 		} else {
2442 			hashtab_e = 0;
2443 		}
2444 
2445 		if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i,
2446 					(uint16_t *)&hashtab_e)) != NPI_SUCCESS)
2447 			goto fail;
2448 	}
2449 
2450 	if (portt == PORT_TYPE_XMAC) {
2451 		if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn,
2452 				0)) != NPI_SUCCESS)
2453 			goto fail;
2454 		nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS;
2455 
2456 		(void) nxge_fflp_init_hostinfo(nxgep);
2457 
2458 		xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK |
2459 			CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK &
2460 			~CFG_XMAC_RX_STRIP_CRC;
2461 
2462 		if (nxgep->filter.all_phys_cnt != 0)
2463 			xconfig |= CFG_XMAC_RX_PROMISCUOUS;
2464 
2465 		if (nxgep->filter.all_multicast_cnt != 0)
2466 			xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP;
2467 
2468 		xconfig |= CFG_XMAC_RX_HASH_FILTER;
2469 
2470 		if ((rs = npi_xmac_rx_config(handle, INIT, portn,
2471 					xconfig)) != NPI_SUCCESS)
2472 			goto fail;
2473 		nxgep->mac.rx_config = xconfig;
2474 
2475 		/* Comparison of mac unique address is always enabled on XMAC */
2476 
2477 		if ((rs = npi_xmac_zap_rx_counters(handle, portn))
2478 							!= NPI_SUCCESS)
2479 			goto fail;
2480 	} else {
2481 		(void) nxge_fflp_init_hostinfo(nxgep);
2482 
2483 		if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn,
2484 					0) != NPI_SUCCESS)
2485 			goto fail;
2486 		nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS;
2487 
2488 		bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX &
2489 			~CFG_BMAC_RX_STRIP_CRC;
2490 
2491 		if (nxgep->filter.all_phys_cnt != 0)
2492 			bconfig |= CFG_BMAC_RX_PROMISCUOUS;
2493 
2494 		if (nxgep->filter.all_multicast_cnt != 0)
2495 			bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP;
2496 
2497 		bconfig |= CFG_BMAC_RX_HASH_FILTER;
2498 		if ((rs = npi_bmac_rx_config(handle, INIT, portn,
2499 					bconfig)) != NPI_SUCCESS)
2500 			goto fail;
2501 		nxgep->mac.rx_config = bconfig;
2502 
2503 		/* Always enable comparison of mac unique address */
2504 		if ((rs = npi_mac_altaddr_enable(handle, portn, 0))
2505 					!= NPI_SUCCESS)
2506 			goto fail;
2507 	}
2508 
2509 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n",
2510 			portn));
2511 
2512 	return (NXGE_OK);
2513 
2514 fail:
2515 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2516 		"nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC",
2517 				portn));
2518 
2519 	return (NXGE_ERROR | rs);
2520 }
2521 
2522 /* Enable TXMAC */
2523 
2524 nxge_status_t
2525 nxge_tx_mac_enable(p_nxge_t nxgep)
2526 {
2527 	npi_handle_t	handle;
2528 	npi_status_t	rs = NPI_SUCCESS;
2529 	nxge_status_t	status = NXGE_OK;
2530 
2531 	handle = nxgep->npi_handle;
2532 
2533 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>",
2534 			nxgep->mac.portnum));
2535 
2536 	if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
2537 		goto fail;
2538 
2539 	/* based on speed */
2540 	nxgep->msg_min = ETHERMIN;
2541 
2542 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
2543 		if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
2544 						CFG_XMAC_TX)) != NPI_SUCCESS)
2545 			goto fail;
2546 	} else {
2547 		if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
2548 						CFG_BMAC_TX)) != NPI_SUCCESS)
2549 			goto fail;
2550 	}
2551 
2552 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>",
2553 			nxgep->mac.portnum));
2554 
2555 	return (NXGE_OK);
2556 fail:
2557 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2558 			"nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC",
2559 			nxgep->mac.portnum));
2560 	if (rs != NPI_SUCCESS)
2561 		return (NXGE_ERROR | rs);
2562 	else
2563 		return (status);
2564 }
2565 
2566 /* Disable TXMAC */
2567 
2568 nxge_status_t
2569 nxge_tx_mac_disable(p_nxge_t nxgep)
2570 {
2571 	npi_handle_t	handle;
2572 	npi_status_t	rs = NPI_SUCCESS;
2573 
2574 	handle = nxgep->npi_handle;
2575 
2576 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>",
2577 			nxgep->mac.portnum));
2578 
2579 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
2580 		if ((rs = npi_xmac_tx_config(handle, DISABLE,
2581 			nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS)
2582 			goto fail;
2583 	} else {
2584 		if ((rs = npi_bmac_tx_config(handle, DISABLE,
2585 			nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS)
2586 			goto fail;
2587 	}
2588 
2589 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>",
2590 			nxgep->mac.portnum));
2591 	return (NXGE_OK);
2592 fail:
2593 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2594 			"nxge_tx_mac_disable: Failed to disable port<%d> TxMAC",
2595 			nxgep->mac.portnum));
2596 	return (NXGE_ERROR | rs);
2597 }
2598 
2599 /* Enable RXMAC */
2600 
2601 nxge_status_t
2602 nxge_rx_mac_enable(p_nxge_t nxgep)
2603 {
2604 	npi_handle_t	handle;
2605 	uint8_t 	portn;
2606 	npi_status_t	rs = NPI_SUCCESS;
2607 	nxge_status_t	status = NXGE_OK;
2608 
2609 	handle = nxgep->npi_handle;
2610 	portn = nxgep->mac.portnum;
2611 
2612 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>",
2613 			portn));
2614 
2615 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
2616 		goto fail;
2617 
2618 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
2619 		if ((rs = npi_xmac_rx_config(handle, ENABLE, portn,
2620 						CFG_XMAC_RX)) != NPI_SUCCESS)
2621 			goto fail;
2622 	} else {
2623 		if ((rs = npi_bmac_rx_config(handle, ENABLE, portn,
2624 						CFG_BMAC_RX)) != NPI_SUCCESS)
2625 			goto fail;
2626 	}
2627 
2628 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_enable: port<%d>",
2629 			portn));
2630 
2631 	return (NXGE_OK);
2632 fail:
2633 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2634 			"nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC",
2635 			portn));
2636 
2637 	if (rs != NPI_SUCCESS)
2638 		return (NXGE_ERROR | rs);
2639 	else
2640 		return (status);
2641 }
2642 
2643 /* Disable RXMAC */
2644 
2645 nxge_status_t
2646 nxge_rx_mac_disable(p_nxge_t nxgep)
2647 {
2648 	npi_handle_t	handle;
2649 	uint8_t		portn;
2650 	npi_status_t	rs = NPI_SUCCESS;
2651 
2652 	handle = nxgep->npi_handle;
2653 	portn = nxgep->mac.portnum;
2654 
2655 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>",
2656 			portn));
2657 
2658 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
2659 		if ((rs = npi_xmac_rx_config(handle, DISABLE, portn,
2660 						CFG_XMAC_RX)) != NPI_SUCCESS)
2661 			goto fail;
2662 	} else {
2663 		if ((rs = npi_bmac_rx_config(handle, DISABLE, portn,
2664 						CFG_BMAC_RX)) != NPI_SUCCESS)
2665 			goto fail;
2666 	}
2667 
2668 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>",
2669 			portn));
2670 	return (NXGE_OK);
2671 fail:
2672 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2673 			"nxgep_rx_mac_disable: ",
2674 			"Failed to disable port<%d> RxMAC",
2675 			portn));
2676 
2677 	return (NXGE_ERROR | rs);
2678 }
2679 
2680 /* Reset TXMAC */
2681 
2682 nxge_status_t
2683 nxge_tx_mac_reset(p_nxge_t nxgep)
2684 {
2685 	npi_handle_t	handle;
2686 	uint8_t		portn;
2687 	npi_status_t	rs = NPI_SUCCESS;
2688 
2689 	handle = nxgep->npi_handle;
2690 	portn = nxgep->mac.portnum;
2691 
2692 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>",
2693 			portn));
2694 
2695 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
2696 		if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL))
2697 		    != NPI_SUCCESS)
2698 			goto fail;
2699 	} else {
2700 		if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET))
2701 					!= NPI_SUCCESS)
2702 			goto fail;
2703 	}
2704 
2705 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>",
2706 			portn));
2707 
2708 	return (NXGE_OK);
2709 fail:
2710 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2711 			"nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>",
2712 			portn));
2713 
2714 	return (NXGE_ERROR | rs);
2715 }
2716 
2717 /* Reset RXMAC */
2718 
2719 nxge_status_t
2720 nxge_rx_mac_reset(p_nxge_t nxgep)
2721 {
2722 	npi_handle_t	handle;
2723 	uint8_t		portn;
2724 	npi_status_t	rs = NPI_SUCCESS;
2725 
2726 	handle = nxgep->npi_handle;
2727 	portn = nxgep->mac.portnum;
2728 
2729 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>",
2730 			portn));
2731 
2732 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
2733 		if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL))
2734 		    != NPI_SUCCESS)
2735 		goto fail;
2736 	} else {
2737 		if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET))
2738 					!= NPI_SUCCESS)
2739 		goto fail;
2740 	}
2741 
2742 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>",
2743 			portn));
2744 
2745 	return (NXGE_OK);
2746 fail:
2747 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2748 			"nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>",
2749 			portn));
2750 	return (NXGE_ERROR | rs);
2751 }
2752 
2753 /* 10G fiber link interrupt start routine */
2754 
2755 static nxge_status_t
2756 nxge_10G_link_intr_start(p_nxge_t nxgep)
2757 {
2758 	npi_status_t	rs = NPI_SUCCESS;
2759 	uint8_t		portn = nxgep->mac.portnum;
2760 
2761 	rs = npi_xmac_xpcs_link_intr_enable(nxgep->npi_handle, portn);
2762 
2763 	if (rs != NPI_SUCCESS)
2764 		return (NXGE_ERROR | rs);
2765 	else
2766 		return (NXGE_OK);
2767 }
2768 
2769 /* 10G fiber link interrupt stop routine */
2770 
2771 static nxge_status_t
2772 nxge_10G_link_intr_stop(p_nxge_t nxgep)
2773 {
2774 	npi_status_t	rs = NPI_SUCCESS;
2775 	uint8_t		portn = nxgep->mac.portnum;
2776 
2777 	rs = npi_xmac_xpcs_link_intr_disable(nxgep->npi_handle, portn);
2778 
2779 	if (rs != NPI_SUCCESS)
2780 		return (NXGE_ERROR | rs);
2781 	else
2782 		return (NXGE_OK);
2783 }
2784 
2785 /* 1G fiber link interrupt start routine */
2786 
2787 static nxge_status_t
2788 nxge_1G_fiber_link_intr_start(p_nxge_t nxgep)
2789 {
2790 	npi_status_t	rs = NPI_SUCCESS;
2791 	uint8_t		portn = nxgep->mac.portnum;
2792 
2793 	rs = npi_mac_pcs_link_intr_enable(nxgep->npi_handle, portn);
2794 	if (rs != NPI_SUCCESS)
2795 		return (NXGE_ERROR | rs);
2796 	else
2797 		return (NXGE_OK);
2798 }
2799 
2800 /* 1G fiber link interrupt stop routine */
2801 
2802 static nxge_status_t
2803 nxge_1G_fiber_link_intr_stop(p_nxge_t nxgep)
2804 {
2805 	npi_status_t	rs = NPI_SUCCESS;
2806 	uint8_t		portn = nxgep->mac.portnum;
2807 
2808 	rs = npi_mac_pcs_link_intr_disable(nxgep->npi_handle, portn);
2809 
2810 	if (rs != NPI_SUCCESS)
2811 		return (NXGE_ERROR | rs);
2812 	else
2813 		return (NXGE_OK);
2814 }
2815 
2816 /* 1G copper link interrupt start routine */
2817 
2818 static nxge_status_t
2819 nxge_1G_copper_link_intr_start(p_nxge_t nxgep)
2820 {
2821 	npi_status_t	rs = NPI_SUCCESS;
2822 	uint8_t		portn = nxgep->mac.portnum;
2823 
2824 	rs = npi_mac_mif_link_intr_enable(nxgep->npi_handle, portn,
2825 	    MII_STATUS, MII_STATUS_LINKUP);
2826 
2827 	if (rs != NPI_SUCCESS)
2828 		return (NXGE_ERROR | rs);
2829 	else
2830 		return (NXGE_OK);
2831 }
2832 
2833 /* 1G copper link interrupt stop routine */
2834 
2835 static nxge_status_t
2836 nxge_1G_copper_link_intr_stop(p_nxge_t nxgep)
2837 {
2838 	npi_status_t	rs = NPI_SUCCESS;
2839 	uint8_t		portn = nxgep->mac.portnum;
2840 
2841 	rs = npi_mac_mif_link_intr_disable(nxgep->npi_handle, portn);
2842 
2843 	if (rs != NPI_SUCCESS)
2844 		return (NXGE_ERROR | rs);
2845 	else
2846 		return (NXGE_OK);
2847 }
2848 
2849 /* Enable/Disable Link Status change interrupt */
2850 
2851 nxge_status_t
2852 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable)
2853 {
2854 	uint8_t		portn;
2855 	nxge_status_t	status = NXGE_OK;
2856 
2857 	portn = nxgep->mac.portnum;
2858 
2859 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn));
2860 	if (!nxgep->xcvr.link_intr_stop || !nxgep->xcvr.link_intr_start)
2861 		return (NXGE_OK);
2862 
2863 	if (enable == LINK_INTR_START)
2864 		status = nxgep->xcvr.link_intr_start(nxgep);
2865 	else if (enable == LINK_INTR_STOP)
2866 		status = nxgep->xcvr.link_intr_stop(nxgep);
2867 	if (status != NXGE_OK)
2868 		goto fail;
2869 
2870 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn));
2871 
2872 	return (NXGE_OK);
2873 fail:
2874 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2875 			"nxge_link_intr: Failed to set port<%d> mif intr mode",
2876 			portn));
2877 
2878 	return (status);
2879 }
2880 
2881 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */
2882 
2883 nxge_status_t
2884 nxge_mii_xcvr_init(p_nxge_t nxgep)
2885 {
2886 	p_nxge_param_t	param_arr;
2887 	p_nxge_stats_t	statsp;
2888 	uint8_t		xcvr_portn;
2889 	p_mii_regs_t	mii_regs;
2890 	mii_bmcr_t	bmcr;
2891 	mii_bmsr_t	bmsr;
2892 	mii_anar_t	anar;
2893 	mii_gcr_t	gcr;
2894 	mii_esr_t	esr;
2895 	mii_aux_ctl_t	bcm5464r_aux;
2896 	int		status = NXGE_OK;
2897 
2898 	uint_t delay;
2899 
2900 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init"));
2901 
2902 	param_arr = nxgep->param_arr;
2903 	statsp = nxgep->statsp;
2904 	xcvr_portn = statsp->mac_stats.xcvr_portn;
2905 
2906 	mii_regs = NULL;
2907 
2908 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2909 		"nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value));
2910 
2911 	/*
2912 	 * The mif phy mode may be connected to either a copper link
2913 	 * or fiber link. Read the mode control register to get the fiber
2914 	 * configuration if it is hard-wired to fiber link.
2915 	 */
2916 	(void) nxge_mii_get_link_mode(nxgep);
2917 	if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) {
2918 		return (nxge_mii_xcvr_fiber_init(nxgep));
2919 	}
2920 
2921 	/*
2922 	 * Reset the transceiver.
2923 	 */
2924 	delay = 0;
2925 	bmcr.value = 0;
2926 	bmcr.bits.reset = 1;
2927 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
2928 #if defined(__i386)
2929 		(uint8_t)(uint32_t)&mii_regs->bmcr, bmcr.value)) != NXGE_OK)
2930 #else
2931 		(uint8_t)(uint64_t)&mii_regs->bmcr, bmcr.value)) != NXGE_OK)
2932 #endif
2933 		goto fail;
2934 	do {
2935 		drv_usecwait(500);
2936 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
2937 #if defined(__i386)
2938 			(uint8_t)(uint32_t)&mii_regs->bmcr, &bmcr.value))
2939 #else
2940 			(uint8_t)(uint64_t)&mii_regs->bmcr, &bmcr.value))
2941 #endif
2942 				!= NXGE_OK)
2943 			goto fail;
2944 		delay++;
2945 	} while ((bmcr.bits.reset) && (delay < 1000));
2946 	if (delay == 1000) {
2947 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed."));
2948 		goto fail;
2949 	}
2950 
2951 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
2952 #if defined(__i386)
2953 			(uint8_t)(uint32_t)(&mii_regs->bmsr),
2954 #else
2955 			(uint8_t)(uint64_t)(&mii_regs->bmsr),
2956 #endif
2957 			&bmsr.value)) != NXGE_OK)
2958 		goto fail;
2959 
2960 	param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able;
2961 	param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4;
2962 	param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx;
2963 	param_arr[param_anar_100hdx].value = 0;
2964 	param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx;
2965 	param_arr[param_anar_10hdx].value = 0;
2966 
2967 	/*
2968 	 * Initialize the xcvr statistics.
2969 	 */
2970 	statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able;
2971 	statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4;
2972 	statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx;
2973 	statsp->mac_stats.cap_100hdx = 0;
2974 	statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx;
2975 	statsp->mac_stats.cap_10hdx = 0;
2976 	statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value;
2977 	statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
2978 
2979 	/*
2980 	 * Initialise the xcvr advertised capability statistics.
2981 	 */
2982 	statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value;
2983 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
2984 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
2985 	statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value;
2986 	statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value;
2987 	statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value;
2988 	statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value;
2989 	statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value;
2990 	statsp->mac_stats.adv_cap_asmpause =
2991 					param_arr[param_anar_asmpause].value;
2992 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
2993 
2994 
2995 	/*
2996 	 * Check for extended status just in case we're
2997 	 * running a Gigibit phy.
2998 	 */
2999 	if (bmsr.bits.extend_status) {
3000 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
3001 #if defined(__i386)
3002 			(uint8_t)(uint32_t)(&mii_regs->esr), &esr.value))
3003 #else
3004 			(uint8_t)(uint64_t)(&mii_regs->esr), &esr.value))
3005 #endif
3006 				!= NXGE_OK)
3007 			goto fail;
3008 		param_arr[param_anar_1000fdx].value &=
3009 					esr.bits.link_1000fdx;
3010 		param_arr[param_anar_1000hdx].value = 0;
3011 
3012 		statsp->mac_stats.cap_1000fdx =
3013 			(esr.bits.link_1000Xfdx ||
3014 				esr.bits.link_1000fdx);
3015 		statsp->mac_stats.cap_1000hdx = 0;
3016 	} else {
3017 		param_arr[param_anar_1000fdx].value = 0;
3018 		param_arr[param_anar_1000hdx].value = 0;
3019 	}
3020 
3021 	/*
3022 	 * Initialize 1G Statistics once the capability is established.
3023 	 */
3024 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
3025 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
3026 
3027 	/*
3028 	 * Initialise the link statistics.
3029 	 */
3030 	statsp->mac_stats.link_T4 = 0;
3031 	statsp->mac_stats.link_asmpause = 0;
3032 	statsp->mac_stats.link_pause = 0;
3033 	statsp->mac_stats.link_speed = 0;
3034 	statsp->mac_stats.link_duplex = 0;
3035 	statsp->mac_stats.link_up = 0;
3036 
3037 	/*
3038 	 * Switch off Auto-negotiation, 100M and full duplex.
3039 	 */
3040 	bmcr.value = 0;
3041 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
3042 #if defined(__i386)
3043 		(uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
3044 #else
3045 		(uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
3046 #endif
3047 		goto fail;
3048 
3049 	if ((statsp->port_stats.lb_mode == nxge_lb_phy) ||
3050 			(statsp->port_stats.lb_mode == nxge_lb_phy1000)) {
3051 		bmcr.bits.loopback = 1;
3052 		bmcr.bits.enable_autoneg = 0;
3053 		if (statsp->port_stats.lb_mode == nxge_lb_phy1000)
3054 			bmcr.bits.speed_1000_sel = 1;
3055 		bmcr.bits.duplex_mode = 1;
3056 		param_arr[param_autoneg].value = 0;
3057 	} else {
3058 		bmcr.bits.loopback = 0;
3059 	}
3060 
3061 	if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
3062 		(statsp->port_stats.lb_mode == nxge_lb_ext100) ||
3063 		(statsp->port_stats.lb_mode == nxge_lb_ext10)) {
3064 		param_arr[param_autoneg].value = 0;
3065 		bcm5464r_aux.value = 0;
3066 		bcm5464r_aux.bits.ext_lb = 1;
3067 		bcm5464r_aux.bits.write_1 = 1;
3068 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
3069 				BCM5464R_AUX_CTL, bcm5464r_aux.value))
3070 				!= NXGE_OK)
3071 			goto fail;
3072 	}
3073 
3074 	if (param_arr[param_autoneg].value) {
3075 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3076 				"Restarting Auto-negotiation."));
3077 		/*
3078 		 * Setup our Auto-negotiation advertisement register.
3079 		 */
3080 		anar.value = 0;
3081 		anar.bits.selector = 1;
3082 		anar.bits.cap_100T4 = param_arr[param_anar_100T4].value;
3083 		anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value;
3084 		anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value;
3085 		anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value;
3086 		anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value;
3087 		anar.bits.cap_asmpause = 0;
3088 		anar.bits.cap_pause = 0;
3089 		if (param_arr[param_anar_1000fdx].value ||
3090 			param_arr[param_anar_100fdx].value ||
3091 			param_arr[param_anar_10fdx].value) {
3092 			anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause;
3093 			anar.bits.cap_pause = statsp->mac_stats.cap_pause;
3094 		}
3095 
3096 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
3097 #if defined(__i386)
3098 			(uint8_t)(uint32_t)(&mii_regs->anar), anar.value))
3099 #else
3100 			(uint8_t)(uint64_t)(&mii_regs->anar), anar.value))
3101 #endif
3102 				!= NXGE_OK)
3103 			goto fail;
3104 		if (bmsr.bits.extend_status) {
3105 			gcr.value = 0;
3106 			gcr.bits.ms_mode_en =
3107 				param_arr[param_master_cfg_enable].value;
3108 			gcr.bits.master =
3109 				param_arr[param_master_cfg_value].value;
3110 			gcr.bits.link_1000fdx =
3111 				param_arr[param_anar_1000fdx].value;
3112 			gcr.bits.link_1000hdx =
3113 				param_arr[param_anar_1000hdx].value;
3114 			if ((status = nxge_mii_write(nxgep, xcvr_portn,
3115 #if defined(__i386)
3116 				(uint8_t)(uint32_t)(&mii_regs->gcr), gcr.value))
3117 #else
3118 				(uint8_t)(uint64_t)(&mii_regs->gcr), gcr.value))
3119 #endif
3120 				!= NXGE_OK)
3121 				goto fail;
3122 		}
3123 
3124 		bmcr.bits.enable_autoneg = 1;
3125 		bmcr.bits.restart_autoneg = 1;
3126 
3127 	} else {
3128 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode."));
3129 		bmcr.bits.speed_1000_sel =
3130 			param_arr[param_anar_1000fdx].value |
3131 				param_arr[param_anar_1000hdx].value;
3132 		bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) &
3133 			(param_arr[param_anar_100fdx].value |
3134 				param_arr[param_anar_100hdx].value);
3135 		if (bmcr.bits.speed_1000_sel) {
3136 			statsp->mac_stats.link_speed = 1000;
3137 			gcr.value = 0;
3138 			gcr.bits.ms_mode_en =
3139 				param_arr[param_master_cfg_enable].value;
3140 			gcr.bits.master =
3141 				param_arr[param_master_cfg_value].value;
3142 			if ((status = nxge_mii_write(nxgep, xcvr_portn,
3143 #if defined(__i386)
3144 				(uint8_t)(uint32_t)(&mii_regs->gcr),
3145 #else
3146 				(uint8_t)(uint64_t)(&mii_regs->gcr),
3147 #endif
3148 				gcr.value))
3149 				!= NXGE_OK)
3150 				goto fail;
3151 			if (param_arr[param_anar_1000fdx].value) {
3152 				bmcr.bits.duplex_mode = 1;
3153 				statsp->mac_stats.link_duplex = 2;
3154 			} else
3155 				statsp->mac_stats.link_duplex = 1;
3156 		} else if (bmcr.bits.speed_sel) {
3157 			statsp->mac_stats.link_speed = 100;
3158 			if (param_arr[param_anar_100fdx].value) {
3159 				bmcr.bits.duplex_mode = 1;
3160 				statsp->mac_stats.link_duplex = 2;
3161 			} else
3162 				statsp->mac_stats.link_duplex = 1;
3163 		} else {
3164 			statsp->mac_stats.link_speed = 10;
3165 			if (param_arr[param_anar_10fdx].value) {
3166 				bmcr.bits.duplex_mode = 1;
3167 				statsp->mac_stats.link_duplex = 2;
3168 			} else
3169 				statsp->mac_stats.link_duplex = 1;
3170 		}
3171 		if (statsp->mac_stats.link_duplex != 1) {
3172 			statsp->mac_stats.link_asmpause =
3173 						statsp->mac_stats.cap_asmpause;
3174 			statsp->mac_stats.link_pause =
3175 						statsp->mac_stats.cap_pause;
3176 		}
3177 
3178 		if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
3179 			(statsp->port_stats.lb_mode == nxge_lb_ext100) ||
3180 			(statsp->port_stats.lb_mode == nxge_lb_ext10)) {
3181 			if (statsp->port_stats.lb_mode == nxge_lb_ext1000) {
3182 				/* BCM5464R 1000mbps external loopback mode */
3183 				gcr.value = 0;
3184 				gcr.bits.ms_mode_en = 1;
3185 				gcr.bits.master = 1;
3186 				if ((status = nxge_mii_write(nxgep, xcvr_portn,
3187 #if defined(__i386)
3188 					(uint8_t)(uint32_t)(&mii_regs->gcr),
3189 #else
3190 					(uint8_t)(uint64_t)(&mii_regs->gcr),
3191 #endif
3192 					gcr.value))
3193 					!= NXGE_OK)
3194 					goto fail;
3195 				bmcr.value = 0;
3196 				bmcr.bits.speed_1000_sel = 1;
3197 				statsp->mac_stats.link_speed = 1000;
3198 			} else if (statsp->port_stats.lb_mode
3199 			    == nxge_lb_ext100) {
3200 				/* BCM5464R 100mbps external loopback mode */
3201 				bmcr.value = 0;
3202 				bmcr.bits.speed_sel = 1;
3203 				bmcr.bits.duplex_mode = 1;
3204 				statsp->mac_stats.link_speed = 100;
3205 			} else if (statsp->port_stats.lb_mode
3206 			    == nxge_lb_ext10) {
3207 				/* BCM5464R 10mbps external loopback mode */
3208 				bmcr.value = 0;
3209 				bmcr.bits.duplex_mode = 1;
3210 				statsp->mac_stats.link_speed = 10;
3211 			}
3212 		}
3213 	}
3214 
3215 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
3216 #if defined(__i386)
3217 			(uint8_t)(uint32_t)(&mii_regs->bmcr),
3218 #else
3219 			(uint8_t)(uint64_t)(&mii_regs->bmcr),
3220 #endif
3221 			bmcr.value)) != NXGE_OK)
3222 		goto fail;
3223 
3224 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
3225 #if defined(__i386)
3226 		(uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
3227 #else
3228 		(uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
3229 #endif
3230 		goto fail;
3231 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value));
3232 
3233 	/*
3234 	 * Initialize the xcvr status kept in the context structure.
3235 	 */
3236 	nxgep->soft_bmsr.value = 0;
3237 
3238 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
3239 #if defined(__i386)
3240 		(uint8_t)(uint32_t)(&mii_regs->bmsr),
3241 #else
3242 		(uint8_t)(uint64_t)(&mii_regs->bmsr),
3243 #endif
3244 			&nxgep->bmsr.value)) != NXGE_OK)
3245 		goto fail;
3246 
3247 	statsp->mac_stats.xcvr_inits++;
3248 	nxgep->bmsr.value = 0;
3249 
3250 fail:
3251 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3252 			"<== nxge_mii_xcvr_init status 0x%x", status));
3253 	return (status);
3254 }
3255 
3256 nxge_status_t
3257 nxge_mii_xcvr_fiber_init(p_nxge_t nxgep)
3258 {
3259 	p_nxge_param_t	param_arr;
3260 	p_nxge_stats_t	statsp;
3261 	uint8_t		xcvr_portn;
3262 	p_mii_regs_t	mii_regs;
3263 	mii_bmcr_t	bmcr;
3264 	mii_bmsr_t	bmsr;
3265 	mii_gcr_t	gcr;
3266 	mii_esr_t	esr;
3267 	mii_aux_ctl_t	bcm5464r_aux;
3268 	int		status = NXGE_OK;
3269 
3270 	uint_t delay;
3271 
3272 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_fiber_init"));
3273 
3274 	param_arr = nxgep->param_arr;
3275 	statsp = nxgep->statsp;
3276 	xcvr_portn = statsp->mac_stats.xcvr_portn;
3277 
3278 	mii_regs = NULL;
3279 
3280 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3281 	    "nxge_mii_xcvr_fiber_init: "
3282 	    "nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value));
3283 
3284 	/*
3285 	 * Reset the transceiver.
3286 	 */
3287 	delay = 0;
3288 	bmcr.value = 0;
3289 	bmcr.bits.reset = 1;
3290 
3291 #if defined(__i386)
3292 
3293 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
3294 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
3295 		goto fail;
3296 #else
3297 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
3298 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
3299 		goto fail;
3300 #endif
3301 	do {
3302 		drv_usecwait(500);
3303 #if defined(__i386)
3304 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
3305 		    (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value))
3306 		    != NXGE_OK)
3307 			goto fail;
3308 #else
3309 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
3310 		    (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value))
3311 		    != NXGE_OK)
3312 			goto fail;
3313 #endif
3314 		delay++;
3315 	} while ((bmcr.bits.reset) && (delay < 1000));
3316 	if (delay == 1000) {
3317 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed."));
3318 		goto fail;
3319 	}
3320 
3321 #if defined(__i386)
3322 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
3323 	    (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK)
3324 		goto fail;
3325 #else
3326 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
3327 	    (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value)) != NXGE_OK)
3328 		goto fail;
3329 #endif
3330 
3331 	param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able;
3332 	param_arr[param_anar_100T4].value = 0;
3333 	param_arr[param_anar_100fdx].value = 0;
3334 	param_arr[param_anar_100hdx].value = 0;
3335 	param_arr[param_anar_10fdx].value = 0;
3336 	param_arr[param_anar_10hdx].value = 0;
3337 
3338 	/*
3339 	 * Initialize the xcvr statistics.
3340 	 */
3341 	statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able;
3342 	statsp->mac_stats.cap_100T4 = 0;
3343 	statsp->mac_stats.cap_100fdx = 0;
3344 	statsp->mac_stats.cap_100hdx = 0;
3345 	statsp->mac_stats.cap_10fdx = 0;
3346 	statsp->mac_stats.cap_10hdx = 0;
3347 	statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value;
3348 	statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
3349 
3350 	/*
3351 	 * Initialize the xcvr advertised capability statistics.
3352 	 */
3353 	statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value;
3354 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
3355 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
3356 	statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value;
3357 	statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value;
3358 	statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value;
3359 	statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value;
3360 	statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value;
3361 	statsp->mac_stats.adv_cap_asmpause =
3362 	    param_arr[param_anar_asmpause].value;
3363 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
3364 
3365 	/*
3366 	 * Check for extended status just in case we're
3367 	 * running a Gigibit phy.
3368 	 */
3369 	if (bmsr.bits.extend_status) {
3370 #if defined(__i386)
3371 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
3372 		    (uint8_t)(uint32_t)(&mii_regs->esr), &esr.value)) !=
3373 		    NXGE_OK)
3374 			goto fail;
3375 #else
3376 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
3377 		    (uint8_t)(uint64_t)(&mii_regs->esr), &esr.value)) !=
3378 		    NXGE_OK)
3379 			goto fail;
3380 #endif
3381 		param_arr[param_anar_1000fdx].value &=
3382 		    esr.bits.link_1000fdx;
3383 		param_arr[param_anar_1000hdx].value = 0;
3384 
3385 		statsp->mac_stats.cap_1000fdx =
3386 		    (esr.bits.link_1000Xfdx || esr.bits.link_1000fdx);
3387 		statsp->mac_stats.cap_1000hdx = 0;
3388 	} else {
3389 		param_arr[param_anar_1000fdx].value = 0;
3390 		param_arr[param_anar_1000hdx].value = 0;
3391 	}
3392 
3393 	/*
3394 	 * Initialize 1G Statistics once the capability is established.
3395 	 */
3396 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
3397 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
3398 
3399 	/*
3400 	 * Initialize the link statistics.
3401 	 */
3402 	statsp->mac_stats.link_T4 = 0;
3403 	statsp->mac_stats.link_asmpause = 0;
3404 	statsp->mac_stats.link_pause = 0;
3405 	statsp->mac_stats.link_speed = 0;
3406 	statsp->mac_stats.link_duplex = 0;
3407 	statsp->mac_stats.link_up = 0;
3408 
3409 	/*
3410 	 * Switch off Auto-negotiation, 100M and full duplex.
3411 	 */
3412 	bmcr.value = 0;
3413 #if defined(__i386)
3414 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
3415 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
3416 		goto fail;
3417 #else
3418 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
3419 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
3420 		goto fail;
3421 #endif
3422 
3423 	if ((statsp->port_stats.lb_mode == nxge_lb_phy) ||
3424 	    (statsp->port_stats.lb_mode == nxge_lb_phy1000)) {
3425 		bmcr.bits.loopback = 1;
3426 		bmcr.bits.enable_autoneg = 0;
3427 		if (statsp->port_stats.lb_mode == nxge_lb_phy1000)
3428 			bmcr.bits.speed_1000_sel = 1;
3429 		bmcr.bits.duplex_mode = 1;
3430 		param_arr[param_autoneg].value = 0;
3431 	} else {
3432 		bmcr.bits.loopback = 0;
3433 	}
3434 
3435 	if (statsp->port_stats.lb_mode == nxge_lb_ext1000) {
3436 		param_arr[param_autoneg].value = 0;
3437 		bcm5464r_aux.value = 0;
3438 		bcm5464r_aux.bits.ext_lb = 1;
3439 		bcm5464r_aux.bits.write_1 = 1;
3440 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
3441 		    BCM5464R_AUX_CTL, bcm5464r_aux.value)) != NXGE_OK)
3442 			goto fail;
3443 	}
3444 
3445 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode."));
3446 	bmcr.bits.speed_1000_sel = 1;
3447 	bmcr.bits.speed_sel = 0;
3448 	bmcr.bits.duplex_mode = 1;
3449 	statsp->mac_stats.link_speed = 1000;
3450 	statsp->mac_stats.link_duplex = 2;
3451 
3452 	if ((statsp->port_stats.lb_mode == nxge_lb_ext1000)) {
3453 		/* BCM5464R 1000mbps external loopback mode */
3454 		gcr.value = 0;
3455 		gcr.bits.ms_mode_en = 1;
3456 		gcr.bits.master = 1;
3457 #if defined(__i386)
3458 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
3459 		    (uint8_t)(uint32_t)(&mii_regs->gcr),
3460 		    gcr.value)) != NXGE_OK)
3461 			goto fail;
3462 #else
3463 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
3464 		    (uint8_t)(uint64_t)(&mii_regs->gcr),
3465 		    gcr.value)) != NXGE_OK)
3466 			goto fail;
3467 #endif
3468 		bmcr.value = 0;
3469 		bmcr.bits.speed_1000_sel = 1;
3470 		statsp->mac_stats.link_speed = 1000;
3471 	}
3472 
3473 #if defined(__i386)
3474 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
3475 	    (uint8_t)(uint32_t)(&mii_regs->bmcr),
3476 	    bmcr.value)) != NXGE_OK)
3477 		goto fail;
3478 #else
3479 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
3480 	    (uint8_t)(uint64_t)(&mii_regs->bmcr),
3481 	    bmcr.value)) != NXGE_OK)
3482 		goto fail;
3483 #endif
3484 
3485 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3486 	    "nxge_mii_xcvr_fiber_init: value wrote bmcr = 0x%x",
3487 	    bmcr.value));
3488 
3489 #if defined(__i386)
3490 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
3491 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
3492 		goto fail;
3493 #else
3494 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
3495 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
3496 		goto fail;
3497 #endif
3498 
3499 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3500 	    "nxge_mii_xcvr_fiber_init: read bmcr = 0x%04X", bmcr.value));
3501 
3502 	/*
3503 	 * Initialize the xcvr status kept in the context structure.
3504 	 */
3505 	nxgep->soft_bmsr.value = 0;
3506 #if defined(__i386)
3507 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
3508 	    (uint8_t)(uint32_t)(&mii_regs->bmsr),
3509 	    &nxgep->bmsr.value)) != NXGE_OK)
3510 		goto fail;
3511 #else
3512 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
3513 	    (uint8_t)(uint64_t)(&mii_regs->bmsr),
3514 	    &nxgep->bmsr.value)) != NXGE_OK)
3515 		goto fail;
3516 #endif
3517 
3518 	statsp->mac_stats.xcvr_inits++;
3519 	nxgep->bmsr.value = 0;
3520 
3521 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3522 	    "<== nxge_mii_xcvr_fiber_init status 0x%x", status));
3523 	return (status);
3524 
3525 fail:
3526 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3527 	    "<== nxge_mii_xcvr_fiber_init status 0x%x", status));
3528 	return (status);
3529 }
3530 
3531 /* Read from a MII compliant register */
3532 
3533 nxge_status_t
3534 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
3535 		uint16_t *value)
3536 {
3537 	npi_status_t rs = NPI_SUCCESS;
3538 
3539 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>"
3540 			"xcvr_reg<%d>", xcvr_portn, xcvr_reg));
3541 
3542 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mii_lock);
3543 
3544 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
3545 	    (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) {
3546 		if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle,
3547 				xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
3548 			goto fail;
3549 	} else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
3550 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
3551 		if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle,
3552 				xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
3553 			goto fail;
3554 	} else
3555 		goto fail;
3556 
3557 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mii_lock);
3558 
3559 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>"
3560 			"xcvr_reg<%d> value=0x%x",
3561 			xcvr_portn, xcvr_reg, *value));
3562 	return (NXGE_OK);
3563 fail:
3564 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mii_lock);
3565 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3566 			"nxge_mii_read: Failed to read mii on xcvr %d",
3567 			xcvr_portn));
3568 
3569 	return (NXGE_ERROR | rs);
3570 }
3571 
3572 /* Write to a MII compliant Register */
3573 
3574 nxge_status_t
3575 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
3576 		uint16_t value)
3577 {
3578 	npi_status_t rs = NPI_SUCCESS;
3579 
3580 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>"
3581 			"xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg,
3582 			value));
3583 
3584 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mii_lock);
3585 
3586 	if ((nxgep->mac.portmode == PORT_1G_COPPER) ||
3587 	    (nxgep->mac.portmode == PORT_1G_RGMII_FIBER)) {
3588 		if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle,
3589 				xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
3590 			goto fail;
3591 	} else if ((nxgep->mac.portmode == PORT_1G_FIBER) ||
3592 	    (nxgep->mac.portmode == PORT_1G_SERDES)) {
3593 		if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle,
3594 				xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
3595 			goto fail;
3596 	} else
3597 		goto fail;
3598 
3599 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mii_lock);
3600 
3601 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>"
3602 			"xcvr_reg<%d>", xcvr_portn, xcvr_reg));
3603 	return (NXGE_OK);
3604 fail:
3605 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mii_lock);
3606 
3607 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3608 			"nxge_mii_write: Failed to write mii on xcvr %d",
3609 			xcvr_portn));
3610 
3611 	return (NXGE_ERROR | rs);
3612 }
3613 
3614 /* Perform read from Clause45 serdes / transceiver device */
3615 
3616 nxge_status_t
3617 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
3618 		uint16_t xcvr_reg, uint16_t *value)
3619 {
3620 	npi_status_t rs = NPI_SUCCESS;
3621 
3622 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>",
3623 			xcvr_portn));
3624 
3625 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
3626 
3627 	if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle,
3628 			xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
3629 		goto fail;
3630 
3631 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
3632 
3633 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>",
3634 			xcvr_portn));
3635 	return (NXGE_OK);
3636 fail:
3637 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
3638 
3639 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3640 			"nxge_mdio_read: Failed to read mdio on xcvr %d",
3641 			xcvr_portn));
3642 
3643 	return (NXGE_ERROR | rs);
3644 }
3645 
3646 /* Perform write to Clause45 serdes / transceiver device */
3647 
3648 nxge_status_t
3649 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
3650 		uint16_t xcvr_reg, uint16_t value)
3651 {
3652 	npi_status_t rs = NPI_SUCCESS;
3653 
3654 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>",
3655 			xcvr_portn));
3656 
3657 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
3658 
3659 	if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle,
3660 			xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
3661 		goto fail;
3662 
3663 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
3664 
3665 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>",
3666 			xcvr_portn));
3667 	return (NXGE_OK);
3668 fail:
3669 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
3670 
3671 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3672 			"nxge_mdio_write: Failed to write mdio on xcvr %d",
3673 			xcvr_portn));
3674 
3675 	return (NXGE_ERROR | rs);
3676 }
3677 
3678 
3679 /* Check MII to see if there is any link status change */
3680 
3681 nxge_status_t
3682 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints,
3683 		nxge_link_state_t *link_up)
3684 {
3685 	p_nxge_param_t	param_arr;
3686 	p_nxge_stats_t	statsp;
3687 	p_mii_regs_t	mii_regs;
3688 	p_mii_bmsr_t	soft_bmsr;
3689 	mii_anar_t	anar;
3690 	mii_anlpar_t	anlpar;
3691 	mii_anar_t	an_common;
3692 	mii_aner_t	aner;
3693 	mii_gsr_t	gsr;
3694 	nxge_status_t	status = NXGE_OK;
3695 
3696 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check"));
3697 
3698 	mii_regs = NULL;
3699 	param_arr = nxgep->param_arr;
3700 	statsp = nxgep->statsp;
3701 	soft_bmsr = &nxgep->soft_bmsr;
3702 	*link_up = LINK_NO_CHANGE;
3703 
3704 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3705 	    "==> nxge_mii_check bmsr 0x%x bmsr_int 0x%x",
3706 	    bmsr.value, bmsr_ints.value));
3707 
3708 	if (bmsr_ints.bits.link_status) {
3709 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3710 		    "==> nxge_mii_check (link up) bmsr 0x%x bmsr_int 0x%x",
3711 		    bmsr.value, bmsr_ints.value));
3712 		if (bmsr.bits.link_status) {
3713 			soft_bmsr->bits.link_status = 1;
3714 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3715 		    "==> nxge_mii_check (link up) soft bmsr 0x%x bmsr_int "
3716 		    "0x%x", bmsr.value, bmsr_ints.value));
3717 		} else {
3718 			statsp->mac_stats.link_up = 0;
3719 			soft_bmsr->bits.link_status = 0;
3720 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3721 					"Link down cable problem"));
3722 			*link_up = LINK_IS_DOWN;
3723 		}
3724 	}
3725 
3726 	if (nxgep->mac.portmode == PORT_1G_COPPER &&
3727 	    param_arr[param_autoneg].value) {
3728 		if (bmsr_ints.bits.auto_neg_complete) {
3729 			if (bmsr.bits.auto_neg_complete)
3730 				soft_bmsr->bits.auto_neg_complete = 1;
3731 			else
3732 				soft_bmsr->bits.auto_neg_complete = 0;
3733 		}
3734 		if (soft_bmsr->bits.link_status == 0) {
3735 			statsp->mac_stats.link_T4 = 0;
3736 			statsp->mac_stats.link_speed = 0;
3737 			statsp->mac_stats.link_duplex = 0;
3738 			statsp->mac_stats.link_asmpause = 0;
3739 			statsp->mac_stats.link_pause = 0;
3740 			statsp->mac_stats.lp_cap_autoneg = 0;
3741 			statsp->mac_stats.lp_cap_100T4 = 0;
3742 			statsp->mac_stats.lp_cap_1000fdx = 0;
3743 			statsp->mac_stats.lp_cap_1000hdx = 0;
3744 			statsp->mac_stats.lp_cap_100fdx = 0;
3745 			statsp->mac_stats.lp_cap_100hdx = 0;
3746 			statsp->mac_stats.lp_cap_10fdx = 0;
3747 			statsp->mac_stats.lp_cap_10hdx = 0;
3748 			statsp->mac_stats.lp_cap_10gfdx = 0;
3749 			statsp->mac_stats.lp_cap_10ghdx = 0;
3750 			statsp->mac_stats.lp_cap_asmpause = 0;
3751 			statsp->mac_stats.lp_cap_pause = 0;
3752 		}
3753 	} else
3754 		soft_bmsr->bits.auto_neg_complete = 1;
3755 
3756 	if ((bmsr_ints.bits.link_status ||
3757 		bmsr_ints.bits.auto_neg_complete) &&
3758 		soft_bmsr->bits.link_status &&
3759 		soft_bmsr->bits.auto_neg_complete) {
3760 		statsp->mac_stats.link_up = 1;
3761 
3762 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3763 		    "==> nxge_mii_check "
3764 		    "(auto negotiation complete or link up) "
3765 		    "soft bmsr 0x%x bmsr_int 0x%x",
3766 		    bmsr.value, bmsr_ints.value));
3767 
3768 		if (nxgep->mac.portmode == PORT_1G_COPPER &&
3769 		    param_arr[param_autoneg].value) {
3770 			if ((status = nxge_mii_read(nxgep,
3771 				statsp->mac_stats.xcvr_portn,
3772 #if defined(__i386)
3773 				(uint8_t)(uint32_t)(&mii_regs->anar),
3774 #else
3775 				(uint8_t)(uint64_t)(&mii_regs->anar),
3776 #endif
3777 					&anar.value)) != NXGE_OK)
3778 				goto fail;
3779 			if ((status = nxge_mii_read(nxgep,
3780 				statsp->mac_stats.xcvr_portn,
3781 #if defined(__i386)
3782 				(uint8_t)(uint32_t)(&mii_regs->anlpar),
3783 #else
3784 				(uint8_t)(uint64_t)(&mii_regs->anlpar),
3785 #endif
3786 					&anlpar.value)) != NXGE_OK)
3787 				goto fail;
3788 			if ((status = nxge_mii_read(nxgep,
3789 				statsp->mac_stats.xcvr_portn,
3790 #if defined(__i386)
3791 				(uint8_t)(uint32_t)(&mii_regs->aner),
3792 #else
3793 				(uint8_t)(uint64_t)(&mii_regs->aner),
3794 #endif
3795 					&aner.value)) != NXGE_OK)
3796 				goto fail;
3797 			statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able;
3798 			statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4;
3799 			statsp->mac_stats.lp_cap_100fdx =
3800 							anlpar.bits.cap_100fdx;
3801 			statsp->mac_stats.lp_cap_100hdx =
3802 							anlpar.bits.cap_100hdx;
3803 			statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx;
3804 			statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx;
3805 			statsp->mac_stats.lp_cap_asmpause =
3806 						anlpar.bits.cap_asmpause;
3807 			statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause;
3808 			an_common.value = anar.value & anlpar.value;
3809 			if (param_arr[param_anar_1000fdx].value ||
3810 				param_arr[param_anar_1000hdx].value) {
3811 				if ((status = nxge_mii_read(nxgep,
3812 					statsp->mac_stats.xcvr_portn,
3813 #if defined(__i386)
3814 					(uint8_t)(uint32_t)(&mii_regs->gsr),
3815 #else
3816 					(uint8_t)(uint64_t)(&mii_regs->gsr),
3817 #endif
3818 						&gsr.value))
3819 						!= NXGE_OK)
3820 					goto fail;
3821 				statsp->mac_stats.lp_cap_1000fdx =
3822 					gsr.bits.link_1000fdx;
3823 				statsp->mac_stats.lp_cap_1000hdx =
3824 					gsr.bits.link_1000hdx;
3825 				if (param_arr[param_anar_1000fdx].value &&
3826 					gsr.bits.link_1000fdx) {
3827 					statsp->mac_stats.link_speed = 1000;
3828 					statsp->mac_stats.link_duplex = 2;
3829 				} else if (
3830 					param_arr[param_anar_1000hdx].value &&
3831 						gsr.bits.link_1000hdx) {
3832 					statsp->mac_stats.link_speed = 1000;
3833 					statsp->mac_stats.link_duplex = 1;
3834 				}
3835 			}
3836 			if ((an_common.value != 0) &&
3837 					!(statsp->mac_stats.link_speed)) {
3838 				if (an_common.bits.cap_100T4) {
3839 					statsp->mac_stats.link_T4 = 1;
3840 					statsp->mac_stats.link_speed = 100;
3841 					statsp->mac_stats.link_duplex = 1;
3842 				} else if (an_common.bits.cap_100fdx) {
3843 					statsp->mac_stats.link_speed = 100;
3844 					statsp->mac_stats.link_duplex = 2;
3845 				} else if (an_common.bits.cap_100hdx) {
3846 					statsp->mac_stats.link_speed = 100;
3847 					statsp->mac_stats.link_duplex = 1;
3848 				} else if (an_common.bits.cap_10fdx) {
3849 					statsp->mac_stats.link_speed = 10;
3850 					statsp->mac_stats.link_duplex = 2;
3851 				} else if (an_common.bits.cap_10hdx) {
3852 					statsp->mac_stats.link_speed = 10;
3853 					statsp->mac_stats.link_duplex = 1;
3854 				} else {
3855 					goto fail;
3856 				}
3857 			}
3858 			if (statsp->mac_stats.link_duplex != 1) {
3859 				statsp->mac_stats.link_asmpause =
3860 					an_common.bits.cap_asmpause;
3861 				if (statsp->mac_stats.link_asmpause)
3862 				if ((statsp->mac_stats.cap_pause == 0) &&
3863 						(statsp->mac_stats.lp_cap_pause
3864 						== 1))
3865 						statsp->mac_stats.link_pause
3866 						= 0;
3867 					else
3868 						statsp->mac_stats.link_pause
3869 						= 1;
3870 				else
3871 					statsp->mac_stats.link_pause =
3872 						an_common.bits.cap_pause;
3873 			}
3874 		} else if (nxgep->mac.portmode == PORT_1G_RGMII_FIBER) {
3875 			statsp->mac_stats.link_speed = 1000;
3876 			statsp->mac_stats.link_duplex = 2;
3877 		}
3878 		*link_up = LINK_IS_UP;
3879 	}
3880 
3881 	if (nxgep->link_notify) {
3882 		*link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP :
3883 				LINK_IS_DOWN);
3884 		nxgep->link_notify = B_FALSE;
3885 	}
3886 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check"));
3887 	return (NXGE_OK);
3888 fail:
3889 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3890 			"nxge_mii_check: Unable to check MII"));
3891 	return (status);
3892 }
3893 
3894 /* Check PCS to see if there is any link status change */
3895 nxge_status_t
3896 nxge_pcs_check(p_nxge_t nxgep, uint8_t portn, nxge_link_state_t *link_up)
3897 {
3898 	p_nxge_stats_t	statsp;
3899 	nxge_status_t	status = NXGE_OK;
3900 	boolean_t	linkup;
3901 
3902 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_check"));
3903 
3904 	statsp = nxgep->statsp;
3905 	*link_up = LINK_NO_CHANGE;
3906 
3907 	(void) npi_mac_get_link_status(nxgep->npi_handle, portn, &linkup);
3908 	if (linkup) {
3909 		if (nxgep->link_notify ||
3910 		    nxgep->statsp->mac_stats.link_up == 0) {
3911 			statsp->mac_stats.link_up = 1;
3912 			statsp->mac_stats.link_speed = 1000;
3913 			statsp->mac_stats.link_duplex = 2;
3914 			*link_up = LINK_IS_UP;
3915 			nxgep->link_notify = B_FALSE;
3916 		}
3917 	} else {
3918 		if (nxgep->link_notify ||
3919 		    nxgep->statsp->mac_stats.link_up == 1) {
3920 			statsp->mac_stats.link_up = 0;
3921 			statsp->mac_stats.link_speed = 0;
3922 			statsp->mac_stats.link_duplex = 0;
3923 			*link_up = LINK_IS_DOWN;
3924 			nxgep->link_notify = B_FALSE;
3925 		}
3926 	}
3927 
3928 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_check"));
3929 	return (NXGE_OK);
3930 fail:
3931 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3932 	    "nxge_pcs_check: Unable to check PCS"));
3933 	return (status);
3934 }
3935 
3936 /* Add a multicast address entry into the HW hash table */
3937 
3938 nxge_status_t
3939 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
3940 {
3941 	uint32_t mchash;
3942 	p_hash_filter_t hash_filter;
3943 	uint16_t hash_bit;
3944 	boolean_t rx_init = B_FALSE;
3945 	uint_t j;
3946 	nxge_status_t status = NXGE_OK;
3947 
3948 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr"));
3949 
3950 	RW_ENTER_WRITER(&nxgep->filter_lock);
3951 	mchash = crc32_mchash(addrp);
3952 	if (nxgep->hash_filter == NULL) {
3953 		NXGE_DEBUG_MSG((NULL, STR_CTL,
3954 			"Allocating hash filter storage."));
3955 		nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t),
3956 					KM_SLEEP);
3957 	}
3958 	hash_filter = nxgep->hash_filter;
3959 	j = mchash / HASH_REG_WIDTH;
3960 	hash_bit = (1 << (mchash % HASH_REG_WIDTH));
3961 	hash_filter->hash_filter_regs[j] |= hash_bit;
3962 	hash_filter->hash_bit_ref_cnt[mchash]++;
3963 	if (hash_filter->hash_bit_ref_cnt[mchash] == 1) {
3964 		hash_filter->hash_ref_cnt++;
3965 		rx_init = B_TRUE;
3966 	}
3967 	if (rx_init) {
3968 		if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
3969 			goto fail;
3970 		if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
3971 			goto fail;
3972 	}
3973 
3974 	RW_EXIT(&nxgep->filter_lock);
3975 
3976 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr"));
3977 
3978 	return (NXGE_OK);
3979 fail:
3980 	RW_EXIT(&nxgep->filter_lock);
3981 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: "
3982 					"Unable to add multicast address"));
3983 	return (status);
3984 }
3985 
3986 /* Remove a multicast address entry from the HW hash table */
3987 
3988 nxge_status_t
3989 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
3990 {
3991 	uint32_t mchash;
3992 	p_hash_filter_t hash_filter;
3993 	uint16_t hash_bit;
3994 	boolean_t rx_init = B_FALSE;
3995 	uint_t j;
3996 	nxge_status_t status = NXGE_OK;
3997 
3998 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr"));
3999 	RW_ENTER_WRITER(&nxgep->filter_lock);
4000 	mchash = crc32_mchash(addrp);
4001 	if (nxgep->hash_filter == NULL) {
4002 		NXGE_DEBUG_MSG((NULL, STR_CTL,
4003 			"Hash filter already de_allocated."));
4004 		RW_EXIT(&nxgep->filter_lock);
4005 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
4006 		return (NXGE_OK);
4007 	}
4008 	hash_filter = nxgep->hash_filter;
4009 	hash_filter->hash_bit_ref_cnt[mchash]--;
4010 	if (hash_filter->hash_bit_ref_cnt[mchash] == 0) {
4011 		j = mchash / HASH_REG_WIDTH;
4012 		hash_bit = (1 << (mchash % HASH_REG_WIDTH));
4013 		hash_filter->hash_filter_regs[j] &= ~hash_bit;
4014 		hash_filter->hash_ref_cnt--;
4015 		rx_init = B_TRUE;
4016 	}
4017 	if (hash_filter->hash_ref_cnt == 0) {
4018 		NXGE_DEBUG_MSG((NULL, STR_CTL,
4019 			"De-allocating hash filter storage."));
4020 		KMEM_FREE(hash_filter, sizeof (hash_filter_t));
4021 		nxgep->hash_filter = NULL;
4022 	}
4023 
4024 	if (rx_init) {
4025 		if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
4026 			goto fail;
4027 		if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
4028 			goto fail;
4029 	}
4030 	RW_EXIT(&nxgep->filter_lock);
4031 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
4032 
4033 	return (NXGE_OK);
4034 fail:
4035 	RW_EXIT(&nxgep->filter_lock);
4036 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: "
4037 			"Unable to remove multicast address"));
4038 
4039 	return (status);
4040 }
4041 
4042 /* Set MAC address into MAC address HW registers */
4043 
4044 nxge_status_t
4045 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp)
4046 {
4047 	nxge_status_t status = NXGE_OK;
4048 
4049 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr"));
4050 
4051 	MUTEX_ENTER(&nxgep->ouraddr_lock);
4052 	/*
4053 	 * Exit if the address is same as ouraddr or multicast or broadcast
4054 	 */
4055 	if (((addrp->ether_addr_octet[0] & 01) == 1) ||
4056 		(ether_cmp(addrp, &etherbroadcastaddr) == 0) ||
4057 		(ether_cmp(addrp, &nxgep->ouraddr) == 0)) {
4058 		goto nxge_set_mac_addr_exit;
4059 	}
4060 	nxgep->ouraddr = *addrp;
4061 	/*
4062 	 * Set new interface local address and re-init device.
4063 	 * This is destructive to any other streams attached
4064 	 * to this device.
4065 	 */
4066 	RW_ENTER_WRITER(&nxgep->filter_lock);
4067 	if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
4068 		goto fail;
4069 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
4070 		goto fail;
4071 
4072 	RW_EXIT(&nxgep->filter_lock);
4073 	MUTEX_EXIT(&nxgep->ouraddr_lock);
4074 	goto nxge_set_mac_addr_end;
4075 nxge_set_mac_addr_exit:
4076 	MUTEX_EXIT(&nxgep->ouraddr_lock);
4077 nxge_set_mac_addr_end:
4078 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr"));
4079 
4080 	return (NXGE_OK);
4081 fail:
4082 	MUTEX_EXIT(&nxgep->ouraddr_lock);
4083 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: "
4084 			"Unable to set mac address"));
4085 	return (status);
4086 }
4087 
4088 static
4089 check_link_state_t
4090 nxge_check_link_stop(
4091 	nxge_t *nxge)
4092 {
4093 	/* If the poll has been cancelled, return STOP. */
4094 	MUTEX_ENTER(&nxge->poll_lock);
4095 	if (nxge->suspended || nxge->poll_state == LINK_MONITOR_STOPPING) {
4096 		nxge->poll_state = LINK_MONITOR_STOP;
4097 		nxge->nxge_link_poll_timerid = 0;
4098 		cv_broadcast(&nxge->poll_cv);
4099 		MUTEX_EXIT(&nxge->poll_lock);
4100 
4101 		NXGE_DEBUG_MSG((nxge, MAC_CTL,
4102 		    "nxge_check_%s_link(port<%d>) stopped.",
4103 		    nxge->mac.portmode == PORT_10G_FIBER ? "10g" : "mii",
4104 		    nxge->mac.portnum));
4105 		return (CHECK_LINK_STOP);
4106 	}
4107 	MUTEX_EXIT(&nxge->poll_lock);
4108 
4109 	return (CHECK_LINK_RESCHEDULE);
4110 }
4111 
4112 /* Check status of MII (MIF or PCS) link */
4113 
4114 static nxge_status_t
4115 nxge_check_mii_link(p_nxge_t nxgep)
4116 {
4117 	mii_bmsr_t bmsr_ints, bmsr_data;
4118 	mii_anlpar_t anlpar;
4119 	mii_gsr_t gsr;
4120 	p_mii_regs_t mii_regs;
4121 	nxge_status_t status = NXGE_OK;
4122 	uint8_t portn;
4123 	nxge_link_state_t link_up;
4124 
4125 	if (nxgep->nxge_magic != NXGE_MAGIC)
4126 		return (NXGE_ERROR);
4127 
4128 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
4129 		return (NXGE_OK);
4130 
4131 	portn = nxgep->mac.portnum;
4132 
4133 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>",
4134 	    portn));
4135 
4136 	mii_regs = NULL;
4137 
4138 	RW_ENTER_WRITER(&nxgep->filter_lock);
4139 
4140 	if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10)
4141 		goto nxge_check_mii_link_exit;
4142 
4143 	switch (nxgep->mac.portmode) {
4144 	default:
4145 		bmsr_data.value = 0;
4146 		if ((status = nxge_mii_read(nxgep,
4147 		    nxgep->statsp->mac_stats.xcvr_portn,
4148 #if defined(__i386)
4149 		    (uint8_t)(uint32_t)(&mii_regs->bmsr),
4150 #else
4151 		    (uint8_t)(uint64_t)(&mii_regs->bmsr),
4152 #endif
4153 		    &bmsr_data.value)) != NXGE_OK) {
4154 			goto fail;
4155 		}
4156 
4157 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4158 		    "==> nxge_check_mii_link port<0x%x> "
4159 		    "RIGHT AFTER READ bmsr_data 0x%x (nxgep->bmsr 0x%x ",
4160 		    portn, bmsr_data.value, nxgep->bmsr.value));
4161 
4162 		if (nxgep->param_arr[param_autoneg].value) {
4163 			if ((status = nxge_mii_read(nxgep,
4164 				nxgep->statsp->mac_stats.xcvr_portn,
4165 #if defined(__i386)
4166 				(uint8_t)(uint32_t)(&mii_regs->gsr),
4167 #else
4168 				(uint8_t)(uint64_t)(&mii_regs->gsr),
4169 #endif
4170 				&gsr.value)) != NXGE_OK)
4171 				goto fail;
4172 			if ((status = nxge_mii_read(nxgep,
4173 				nxgep->statsp->mac_stats.xcvr_portn,
4174 #if defined(__i386)
4175 				(uint8_t)(uint32_t)(&mii_regs->anlpar),
4176 #else
4177 				(uint8_t)(uint64_t)(&mii_regs->anlpar),
4178 #endif
4179 				&anlpar.value)) != NXGE_OK)
4180 				goto fail;
4181 			if (nxgep->mac.portmode != PORT_1G_RGMII_FIBER) {
4182 
4183 				if (nxgep->statsp->mac_stats.link_up &&
4184 				    ((nxgep->statsp->mac_stats.lp_cap_1000fdx ^
4185 				    gsr.bits.link_1000fdx) ||
4186 				    (nxgep->statsp->mac_stats.lp_cap_1000hdx ^
4187 				    gsr.bits.link_1000hdx) ||
4188 				    (nxgep->statsp->mac_stats.lp_cap_100T4 ^
4189 				    anlpar.bits.cap_100T4) ||
4190 				    (nxgep->statsp->mac_stats.lp_cap_100fdx ^
4191 				    anlpar.bits.cap_100fdx) ||
4192 				    (nxgep->statsp->mac_stats.lp_cap_100hdx ^
4193 				    anlpar.bits.cap_100hdx) ||
4194 				    (nxgep->statsp->mac_stats.lp_cap_10fdx ^
4195 				    anlpar.bits.cap_10fdx) ||
4196 				    (nxgep->statsp->mac_stats.lp_cap_10hdx ^
4197 				    anlpar.bits.cap_10hdx))) {
4198 					bmsr_data.bits.link_status = 0;
4199 				}
4200 			}
4201 		}
4202 
4203 		/* Workaround for link down issue */
4204 		if (bmsr_data.value == 0) {
4205 			cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n");
4206 			goto nxge_check_mii_link_exit;
4207 		}
4208 
4209 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4210 		    "==> nxge_check_mii_link port<0x%x> :"
4211 		    "BEFORE BMSR ^ nxgep->bmsr 0x%x bmsr_data 0x%x",
4212 		    portn, nxgep->bmsr.value, bmsr_data.value));
4213 
4214 		bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value;
4215 		nxgep->bmsr.value = bmsr_data.value;
4216 
4217 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4218 		    "==> nxge_check_mii_link port<0x%x> CALLING "
4219 		    "bmsr_data 0x%x bmsr_ints.value 0x%x",
4220 		    portn, bmsr_data.value, bmsr_ints.value));
4221 
4222 		if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints,
4223 		    &link_up)) != NXGE_OK) {
4224 			goto fail;
4225 		}
4226 		break;
4227 
4228 	case PORT_1G_SERDES:
4229 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4230 		    "==> nxge_check_mii_link port<%d> (SERDES)", portn));
4231 		if ((status = nxge_pcs_check(nxgep, portn, &link_up))
4232 		    != NXGE_OK) {
4233 			goto fail;
4234 		}
4235 		break;
4236 	}
4237 
4238 nxge_check_mii_link_exit:
4239 	RW_EXIT(&nxgep->filter_lock);
4240 	if (link_up == LINK_IS_UP) {
4241 		nxge_link_is_up(nxgep);
4242 	} else if (link_up == LINK_IS_DOWN) {
4243 		nxge_link_is_down(nxgep);
4244 	}
4245 
4246 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
4247 
4248 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>",
4249 				portn));
4250 	return (NXGE_OK);
4251 
4252 fail:
4253 	RW_EXIT(&nxgep->filter_lock);
4254 
4255 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
4256 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4257 			"nxge_check_mii_link: Failed to check link port<%d>",
4258 			portn));
4259 	return (status);
4260 }
4261 
4262 
4263 /*ARGSUSED*/
4264 static nxge_status_t
4265 nxge_check_10g_link(p_nxge_t nxgep)
4266 {
4267 	uint8_t		portn;
4268 	nxge_status_t	status = NXGE_OK;
4269 	boolean_t	link_up;
4270 	uint32_t	val;
4271 	npi_status_t	rs;
4272 
4273 	if (nxgep->nxge_magic != NXGE_MAGIC)
4274 		return (NXGE_ERROR);
4275 
4276 	if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
4277 		return (NXGE_OK);
4278 
4279 	portn = nxgep->mac.portnum;
4280 	val = 0;
4281 	rs = NPI_SUCCESS;
4282 
4283 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>",
4284 	    portn));
4285 
4286 	switch (nxgep->mac.portmode) {
4287 	default:
4288 		/*
4289 		 * Check if the phy is present in case of hot swappable phy
4290 		 */
4291 		if (nxgep->hot_swappable_phy) {
4292 			boolean_t phy_present_now = B_FALSE;
4293 
4294 			/*
4295 			 * If this is the 2nd Goa port, then check 2 addresses
4296 			 * to take care of the Goa NEM card requirements.
4297 			 */
4298 			if (portn == 1) {
4299 				if (nxge_is_phy_present(nxgep,
4300 				    BCM8706_ALT_GOA_PORT1_ADDR,
4301 				    BCM8706_DEV_ID, BCM_PHY_ID_MASK)) {
4302 					phy_present_now = B_TRUE;
4303 					nxgep->xcvr_addr =
4304 					    BCM8706_ALT_GOA_PORT1_ADDR;
4305 					goto phy_check_done;
4306 				}
4307 			}
4308 			if (nxge_is_phy_present(nxgep,
4309 			    (BCM8706_GOA_PORT_ADDR_BASE) + portn,
4310 			    BCM8706_DEV_ID, BCM_PHY_ID_MASK)) {
4311 				nxgep->xcvr_addr =
4312 				    (BCM8706_GOA_PORT_ADDR_BASE) + portn;
4313 				phy_present_now = B_TRUE;
4314 			}
4315 
4316 phy_check_done:
4317 			if (nxgep->phy_absent) {
4318 				if (phy_present_now) {
4319 				/*
4320 				 * Detect, Initialize phy and do link up
4321 				 * set xcvr vals, link_init, nxge_init
4322 				 */
4323 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4324 					    "Hot swappable phy DETECTED!!"));
4325 					nxgep->phy_absent = B_FALSE;
4326 					(void) nxge_xcvr_find(nxgep);
4327 					(void) nxge_link_init(nxgep);
4328 					if (!(nxgep->drv_state &
4329 					    STATE_HW_INITIALIZED)) {
4330 						status = nxge_init(nxgep);
4331 						if (status != NXGE_OK) {
4332 							NXGE_ERROR_MSG((nxgep,
4333 							    NXGE_ERR_CTL,
4334 							    "Hot swappable "
4335 							    "phy present, but"
4336 							    " driver init"
4337 							    "  failed..."));
4338 							goto fail;
4339 						}
4340 					}
4341 				}
4342 
4343 				goto start_link_check;
4344 
4345 			} else if (!phy_present_now) {
4346 				/*
4347 				 * Phy gone, bring link down reset xcvr vals
4348 				 */
4349 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4350 				    "Hot swappable phy REMOVED!!"));
4351 				nxgep->phy_absent = B_TRUE;
4352 				nxgep->statsp->mac_stats.link_up = 0;
4353 				nxgep->statsp->mac_stats.link_speed = 0;
4354 				nxgep->statsp->mac_stats.link_duplex = 0;
4355 				nxge_link_is_down(nxgep);
4356 				nxgep->link_notify = B_FALSE;
4357 
4358 				(void) nxge_xcvr_find(nxgep);
4359 
4360 				goto start_link_check;
4361 
4362 			}
4363 		}
4364 
4365 		status = nxge_check_bcm8704_link(nxgep, &link_up);
4366 		if (status != NXGE_OK)
4367 			goto fail;
4368 		break;
4369 	case PORT_10G_SERDES:
4370 		rs = npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
4371 		    XPCS_REG_STATUS, &val);
4372 		if (rs != 0)
4373 			goto fail;
4374 
4375 		link_up = B_FALSE;
4376 		if (val & XPCS_STATUS_LANE_ALIGN) {
4377 			link_up = B_TRUE;
4378 		}
4379 
4380 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4381 		    "==> nxge_check_10g_link port<%d> "
4382 		    "XPCS_REG_STATUS2 0x%x link_up %d",
4383 		    portn, val, link_up));
4384 
4385 		break;
4386 	}
4387 
4388 	if (link_up) {
4389 		if (nxgep->link_notify ||
4390 			nxgep->statsp->mac_stats.link_up == 0) {
4391 			if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
4392 				goto fail;
4393 			nxgep->statsp->mac_stats.link_up = 1;
4394 			nxgep->statsp->mac_stats.link_speed = 10000;
4395 			nxgep->statsp->mac_stats.link_duplex = 2;
4396 
4397 			nxge_link_is_up(nxgep);
4398 			nxgep->link_notify = B_FALSE;
4399 		}
4400 	} else {
4401 		if (nxgep->link_notify ||
4402 			nxgep->statsp->mac_stats.link_up == 1) {
4403 			if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
4404 				goto fail;
4405 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4406 					"Link down cable problem"));
4407 			nxgep->statsp->mac_stats.link_up = 0;
4408 			nxgep->statsp->mac_stats.link_speed = 0;
4409 			nxgep->statsp->mac_stats.link_duplex = 0;
4410 
4411 			nxge_link_is_down(nxgep);
4412 			nxgep->link_notify = B_FALSE;
4413 		}
4414 	}
4415 
4416 start_link_check:
4417 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
4418 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>",
4419 	    portn));
4420 	return (NXGE_OK);
4421 
4422 fail:
4423 	(void) nxge_check_link_stop(nxgep);
4424 
4425 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4426 	    "nxge_check_10g_link: Failed to check link port<%d>",
4427 	    portn));
4428 	return (status);
4429 }
4430 
4431 
4432 /* Declare link down */
4433 
4434 void
4435 nxge_link_is_down(p_nxge_t nxgep)
4436 {
4437 	p_nxge_stats_t statsp;
4438 	char link_stat_msg[64];
4439 
4440 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down"));
4441 
4442 	statsp = nxgep->statsp;
4443 	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is down",
4444 	    statsp->mac_stats.xcvr_portn);
4445 
4446 	if (nxge_no_msg == B_FALSE) {
4447 		NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
4448 	}
4449 
4450 	mac_link_update(nxgep->mach, LINK_STATE_DOWN);
4451 
4452 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down"));
4453 }
4454 
4455 /* Declare link up */
4456 
4457 void
4458 nxge_link_is_up(p_nxge_t nxgep)
4459 {
4460 	p_nxge_stats_t statsp;
4461 	char link_stat_msg[64];
4462 	uint32_t val;
4463 
4464 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up"));
4465 
4466 	statsp = nxgep->statsp;
4467 	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link is up %d Mbps ",
4468 	    statsp->mac_stats.xcvr_portn,
4469 	    statsp->mac_stats.link_speed);
4470 
4471 	if (statsp->mac_stats.link_T4)
4472 		(void) strcat(link_stat_msg, "T4");
4473 	else if (statsp->mac_stats.link_duplex == 2)
4474 		(void) strcat(link_stat_msg, "full duplex");
4475 	else
4476 		(void) strcat(link_stat_msg, "half duplex");
4477 
4478 	(void) nxge_xif_init(nxgep);
4479 
4480 	/* Clean up symbol errors incurred during link transition */
4481 	if ((nxgep->mac.portmode == PORT_10G_FIBER) ||
4482 	    (nxgep->mac.portmode == PORT_10G_SERDES)) {
4483 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
4484 					XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
4485 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
4486 					XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
4487 	}
4488 
4489 	if (nxge_no_msg == B_FALSE) {
4490 		NXGE_ERROR_MSG((nxgep, NXGE_NOTE, "%s", link_stat_msg));
4491 	}
4492 
4493 	mac_link_update(nxgep->mach, LINK_STATE_UP);
4494 
4495 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up"));
4496 }
4497 
4498 /*
4499  * Calculate the bit in the multicast address filter
4500  * that selects the given * address.
4501  * Note: For GEM, the last 8-bits are used.
4502  */
4503 uint32_t
4504 crc32_mchash(p_ether_addr_t addr)
4505 {
4506 	uint8_t *cp;
4507 	uint32_t crc;
4508 	uint32_t c;
4509 	int byte;
4510 	int bit;
4511 
4512 	cp = (uint8_t *)addr;
4513 	crc = (uint32_t)0xffffffff;
4514 	for (byte = 0; byte < 6; byte++) {
4515 		c = (uint32_t)cp[byte];
4516 		for (bit = 0; bit < 8; bit++) {
4517 			if ((c & 0x1) ^ (crc & 0x1))
4518 				crc = (crc >> 1)^0xedb88320;
4519 			else
4520 				crc = (crc >> 1);
4521 			c >>= 1;
4522 		}
4523 	}
4524 	return ((~crc) >> (32 - HASH_BITS));
4525 }
4526 
4527 /* Reset serdes */
4528 
4529 nxge_status_t
4530 nxge_serdes_reset(p_nxge_t nxgep)
4531 {
4532 	npi_handle_t		handle;
4533 
4534 	handle = nxgep->npi_handle;
4535 
4536 	ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1);
4537 	drv_usecwait(500);
4538 	ESR_REG_WR(handle, ESR_CONFIG_REG, 0);
4539 
4540 	return (NXGE_OK);
4541 }
4542 
4543 /* Monitor link status using interrupt or polling */
4544 
4545 nxge_status_t
4546 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable)
4547 {
4548 	nxge_status_t status = NXGE_OK;
4549 
4550 	/*
4551 	 * Return immediately if this is an imaginary XMAC port.
4552 	 * (At least, we don't have 4-port XMAC cards yet.)
4553 	 */
4554 	if ((nxgep->mac.portmode == PORT_10G_FIBER ||
4555 	    nxgep->mac.portmode == PORT_10G_SERDES) &&
4556 	    (nxgep->mac.portnum > 1))
4557 		return (NXGE_OK);
4558 
4559 	if (nxgep->statsp == NULL) {
4560 		/* stats has not been allocated. */
4561 		return (NXGE_OK);
4562 	}
4563 	/* Don't check link if we're not in internal loopback mode */
4564 	if (nxgep->statsp->port_stats.lb_mode != nxge_lb_normal)
4565 		return (NXGE_OK);
4566 
4567 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4568 	    "==> nxge_link_monitor port<%d> enable=%d",
4569 	    nxgep->mac.portnum, enable));
4570 	if (enable == LINK_MONITOR_START) {
4571 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
4572 			if ((status = nxge_link_intr(nxgep, LINK_INTR_START))
4573 			    != NXGE_OK)
4574 				goto fail;
4575 		} else {
4576 			timeout_id_t timerid;
4577 
4578 			if (nxge_check_link_stop(nxgep) == CHECK_LINK_STOP)
4579 				return (NXGE_OK);
4580 
4581 			if (nxgep->xcvr.check_link) {
4582 				timerid = timeout(
4583 				    (fptrv_t)(nxgep->xcvr.check_link),
4584 				    nxgep,
4585 				    drv_usectohz(LINK_MONITOR_PERIOD));
4586 				MUTEX_ENTER(&nxgep->poll_lock);
4587 				nxgep->nxge_link_poll_timerid = timerid;
4588 				MUTEX_EXIT(&nxgep->poll_lock);
4589 			} else {
4590 				return (NXGE_ERROR);
4591 			}
4592 		}
4593 	} else {
4594 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
4595 			if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP))
4596 			    != NXGE_OK)
4597 				goto fail;
4598 		} else {
4599 			clock_t rv;
4600 
4601 			MUTEX_ENTER(&nxgep->poll_lock);
4602 
4603 			/* If <timerid> == 0, the link monitor has */
4604 			/* never been started, or just now stopped. */
4605 			if (nxgep->nxge_link_poll_timerid == 0) {
4606 				MUTEX_EXIT(&nxgep->poll_lock);
4607 				return (NXGE_OK);
4608 			}
4609 
4610 			nxgep->poll_state = LINK_MONITOR_STOPPING;
4611 			rv = cv_timedwait(&nxgep->poll_cv,
4612 			    &nxgep->poll_lock,
4613 			    ddi_get_lbolt() +
4614 			    drv_usectohz(LM_WAIT_MULTIPLIER *
4615 			    LINK_MONITOR_PERIOD));
4616 			if (rv == -1) {
4617 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4618 				    "==> stopping port %d: "
4619 				    "cv_timedwait(%d) timed out",
4620 				    nxgep->mac.portnum, nxgep->poll_state));
4621 				nxgep->poll_state = LINK_MONITOR_STOP;
4622 				nxgep->nxge_link_poll_timerid = 0;
4623 			}
4624 
4625 			MUTEX_EXIT(&nxgep->poll_lock);
4626 		}
4627 	}
4628 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
4629 	    "<== nxge_link_monitor port<%d> enable=%d",
4630 	    nxgep->mac.portnum, enable));
4631 	return (NXGE_OK);
4632 fail:
4633 	return (status);
4634 }
4635 
4636 /* Set promiscous mode */
4637 
4638 nxge_status_t
4639 nxge_set_promisc(p_nxge_t nxgep, boolean_t on)
4640 {
4641 	nxge_status_t status = NXGE_OK;
4642 
4643 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_promisc: on %d", on));
4644 
4645 	nxgep->filter.all_phys_cnt = ((on) ? 1 : 0);
4646 
4647 	RW_ENTER_WRITER(&nxgep->filter_lock);
4648 
4649 	if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) {
4650 		goto fail;
4651 	}
4652 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) {
4653 		goto fail;
4654 	}
4655 
4656 	RW_EXIT(&nxgep->filter_lock);
4657 
4658 	if (on)
4659 		nxgep->statsp->mac_stats.promisc = B_TRUE;
4660 	else
4661 		nxgep->statsp->mac_stats.promisc = B_FALSE;
4662 
4663 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc"));
4664 
4665 	return (NXGE_OK);
4666 fail:
4667 	RW_EXIT(&nxgep->filter_lock);
4668 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: "
4669 	    "Unable to set promisc (%d)", on));
4670 
4671 	return (status);
4672 }
4673 
4674 /*ARGSUSED*/
4675 uint_t
4676 nxge_mif_intr(void *arg1, void *arg2)
4677 {
4678 #ifdef	NXGE_DEBUG
4679 	p_nxge_t		nxgep = (p_nxge_t)arg2;
4680 #endif
4681 #if NXGE_MIF
4682 	p_nxge_ldv_t		ldvp = (p_nxge_ldv_t)arg1;
4683 	uint32_t		status;
4684 	npi_handle_t		handle;
4685 	uint8_t			portn;
4686 	p_nxge_stats_t		statsp;
4687 #endif
4688 
4689 #ifdef	NXGE_MIF
4690 	if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
4691 		nxgep = ldvp->nxgep;
4692 	}
4693 	nxgep = ldvp->nxgep;
4694 #endif
4695 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr"));
4696 
4697 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
4698 	return (DDI_INTR_CLAIMED);
4699 
4700 mif_intr_fail:
4701 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
4702 	return (DDI_INTR_UNCLAIMED);
4703 }
4704 
4705 /*ARGSUSED*/
4706 uint_t
4707 nxge_mac_intr(void *arg1, void *arg2)
4708 {
4709 	p_nxge_t		nxgep = (p_nxge_t)arg2;
4710 	p_nxge_ldv_t		ldvp = (p_nxge_ldv_t)arg1;
4711 	p_nxge_ldg_t		ldgp;
4712 	uint32_t		status;
4713 	npi_handle_t		handle;
4714 	uint8_t			portn;
4715 	p_nxge_stats_t		statsp;
4716 	npi_status_t		rs = NPI_SUCCESS;
4717 
4718 	if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
4719 		nxgep = ldvp->nxgep;
4720 	}
4721 
4722 	ldgp = ldvp->ldgp;
4723 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: "
4724 	    "group %d", ldgp->ldg));
4725 
4726 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
4727 	/*
4728 	 * This interrupt handler is for a specific
4729 	 * mac port.
4730 	 */
4731 	statsp = (p_nxge_stats_t)nxgep->statsp;
4732 	portn = nxgep->mac.portnum;
4733 
4734 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
4735 	    "==> nxge_mac_intr: reading mac stats: port<%d>", portn));
4736 
4737 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
4738 		rs = npi_xmac_tx_get_istatus(handle, portn,
4739 					(xmac_tx_iconfig_t *)&status);
4740 		if (rs != NPI_SUCCESS)
4741 			goto npi_fail;
4742 		if (status & ICFG_XMAC_TX_ALL) {
4743 			if (status & ICFG_XMAC_TX_UNDERRUN) {
4744 				statsp->xmac_stats.tx_underflow_err++;
4745 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4746 					NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
4747 			}
4748 			if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) {
4749 				statsp->xmac_stats.tx_maxpktsize_err++;
4750 				/*
4751 				 * Do not send FMA ereport because this
4752 				 * error does not indicate HW failure.
4753 				 */
4754 			}
4755 			if (status & ICFG_XMAC_TX_OVERFLOW) {
4756 				statsp->xmac_stats.tx_overflow_err++;
4757 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4758 					NXGE_FM_EREPORT_TXMAC_OVERFLOW);
4759 			}
4760 			if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) {
4761 				statsp->xmac_stats.tx_fifo_xfr_err++;
4762 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4763 					NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR);
4764 			}
4765 			if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) {
4766 				statsp->xmac_stats.tx_byte_cnt +=
4767 							XTXMAC_BYTE_CNT_MASK;
4768 			}
4769 			if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) {
4770 				statsp->xmac_stats.tx_frame_cnt +=
4771 							XTXMAC_FRM_CNT_MASK;
4772 			}
4773 		}
4774 
4775 		rs = npi_xmac_rx_get_istatus(handle, portn,
4776 					(xmac_rx_iconfig_t *)&status);
4777 		if (rs != NPI_SUCCESS)
4778 			goto npi_fail;
4779 		if (status & ICFG_XMAC_RX_ALL) {
4780 			if (status & ICFG_XMAC_RX_OVERFLOW)
4781 				statsp->xmac_stats.rx_overflow_err++;
4782 			if (status & ICFG_XMAC_RX_UNDERFLOW) {
4783 				statsp->xmac_stats.rx_underflow_err++;
4784 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4785 					NXGE_FM_EREPORT_RXMAC_UNDERFLOW);
4786 			}
4787 			/*
4788 			 * Do not send FMA ereport for the following 3 errors
4789 			 * because they do not indicate HW failures.
4790 			 */
4791 			if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) {
4792 				statsp->xmac_stats.rx_crc_err_cnt +=
4793 							XRXMAC_CRC_ER_CNT_MASK;
4794 			}
4795 			if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) {
4796 				statsp->xmac_stats.rx_len_err_cnt +=
4797 							MAC_LEN_ER_CNT_MASK;
4798 			}
4799 			if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) {
4800 				statsp->xmac_stats.rx_viol_err_cnt +=
4801 							XRXMAC_CD_VIO_CNT_MASK;
4802 			}
4803 			if (status & ICFG_XMAC_RX_OCT_CNT_EXP) {
4804 				statsp->xmac_stats.rx_byte_cnt +=
4805 							XRXMAC_BT_CNT_MASK;
4806 			}
4807 			if (status & ICFG_XMAC_RX_HST_CNT1_EXP) {
4808 				statsp->xmac_stats.rx_hist1_cnt +=
4809 							XRXMAC_HIST_CNT1_MASK;
4810 			}
4811 			if (status & ICFG_XMAC_RX_HST_CNT2_EXP) {
4812 				statsp->xmac_stats.rx_hist2_cnt +=
4813 							XRXMAC_HIST_CNT2_MASK;
4814 			}
4815 			if (status & ICFG_XMAC_RX_HST_CNT3_EXP) {
4816 				statsp->xmac_stats.rx_hist3_cnt +=
4817 							XRXMAC_HIST_CNT3_MASK;
4818 			}
4819 			if (status & ICFG_XMAC_RX_HST_CNT4_EXP) {
4820 				statsp->xmac_stats.rx_hist4_cnt +=
4821 							XRXMAC_HIST_CNT4_MASK;
4822 			}
4823 			if (status & ICFG_XMAC_RX_HST_CNT5_EXP) {
4824 				statsp->xmac_stats.rx_hist5_cnt +=
4825 							XRXMAC_HIST_CNT5_MASK;
4826 			}
4827 			if (status & ICFG_XMAC_RX_HST_CNT6_EXP) {
4828 				statsp->xmac_stats.rx_hist6_cnt +=
4829 							XRXMAC_HIST_CNT6_MASK;
4830 			}
4831 			if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) {
4832 				statsp->xmac_stats.rx_broadcast_cnt +=
4833 							XRXMAC_BC_FRM_CNT_MASK;
4834 			}
4835 			if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) {
4836 				statsp->xmac_stats.rx_mult_cnt +=
4837 							XRXMAC_MC_FRM_CNT_MASK;
4838 			}
4839 			/*
4840 			 * Do not send FMA ereport for the following 3 errors
4841 			 * because they do not indicate HW failures.
4842 			 */
4843 			if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) {
4844 				statsp->xmac_stats.rx_frag_cnt +=
4845 							XRXMAC_FRAG_CNT_MASK;
4846 			}
4847 			if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) {
4848 				statsp->xmac_stats.rx_frame_align_err_cnt +=
4849 							XRXMAC_AL_ER_CNT_MASK;
4850 			}
4851 			if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) {
4852 				statsp->xmac_stats.rx_linkfault_err_cnt +=
4853 							XMAC_LINK_FLT_CNT_MASK;
4854 			}
4855 			if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) {
4856 				statsp->xmac_stats.rx_remotefault_err++;
4857 			}
4858 			if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) {
4859 				statsp->xmac_stats.rx_localfault_err++;
4860 			}
4861 		}
4862 
4863 		rs = npi_xmac_ctl_get_istatus(handle, portn,
4864 						(xmac_ctl_iconfig_t *)&status);
4865 		if (rs != NPI_SUCCESS)
4866 			goto npi_fail;
4867 		if (status & ICFG_XMAC_CTRL_ALL) {
4868 			if (status & ICFG_XMAC_CTRL_PAUSE_RCVD)
4869 				statsp->xmac_stats.rx_pause_cnt++;
4870 			if (status & ICFG_XMAC_CTRL_PAUSE_STATE)
4871 				statsp->xmac_stats.tx_pause_state++;
4872 			if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE)
4873 				statsp->xmac_stats.tx_nopause_state++;
4874 		}
4875 	} else if (nxgep->mac.porttype == PORT_TYPE_BMAC) {
4876 		rs = npi_bmac_tx_get_istatus(handle, portn,
4877 						(bmac_tx_iconfig_t *)&status);
4878 		if (rs != NPI_SUCCESS)
4879 			goto npi_fail;
4880 		if (status & ICFG_BMAC_TX_ALL) {
4881 			if (status & ICFG_BMAC_TX_UNDERFLOW) {
4882 				statsp->bmac_stats.tx_underrun_err++;
4883 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4884 					NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
4885 			}
4886 			if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) {
4887 				statsp->bmac_stats.tx_max_pkt_err++;
4888 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4889 					NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR);
4890 			}
4891 			if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) {
4892 				statsp->bmac_stats.tx_byte_cnt +=
4893 							BTXMAC_BYTE_CNT_MASK;
4894 			}
4895 			if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) {
4896 				statsp->bmac_stats.tx_frame_cnt +=
4897 							BTXMAC_FRM_CNT_MASK;
4898 			}
4899 		}
4900 
4901 		rs = npi_bmac_rx_get_istatus(handle, portn,
4902 						(bmac_rx_iconfig_t *)&status);
4903 		if (rs != NPI_SUCCESS)
4904 			goto npi_fail;
4905 		if (status & ICFG_BMAC_RX_ALL) {
4906 			if (status & ICFG_BMAC_RX_OVERFLOW) {
4907 				statsp->bmac_stats.rx_overflow_err++;
4908 			}
4909 			if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) {
4910 				statsp->bmac_stats.rx_frame_cnt +=
4911 							RXMAC_FRM_CNT_MASK;
4912 			}
4913 			if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) {
4914 				statsp->bmac_stats.rx_crc_err_cnt +=
4915 							BMAC_CRC_ER_CNT_MASK;
4916 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4917 					NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP);
4918 			}
4919 			if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) {
4920 				statsp->bmac_stats.rx_len_err_cnt +=
4921 							MAC_LEN_ER_CNT_MASK;
4922 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4923 				NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP);
4924 			}
4925 			if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP)
4926 				statsp->bmac_stats.rx_viol_err_cnt +=
4927 							BMAC_CD_VIO_CNT_MASK;
4928 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4929 					NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP);
4930 			}
4931 			if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) {
4932 				statsp->bmac_stats.rx_byte_cnt +=
4933 							BRXMAC_BYTE_CNT_MASK;
4934 			}
4935 			if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) {
4936 				statsp->bmac_stats.rx_align_err_cnt +=
4937 							BMAC_AL_ER_CNT_MASK;
4938 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4939 					NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP);
4940 			}
4941 
4942 			rs = npi_bmac_ctl_get_istatus(handle, portn,
4943 						(bmac_ctl_iconfig_t *)&status);
4944 			if (rs != NPI_SUCCESS)
4945 				goto npi_fail;
4946 
4947 			if (status & ICFG_BMAC_CTL_ALL) {
4948 				if (status & ICFG_BMAC_CTL_RCVPAUSE)
4949 					statsp->bmac_stats.rx_pause_cnt++;
4950 				if (status & ICFG_BMAC_CTL_INPAUSE_ST)
4951 					statsp->bmac_stats.tx_pause_state++;
4952 				if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST)
4953 					statsp->bmac_stats.tx_nopause_state++;
4954 			}
4955 		}
4956 
4957 	if (ldgp->nldvs == 1) {
4958 		(void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg,
4959 			B_TRUE, ldgp->ldg_timer);
4960 	}
4961 
4962 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
4963 	return (DDI_INTR_CLAIMED);
4964 
4965 npi_fail:
4966 	NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
4967 	return (DDI_INTR_UNCLAIMED);
4968 }
4969 
4970 nxge_status_t
4971 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up)
4972 {
4973 	uint8_t		phy_port_addr;
4974 	nxge_status_t	status = NXGE_OK;
4975 	boolean_t	rx_sig_ok;
4976 	boolean_t	pcs_blk_lock;
4977 	boolean_t	link_align;
4978 	uint16_t	val1, val2, val3;
4979 #ifdef	NXGE_DEBUG_SYMBOL_ERR
4980 	uint16_t	val_debug;
4981 	uint16_t	val;
4982 #endif
4983 
4984 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
4985 
4986 #ifdef	NXGE_DEBUG_SYMBOL_ERR
4987 	/* Check Device 3 Register Device 3 0xC809 */
4988 	(void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug);
4989 	if ((val_debug & ~0x200) != 0) {
4990 		cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n",
4991 				nxgep->mac.portnum, val_debug);
4992 		(void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18,
4993 				&val_debug);
4994 		cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n",
4995 				nxgep->mac.portnum, val_debug);
4996 	}
4997 
4998 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
4999 					XPCS_REG_DESCWERR_COUNTER, &val);
5000 	if (val != 0)
5001 		cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val);
5002 
5003 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
5004 					XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
5005 	if (val != 0)
5006 		cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val);
5007 
5008 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
5009 					XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
5010 	if (val != 0)
5011 		cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val);
5012 #endif
5013 
5014 	/* Check from BCM8704 if 10G link is up or down */
5015 
5016 	/* Check Device 1 Register 0xA bit0 */
5017 	status = nxge_mdio_read(nxgep, phy_port_addr,
5018 			BCM8704_PMA_PMD_DEV_ADDR,
5019 			BCM8704_PMD_RECEIVE_SIG_DETECT,
5020 			&val1);
5021 	if (status != NXGE_OK)
5022 		goto fail;
5023 	rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE);
5024 
5025 	/* Check Device 3 Register 0x20 bit0 */
5026 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
5027 			BCM8704_PCS_DEV_ADDR,
5028 			BCM8704_10GBASE_R_PCS_STATUS_REG,
5029 			&val2)) != NPI_SUCCESS)
5030 		goto fail;
5031 	pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE);
5032 
5033 	/* Check Device 4 Register 0x18 bit12 */
5034 	status = nxge_mdio_read(nxgep, phy_port_addr,
5035 			BCM8704_PHYXS_ADDR,
5036 			BCM8704_PHYXS_XGXS_LANE_STATUS_REG,
5037 			&val3);
5038 	if (status != NXGE_OK)
5039 		goto fail;
5040 
5041 	switch (nxgep->chip_id) {
5042 	case BCM8704_CHIP_ID:
5043 		link_align = (val3 == (XGXS_LANE_ALIGN_STATUS |
5044 		    XGXS_LANE3_SYNC | XGXS_LANE2_SYNC | XGXS_LANE1_SYNC |
5045 		    XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE;
5046 		break;
5047 	case BCM8706_CHIP_ID:
5048 		link_align = ((val3 & XGXS_LANE_ALIGN_STATUS) &&
5049 		    (val3 & XGXS_LANE3_SYNC) && (val3 & XGXS_LANE2_SYNC) &&
5050 		    (val3 & XGXS_LANE1_SYNC) && (val3 & XGXS_LANE0_SYNC)) ?
5051 		    B_TRUE : B_FALSE;
5052 		break;
5053 	default:
5054 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_check_bcm8704_link:"
5055 		    "Unknown chip ID [0x%x]", nxgep->chip_id));
5056 		goto fail;
5057 	}
5058 
5059 
5060 #ifdef	NXGE_DEBUG_ALIGN_ERR
5061 	/* Temp workaround for link down issue */
5062 	if (pcs_blk_lock == B_FALSE) {
5063 		if (val2 != 0x4) {
5064 			pcs_blk_lock = B_TRUE;
5065 			cmn_err(CE_NOTE,
5066 				"!LINK DEBUG: port%d PHY Dev3 "
5067 				"Reg 0x20 = 0x%x\n",
5068 				nxgep->mac.portnum, val2);
5069 		}
5070 	}
5071 
5072 	if (link_align == B_FALSE) {
5073 		if (val3 != 0x140f) {
5074 			link_align = B_TRUE;
5075 			cmn_err(CE_NOTE,
5076 				"!LINK DEBUG: port%d PHY Dev4 "
5077 				"Reg 0x18 = 0x%x\n",
5078 				nxgep->mac.portnum, val3);
5079 		}
5080 	}
5081 
5082 	if (rx_sig_ok == B_FALSE) {
5083 		if ((val2 == 0) || (val3 == 0)) {
5084 			rx_sig_ok = B_TRUE;
5085 			cmn_err(CE_NOTE,
5086 				"!LINK DEBUG: port %d Dev3 or Dev4 read zero\n",
5087 				nxgep->mac.portnum);
5088 		}
5089 	}
5090 #endif
5091 
5092 	*link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) &&
5093 			(link_align == B_TRUE)) ? B_TRUE : B_FALSE;
5094 
5095 	return (NXGE_OK);
5096 fail:
5097 	return (status);
5098 }
5099 
5100 nxge_status_t
5101 nxge_10g_link_led_on(p_nxge_t nxgep)
5102 {
5103 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE)
5104 	    != NPI_SUCCESS)
5105 		return (NXGE_ERROR);
5106 	else
5107 		return (NXGE_OK);
5108 }
5109 
5110 nxge_status_t
5111 nxge_10g_link_led_off(p_nxge_t nxgep)
5112 {
5113 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE)
5114 	    != NPI_SUCCESS)
5115 		return (NXGE_ERROR);
5116 	else
5117 		return (NXGE_OK);
5118 }
5119 
5120 static boolean_t
5121 nxge_is_phy_present(p_nxge_t nxgep, int addr, uint32_t id, uint32_t mask)
5122 {
5123 	uint32_t pma_pmd_id = 0;
5124 	uint32_t pcs_id = 0;
5125 	uint32_t phy_id = 0;
5126 
5127 	pma_pmd_id = nxge_get_cl45_pma_pmd_id(nxgep, addr);
5128 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5129 	    "nxge_is_phy_present: pma_pmd_id[0x%x]", pma_pmd_id));
5130 	if ((pma_pmd_id & mask) == (id & mask))
5131 		goto found_phy;
5132 	pcs_id = nxge_get_cl45_pcs_id(nxgep, addr);
5133 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5134 	    "nxge_is_phy_present: pcs_id[0x%x]", pcs_id));
5135 	if ((pcs_id & mask) == (id & mask))
5136 		goto found_phy;
5137 	phy_id = nxge_get_cl22_phy_id(nxgep, addr);
5138 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5139 	    "nxge_is_phy_present: phy_id[0x%x]", phy_id));
5140 	if ((phy_id & mask) == (id & mask))
5141 		goto found_phy;
5142 
5143 	return (B_FALSE);
5144 
5145 found_phy:
5146 	return (B_TRUE);
5147 }
5148 
5149 /* Check if the given id read using the given MDIO Clause is supported */
5150 
5151 static boolean_t
5152 nxge_is_supported_phy(uint32_t id, uint8_t type)
5153 {
5154 	int		i;
5155 	int		cl45_arr_len = NUM_CLAUSE_45_IDS;
5156 	int		cl22_arr_len = NUM_CLAUSE_22_IDS;
5157 	boolean_t	found = B_FALSE;
5158 
5159 	switch (type) {
5160 	case CLAUSE_45_TYPE:
5161 		for (i = 0; i < cl45_arr_len; i++) {
5162 			if ((nxge_supported_cl45_ids[i] & BCM_PHY_ID_MASK) ==
5163 			    (id & BCM_PHY_ID_MASK)) {
5164 				found = B_TRUE;
5165 				break;
5166 			}
5167 		}
5168 		break;
5169 	case CLAUSE_22_TYPE:
5170 		for (i = 0; i < cl22_arr_len; i++) {
5171 			if ((nxge_supported_cl22_ids[i] & BCM_PHY_ID_MASK) ==
5172 			    (id & BCM_PHY_ID_MASK)) {
5173 				found = B_TRUE;
5174 				break;
5175 			}
5176 		}
5177 		break;
5178 	default:
5179 		break;
5180 	}
5181 
5182 	return (found);
5183 }
5184 
5185 static uint32_t
5186 nxge_get_cl45_pma_pmd_id(p_nxge_t nxgep, int phy_port)
5187 {
5188 	uint16_t	val1 = 0;
5189 	uint16_t	val2 = 0;
5190 	uint32_t	pma_pmd_dev_id = 0;
5191 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
5192 
5193 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
5194 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR,
5195 	    NXGE_DEV_ID_REG_1, &val1);
5196 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PMA_PMD_DEV_ADDR,
5197 	    NXGE_DEV_ID_REG_2, &val2);
5198 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
5199 
5200 	pma_pmd_dev_id = val1;
5201 	pma_pmd_dev_id = (pma_pmd_dev_id << 16);
5202 	pma_pmd_dev_id |= val2;
5203 
5204 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PMA/PMD "
5205 	    "devid[0x%llx]", phy_port, pma_pmd_dev_id));
5206 
5207 	return (pma_pmd_dev_id);
5208 }
5209 
5210 static uint32_t
5211 nxge_get_cl45_pcs_id(p_nxge_t nxgep, int phy_port)
5212 {
5213 	uint16_t	val1 = 0;
5214 	uint16_t	val2 = 0;
5215 	uint32_t	pcs_dev_id = 0;
5216 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
5217 
5218 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mdio_lock);
5219 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR,
5220 	    NXGE_DEV_ID_REG_1, &val1);
5221 	(void) npi_mac_mif_mdio_read(handle, phy_port, NXGE_PCS_DEV_ADDR,
5222 	    NXGE_DEV_ID_REG_2, &val2);
5223 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mdio_lock);
5224 
5225 	pcs_dev_id = val1;
5226 	pcs_dev_id = (pcs_dev_id << 16);
5227 	pcs_dev_id |= val2;
5228 
5229 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS "
5230 	    "devid[0x%llx]", phy_port, pcs_dev_id));
5231 
5232 	return (pcs_dev_id);
5233 }
5234 
5235 static uint32_t
5236 nxge_get_cl22_phy_id(p_nxge_t nxgep, int phy_port)
5237 {
5238 	uint16_t	val1 = 0;
5239 	uint16_t	val2 = 0;
5240 	uint32_t	phy_id = 0;
5241 	npi_handle_t	handle = NXGE_DEV_NPI_HANDLE(nxgep);
5242 	npi_status_t	npi_status = NPI_SUCCESS;
5243 
5244 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mii_lock);
5245 	npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_1,
5246 	    &val1);
5247 	if (npi_status != NPI_SUCCESS) {
5248 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
5249 		    "clause 22 read to reg 2 failed!!!"));
5250 		goto exit;
5251 	}
5252 	npi_status = npi_mac_mif_mii_read(handle, phy_port, NXGE_PHY_ID_REG_2,
5253 	    &val2);
5254 	if (npi_status != 0) {
5255 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
5256 		    "clause 22 read to reg 3 failed!!!"));
5257 		goto exit;
5258 	}
5259 	phy_id = val1;
5260 	phy_id = (phy_id << 16);
5261 	phy_id |= val2;
5262 
5263 exit:
5264 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mii_lock);
5265 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID [0x%llx]",
5266 	    phy_port, phy_id));
5267 
5268 	return (phy_id);
5269 }
5270 
5271 /*
5272  * Scan the PHY ports 0 through 31 to get the PHY ID using Clause 22 MDIO
5273  * read and the PMA/PMD device ID and the PCS device ID using Clause 45 MDIO
5274  * read. Then use the values obtained to determine the phy type of each port
5275  * and the Neptune type.
5276  */
5277 
5278 nxge_status_t
5279 nxge_scan_ports_phy(p_nxge_t nxgep, p_nxge_hw_list_t hw_p)
5280 {
5281 	int		i, j, k, l;
5282 	uint32_t	pma_pmd_dev_id = 0;
5283 	uint32_t	pcs_dev_id = 0;
5284 	uint32_t	phy_id = 0;
5285 	uint32_t	port_pma_pmd_dev_id[NXGE_PORTS_NEPTUNE];
5286 	uint32_t	port_pcs_dev_id[NXGE_PORTS_NEPTUNE];
5287 	uint32_t	port_phy_id[NXGE_PORTS_NEPTUNE];
5288 	uint8_t		pma_pmd_dev_fd[NXGE_MAX_PHY_PORTS];
5289 	uint8_t		pcs_dev_fd[NXGE_MAX_PHY_PORTS];
5290 	uint8_t		phy_fd_arr[NXGE_MAX_PHY_PORTS];
5291 	uint8_t		port_fd_arr[NXGE_MAX_PHY_PORTS];
5292 	uint8_t		total_port_fd, total_phy_fd;
5293 	nxge_status_t	status = NXGE_OK;
5294 
5295 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_scan_ports_phy: "));
5296 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5297 	    "==> nxge_scan_ports_phy: nxge niu_type[0x%x]",
5298 	    nxgep->niu_type));
5299 
5300 	j = k = l = 0;
5301 	total_port_fd = total_phy_fd = 0;
5302 	/*
5303 	 * Clause 45 and Clause 22 port/phy addresses 0 through 7 are reserved
5304 	 * for on chip serdes usages.
5305 	 */
5306 	for (i = NXGE_EXT_PHY_PORT_ST; i < NXGE_MAX_PHY_PORTS; i++) {
5307 
5308 		pma_pmd_dev_id = nxge_get_cl45_pma_pmd_id(nxgep, i);
5309 
5310 		if (nxge_is_supported_phy(pma_pmd_dev_id, CLAUSE_45_TYPE)) {
5311 			pma_pmd_dev_fd[i] = 1;
5312 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] "
5313 			    "PMA/PMD dev found", i));
5314 			if (j < NXGE_PORTS_NEPTUNE) {
5315 				port_pma_pmd_dev_id[j] = pma_pmd_dev_id &
5316 				    BCM_PHY_ID_MASK;
5317 				port_fd_arr[j] = (uint8_t)i;
5318 				j++;
5319 			}
5320 		} else {
5321 			pma_pmd_dev_fd[i] = 0;
5322 		}
5323 
5324 		pcs_dev_id = nxge_get_cl45_pcs_id(nxgep, i);
5325 
5326 		if (nxge_is_supported_phy(pcs_dev_id, CLAUSE_45_TYPE)) {
5327 			pcs_dev_fd[i] = 1;
5328 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PCS "
5329 			    "dev found", i));
5330 			if (k < NXGE_PORTS_NEPTUNE) {
5331 				port_pcs_dev_id[k] = pcs_dev_id &
5332 				    BCM_PHY_ID_MASK;
5333 				port_fd_arr[k] = (uint8_t)i;
5334 				k++;
5335 			}
5336 		} else {
5337 			pcs_dev_fd[i] = 0;
5338 		}
5339 
5340 		if (pcs_dev_fd[i] || pma_pmd_dev_fd[i]) {
5341 			total_port_fd ++;
5342 		}
5343 
5344 		phy_id = nxge_get_cl22_phy_id(nxgep, i);
5345 
5346 		if (nxge_is_supported_phy(phy_id, CLAUSE_22_TYPE)) {
5347 			total_phy_fd ++;
5348 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "port[%d] PHY ID"
5349 			    "found", i));
5350 			if (l < NXGE_PORTS_NEPTUNE) {
5351 				port_phy_id[l] = phy_id & BCM_PHY_ID_MASK;
5352 				phy_fd_arr[l] = (uint8_t)i;
5353 				l++;
5354 			}
5355 		}
5356 	}
5357 
5358 	switch (total_port_fd) {
5359 	case 2:
5360 		switch (total_phy_fd) {
5361 		case 2:
5362 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5363 			    "Unsupported neptune type 1"));
5364 			goto error_exit;
5365 		case 1:
5366 			/* TODO - 2 10G, 1 1G */
5367 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5368 			    "Unsupported neptune type 2 10G, 1 1G"));
5369 			goto error_exit;
5370 		case 0:
5371 			/* 2 10G */
5372 			if (((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) &&
5373 			    (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) ||
5374 			    ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) &&
5375 			    (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) {
5376 
5377 				/*
5378 				 * Check the first phy port address against
5379 				 * the known phy start addresses to determine
5380 				 * the platform type.
5381 				 */
5382 
5383 				switch (port_fd_arr[0]) {
5384 				case BCM8704_NEPTUNE_PORT_ADDR_BASE:
5385 					hw_p->niu_type = NEPTUNE_2_10GF;
5386 					hw_p->platform_type =
5387 					    P_NEPTUNE_ATLAS_2PORT;
5388 					break;
5389 				case BCM8706_GOA_PORT_ADDR_BASE:
5390 					if (hw_p->platform_type !=
5391 					    P_NEPTUNE_NIU) {
5392 						hw_p->platform_type =
5393 						    P_NEPTUNE_GENERIC;
5394 						hw_p->niu_type =
5395 						    NEPTUNE_2_10GF;
5396 					}
5397 					break;
5398 				default:
5399 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5400 					    "Unsupported neptune type 2 - 1"));
5401 					goto error_exit;
5402 				}
5403 
5404 				for (i = 0; i < 2; i++) {
5405 					hw_p->xcvr_addr[i] = port_fd_arr[i];
5406 				}
5407 			} else {
5408 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5409 				    "Unsupported neptune type 2"));
5410 				goto error_exit;
5411 			}
5412 			break;
5413 		case 4:
5414 			/* Maramba with 2 XAUI */
5415 			if ((((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) &&
5416 			    (port_pcs_dev_id[1] == PHY_BCM8704_FAMILY)) ||
5417 			    ((port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) &&
5418 			    (port_pma_pmd_dev_id[1] == PHY_BCM8704_FAMILY))) &&
5419 			    ((port_phy_id[0] == PHY_BCM5464R_FAMILY) &&
5420 			    (port_phy_id[1] == PHY_BCM5464R_FAMILY) &&
5421 			    (port_phy_id[2] == PHY_BCM5464R_FAMILY) &&
5422 			    (port_phy_id[3] == PHY_BCM5464R_FAMILY))) {
5423 
5424 				/*
5425 				 * Check the first phy port address against
5426 				 * the known phy start addresses to determine
5427 				 * the platform type.
5428 				 */
5429 				switch (phy_fd_arr[0]) {
5430 				case BCM5464_MARAMBA_P0_PORT_ADDR_BASE:
5431 					hw_p->platform_type =
5432 					    P_NEPTUNE_MARAMBA_P0;
5433 					break;
5434 				case BCM5464_MARAMBA_P1_PORT_ADDR_BASE:
5435 					hw_p->platform_type =
5436 					    P_NEPTUNE_MARAMBA_P1;
5437 					break;
5438 				default:
5439 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5440 					    "Unknown port %d...Cannot "
5441 					    "determine platform type", i));
5442 					goto error_exit;
5443 				}
5444 
5445 				hw_p->niu_type = NEPTUNE_2_10GF_2_1GC;
5446 
5447 				hw_p->xcvr_addr[0] = port_fd_arr[0];
5448 				hw_p->xcvr_addr[1] = port_fd_arr[1];
5449 				hw_p->xcvr_addr[2] = phy_fd_arr[2];
5450 				hw_p->xcvr_addr[3] = phy_fd_arr[3];
5451 
5452 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5453 				    "Maramba with 2 XAUI"));
5454 			} else {
5455 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5456 				    "Unsupported neptune type 3"));
5457 				goto error_exit;
5458 			}
5459 			break;
5460 		default:
5461 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5462 			    "Unsupported neptune type 5"));
5463 			goto error_exit;
5464 		}
5465 		break;
5466 	case 1:
5467 		switch (total_phy_fd) {
5468 		case 3:
5469 			/*
5470 			 * TODO 3 1G, 1 10G mode.
5471 			 * Differentiate between 1_1G_1_10G_2_1G and
5472 			 * 1_10G_3_1G
5473 			 */
5474 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5475 			    "Unsupported neptune type 7"));
5476 			goto error_exit;
5477 		case 2:
5478 			/*
5479 			 * TODO 2 1G, 1 10G mode.
5480 			 * Differentiate between 1_1G_1_10G_1_1G and
5481 			 * 1_10G_2_1G
5482 			 */
5483 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5484 			    "Unsupported neptune type 8"));
5485 			goto error_exit;
5486 		case 1:
5487 			/*
5488 			 * TODO 1 1G, 1 10G mode.
5489 			 * Differentiate between 1_1G_1_10G and
5490 			 * 1_10G_1_1G
5491 			 */
5492 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5493 			    "Unsupported neptune type 9"));
5494 			goto error_exit;
5495 		case 0:
5496 			/* 1 10G mode, N2 with 1 XAUI */
5497 			if (port_pcs_dev_id[0] == PHY_BCM8704_FAMILY ||
5498 			    port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY) {
5499 
5500 				/*
5501 				 * Check the first phy port address against
5502 				 * the known phy start addresses to determine
5503 				 * the platform type.
5504 				 */
5505 
5506 				switch (port_fd_arr[0]) {
5507 				case BCM8704_N2_PORT_ADDR_BASE:
5508 				case (BCM8704_N2_PORT_ADDR_BASE + 1):
5509 				case BCM8706_ALT_GOA_PORT1_ADDR:
5510 					if (hw_p->platform_type !=
5511 					    P_NEPTUNE_NIU) {
5512 						hw_p->platform_type =
5513 						    P_NEPTUNE_GENERIC;
5514 						hw_p->niu_type =
5515 						    NEPTUNE_2_10GF;
5516 					}
5517 					break;
5518 				default:
5519 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5520 					    "Unsupported neptune type 10"));
5521 					goto error_exit;
5522 				}
5523 
5524 				hw_p->xcvr_addr[nxgep->function_num] =
5525 				    port_fd_arr[0];
5526 			} else {
5527 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5528 				    "Unsupported neptune type 10 - 1"));
5529 				goto error_exit;
5530 			}
5531 			break;
5532 		case 4:
5533 			/* Maramba with 1 XAUI */
5534 			if ((port_pcs_dev_id[0] == PHY_BCM8704_FAMILY) ||
5535 			    (port_pma_pmd_dev_id[0] == PHY_BCM8704_FAMILY)) {
5536 
5537 				/*
5538 				 * Check the first phy port address against
5539 				 * the known phy start addresses to determine
5540 				 * the platform type.
5541 				 */
5542 				switch (phy_fd_arr[0]) {
5543 				case BCM5464_MARAMBA_P0_PORT_ADDR_BASE:
5544 					hw_p->platform_type =
5545 					    P_NEPTUNE_MARAMBA_P0;
5546 					break;
5547 				case BCM5464_MARAMBA_P1_PORT_ADDR_BASE:
5548 					hw_p->platform_type =
5549 					    P_NEPTUNE_MARAMBA_P1;
5550 					break;
5551 				default:
5552 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5553 					    "Unknown port %d...Cannot "
5554 					    "determine platform type 10 - 2",
5555 					    i));
5556 					goto error_exit;
5557 				}
5558 
5559 				/*
5560 				 * Check the BCM8704 address to determine
5561 				 * if XAUI is in port 0 or port 1.
5562 				 */
5563 				switch (port_fd_arr[0]) {
5564 				case BCM8704_MARAMBA_PORT_ADDR_BASE:
5565 					hw_p->niu_type = NEPTUNE_1_10GF_3_1GC;
5566 					hw_p->xcvr_addr[0] = port_fd_arr[0];
5567 					for (i = 1; i < NXGE_MAX_PORTS; i++) {
5568 						hw_p->xcvr_addr[i] =
5569 						    phy_fd_arr[i];
5570 					}
5571 					break;
5572 				case (BCM8704_MARAMBA_PORT_ADDR_BASE + 1):
5573 					hw_p->niu_type =
5574 					    NEPTUNE_1_1GC_1_10GF_2_1GC;
5575 					hw_p->xcvr_addr[0] = phy_fd_arr[0];
5576 					hw_p->xcvr_addr[1] = port_fd_arr[0];
5577 					hw_p->xcvr_addr[2] = phy_fd_arr[2];
5578 					hw_p->xcvr_addr[3] = phy_fd_arr[3];
5579 					break;
5580 				default:
5581 					NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5582 					    "Unsupported neptune type 11"));
5583 					goto error_exit;
5584 				}
5585 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5586 				    "Maramba with 1 XAUI"));
5587 			} else {
5588 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5589 				    "Unsupported neptune type 12"));
5590 				goto error_exit;
5591 			}
5592 			break;
5593 		default:
5594 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5595 			    "Unsupported neptune type 13"));
5596 			goto error_exit;
5597 		}
5598 		break;
5599 	case 0:
5600 		switch (total_phy_fd) {
5601 		case 4:
5602 			if ((port_phy_id[0] == PHY_BCM5464R_FAMILY) &&
5603 			    (port_phy_id[1] == PHY_BCM5464R_FAMILY) &&
5604 			    (port_phy_id[2] == PHY_BCM5464R_FAMILY) &&
5605 			    (port_phy_id[3] == PHY_BCM5464R_FAMILY)) {
5606 
5607 				/*
5608 				 * Check the first phy port address against
5609 				 * the known phy start addresses to determine
5610 				 * the platform type.
5611 				 */
5612 				switch (phy_fd_arr[0]) {
5613 				case BCM5464_MARAMBA_P1_PORT_ADDR_BASE:
5614 					hw_p->platform_type =
5615 					    P_NEPTUNE_MARAMBA_P1;
5616 					break;
5617 				case BCM5464_NEPTUNE_PORT_ADDR_BASE:
5618 					hw_p->platform_type =
5619 					    P_NEPTUNE_ATLAS_4PORT;
5620 					break;
5621 				default:
5622 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5623 					    "Unknown port %d...Cannot "
5624 					    "determine platform type", i));
5625 					goto error_exit;
5626 				}
5627 				hw_p->niu_type = NEPTUNE_4_1GC;
5628 				for (i = 0; i < NXGE_MAX_PORTS; i++) {
5629 					hw_p->xcvr_addr[i] = phy_fd_arr[i];
5630 				}
5631 			} else {
5632 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5633 				    "Unsupported neptune type 14"));
5634 				goto error_exit;
5635 			}
5636 			break;
5637 		case 3:
5638 			/* TODO 3 1G mode */
5639 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5640 			    "Unsupported neptune type 15"));
5641 			goto error_exit;
5642 		case 2:
5643 			/* TODO 2 1G mode */
5644 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5645 			    "Unsupported neptune type 16"));
5646 			goto error_exit;
5647 		case 1:
5648 			/* TODO 1 1G mode */
5649 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5650 			    "Unsupported neptune type 17"));
5651 			goto error_exit;
5652 		default:
5653 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5654 			    "Unsupported neptune type 18, total phy fd %d",
5655 			    total_phy_fd));
5656 			goto error_exit;
5657 		}
5658 		break;
5659 	default:
5660 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5661 		    "Unsupported neptune type 19"));
5662 		goto error_exit;
5663 	}
5664 
5665 scan_exit:
5666 
5667 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_scan_ports_phy, "
5668 	    "niu type [0x%x]\n", hw_p->niu_type));
5669 	return (status);
5670 
5671 error_exit:
5672 	return (NXGE_ERROR);
5673 }
5674 
5675 boolean_t
5676 nxge_is_valid_local_mac(ether_addr_st mac_addr)
5677 {
5678 	if ((mac_addr.ether_addr_octet[0] & 0x01) ||
5679 	    (ether_cmp(&mac_addr, &etherbroadcastaddr) == 0) ||
5680 	    (ether_cmp(&mac_addr, &etherzeroaddr) == 0))
5681 		return (B_FALSE);
5682 	else
5683 		return (B_TRUE);
5684 }
5685 
5686 static void
5687 nxge_bcm5464_link_led_off(p_nxge_t nxgep) {
5688 
5689 	npi_status_t rs = NPI_SUCCESS;
5690 	uint8_t xcvr_portn;
5691 	uint8_t	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
5692 
5693 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_bcm5464_link_led_off"));
5694 
5695 	if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P1) {
5696 		xcvr_portn = BCM5464_MARAMBA_P1_PORT_ADDR_BASE;
5697 	} else if (nxgep->nxge_hw_p->platform_type == P_NEPTUNE_MARAMBA_P0) {
5698 		xcvr_portn = BCM5464_MARAMBA_P0_PORT_ADDR_BASE;
5699 	}
5700 	/*
5701 	 * For Altas 4-1G copper, Xcvr port numbers are
5702 	 * swapped with ethernet port number. This is
5703 	 * designed for better signal integrity in routing.
5704 	 */
5705 	switch (portn) {
5706 	case 0:
5707 		xcvr_portn += 3;
5708 		break;
5709 	case 1:
5710 		xcvr_portn += 2;
5711 		break;
5712 	case 2:
5713 		xcvr_portn += 1;
5714 		break;
5715 	case 3:
5716 	default:
5717 		break;
5718 	}
5719 
5720 	MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_mii_lock);
5721 	rs = npi_mac_mif_mii_write(nxgep->npi_handle,
5722 	    xcvr_portn, BCM5464R_MISC, 0xb4ee);
5723 	if (rs != NPI_SUCCESS) {
5724 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5725 		    "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
5726 		    "returned error 0x[%x]", rs));
5727 		MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mii_lock);
5728 		return;
5729 	}
5730 
5731 	rs = npi_mac_mif_mii_write(nxgep->npi_handle,
5732 	    xcvr_portn, BCM5464R_MISC, 0xb8ee);
5733 	if (rs != NPI_SUCCESS) {
5734 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5735 		    "<== nxge_bcm5464_link_led_off: npi_mac_mif_mii_write "
5736 		    "returned error 0x[%x]", rs));
5737 	}
5738 
5739 	MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_mii_lock);
5740 }
5741 
5742 static nxge_status_t
5743 nxge_mii_get_link_mode(p_nxge_t nxgep)
5744 {
5745 	p_nxge_stats_t	statsp;
5746 	uint8_t		xcvr_portn;
5747 	p_mii_regs_t	mii_regs;
5748 	mii_mode_control_stat_t	mode;
5749 	int		status = NXGE_OK;
5750 
5751 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_get_link_mode"));
5752 
5753 	statsp = nxgep->statsp;
5754 	xcvr_portn = statsp->mac_stats.xcvr_portn;
5755 	mii_regs = NULL;
5756 	mode.value = 0;
5757 	mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG;
5758 #if defined(__i386)
5759 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
5760 	    (uint8_t)(uint32_t)(&mii_regs->shadow),
5761 	    mode.value)) != NXGE_OK) {
5762 		goto fail;
5763 #else
5764 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
5765 	    (uint8_t)(uint64_t)(&mii_regs->shadow),
5766 	    mode.value)) != NXGE_OK) {
5767 		goto fail;
5768 #endif
5769 	}
5770 #if defined(__i386)
5771 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
5772 	    (uint8_t)(uint32_t)(&mii_regs->shadow),
5773 	    &mode.value)) != NXGE_OK) {
5774 		goto fail;
5775 	}
5776 #else
5777 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
5778 	    (uint8_t)(uint64_t)(&mii_regs->shadow),
5779 	    &mode.value)) != NXGE_OK) {
5780 		goto fail;
5781 	}
5782 #endif
5783 
5784 	if (mode.bits.mode == NXGE_MODE_SELECT_FIBER) {
5785 		nxgep->mac.portmode = PORT_1G_RGMII_FIBER;
5786 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5787 		    "nxge_mii_get_link_mode: fiber mode"));
5788 	}
5789 
5790 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5791 	    "nxge_mii_get_link_mode: "
5792 	    "(address 0x%x) port 0x%x mode value 0x%x link mode 0x%x",
5793 	    NXGE_MII_MODE_CONTROL_REG, xcvr_portn,
5794 	    mode.value, nxgep->mac.portmode));
5795 
5796 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
5797 	    "<== nxge_mii_get_link_mode"));
5798 	return (status);
5799 fail:
5800 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5801 	    "<== nxge_mii_get_link_mode (failed)"));
5802 	return (NXGE_ERROR);
5803 }
5804 
5805 #ifdef NXGE_DEBUG
5806 static void
5807 nxge_mii_dump(p_nxge_t nxgep)
5808 {
5809 	p_nxge_stats_t	statsp;
5810 	uint8_t		xcvr_portn;
5811 	p_mii_regs_t	mii_regs;
5812 	mii_bmcr_t	bmcr;
5813 	mii_bmsr_t	bmsr;
5814 	mii_idr1_t	idr1;
5815 	mii_idr2_t	idr2;
5816 	mii_mode_control_stat_t	mode;
5817 
5818 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "==> nxge_mii_dump"));
5819 
5820 	statsp = nxgep->statsp;
5821 	xcvr_portn = statsp->mac_stats.xcvr_portn;
5822 
5823 	mii_regs = NULL;
5824 
5825 #if defined(__i386)
5826 	(void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn,
5827 	    (uint8_t)(uint32_t)(&mii_regs->bmcr), &bmcr.value);
5828 #else
5829 	(void) nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn,
5830 	    (uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value);
5831 #endif
5832 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5833 	    "nxge_mii_dump: bmcr (0) xcvr 0x%x value 0x%x",
5834 	    xcvr_portn, bmcr.value));
5835 
5836 #if defined(__i386)
5837 	(void) nxge_mii_read(nxgep,
5838 	    nxgep->statsp->mac_stats.xcvr_portn,
5839 	    (uint8_t)(uint32_t)(&mii_regs->bmsr), &bmsr.value);
5840 #else
5841 	(void) nxge_mii_read(nxgep,
5842 	    nxgep->statsp->mac_stats.xcvr_portn,
5843 	    (uint8_t)(uint64_t)(&mii_regs->bmsr), &bmsr.value);
5844 #endif
5845 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5846 	    "nxge_mii_dump: bmsr (1) xcvr 0x%x value 0x%x",
5847 	    xcvr_portn, bmsr.value));
5848 
5849 #if defined(__i386)
5850 	(void) nxge_mii_read(nxgep,
5851 	    nxgep->statsp->mac_stats.xcvr_portn,
5852 	    (uint8_t)(uint32_t)(&mii_regs->idr1), &idr1.value);
5853 #else
5854 	(void) nxge_mii_read(nxgep,
5855 	    nxgep->statsp->mac_stats.xcvr_portn,
5856 	    (uint8_t)(uint64_t)(&mii_regs->idr1), &idr1.value);
5857 #endif
5858 
5859 
5860 #if defined(__i386)
5861 	(void) nxge_mii_read(nxgep,
5862 	    nxgep->statsp->mac_stats.xcvr_portn,
5863 	    (uint8_t)(uint32_t)(&mii_regs->idr2), &idr2.value);
5864 #else
5865 	(void) nxge_mii_read(nxgep,
5866 	    nxgep->statsp->mac_stats.xcvr_portn,
5867 	    (uint8_t)(uint64_t)(&mii_regs->idr2), &idr2.value);
5868 #endif
5869 
5870 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5871 	    "nxge_mii_dump: idr1 (2) xcvr 0x%x value 0x%x",
5872 	    xcvr_portn, idr1.value));
5873 
5874 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5875 	    "nxge_mii_dump: idr2 (3) xcvr 0x%x value 0x%x",
5876 	    xcvr_portn, idr2.value));
5877 
5878 	mode.value = 0;
5879 	mode.bits.shadow = NXGE_MII_MODE_CONTROL_REG;
5880 
5881 #if defined(__i386)
5882 	(void) nxge_mii_write(nxgep, xcvr_portn,
5883 	    (uint8_t)(uint32_t)(&mii_regs->shadow), mode.value);
5884 
5885 	(void) nxge_mii_read(nxgep, xcvr_portn,
5886 	    (uint8_t)(uint32_t)(&mii_regs->shadow), &mode.value);
5887 #else
5888 	(void) nxge_mii_write(nxgep, xcvr_portn,
5889 	    (uint8_t)(uint64_t)(&mii_regs->shadow), mode.value);
5890 
5891 	(void) nxge_mii_read(nxgep, xcvr_portn,
5892 	    (uint8_t)(uint64_t)(&mii_regs->shadow), &mode.value);
5893 #endif
5894 
5895 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5896 	    "nxge_mii_dump: mode control xcvr 0x%x value 0x%x",
5897 	    xcvr_portn, mode.value));
5898 }
5899 #endif
5900