xref: /titanic_44/usr/src/uts/common/io/nxge/nxge_mac.c (revision 5151fb1220e0ceafdc172203863c73da4285c170)
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 2007 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 extern uint32_t nxge_no_link_notify;
32 extern uint32_t nxge_no_msg;
33 extern uint32_t nxge_lb_dbg;
34 extern nxge_os_mutex_t	nxge_mdio_lock;
35 extern nxge_os_mutex_t	nxge_mii_lock;
36 extern boolean_t nxge_jumbo_enable;
37 
38 /*
39  * Ethernet broadcast address definition.
40  */
41 static ether_addr_st etherbroadcastaddr =
42 				{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
43 
44 nxge_status_t nxge_mac_init(p_nxge_t);
45 
46 /* Initialize the entire MAC and physical layer */
47 
48 nxge_status_t
49 nxge_mac_init(p_nxge_t nxgep)
50 {
51 	uint8_t			portn;
52 	nxge_status_t		status = NXGE_OK;
53 
54 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
55 
56 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mac_init: port<%d>", portn));
57 
58 	nxgep->mac.portnum = portn;
59 	nxgep->mac.porttype = PORT_TYPE_XMAC;
60 
61 	if ((portn == BMAC_PORT_0) || (portn == BMAC_PORT_1))
62 		nxgep->mac.porttype = PORT_TYPE_BMAC;
63 
64 	/* Initialize XIF to configure a network mode */
65 	if ((status = nxge_xif_init(nxgep)) != NXGE_OK) {
66 		goto fail;
67 	}
68 
69 	if ((status = nxge_pcs_init(nxgep)) != NXGE_OK) {
70 		goto fail;
71 	}
72 
73 	/* Initialize TX and RX MACs */
74 	/*
75 	 * Always perform XIF init first, before TX and RX MAC init
76 	 */
77 	if ((status = nxge_tx_mac_reset(nxgep)) != NXGE_OK)
78 		goto fail;
79 
80 	if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
81 		goto fail;
82 
83 	if ((status = nxge_rx_mac_reset(nxgep)) != NXGE_OK)
84 		goto fail;
85 
86 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
87 		goto fail;
88 
89 	if ((status = nxge_tx_mac_enable(nxgep)) != NXGE_OK)
90 		goto fail;
91 
92 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
93 		goto fail;
94 
95 	nxgep->statsp->mac_stats.mac_mtu = nxgep->mac.maxframesize;
96 
97 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mac_init: port<%d>", portn));
98 
99 	return (NXGE_OK);
100 fail:
101 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
102 			"nxge_mac_init: failed to initialize MAC port<%d>",
103 			portn));
104 	return (status);
105 }
106 
107 /* Initialize the Ethernet Link */
108 
109 nxge_status_t
110 nxge_link_init(p_nxge_t nxgep)
111 {
112 	nxge_status_t		status = NXGE_OK;
113 #ifdef	NXGE_DEBUG
114 	uint8_t			portn;
115 
116 	portn = nxgep->mac.portnum;
117 
118 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_init: port<%d>", portn));
119 #endif
120 
121 	if (nxgep->niu_type == N2_NIU) {
122 		/* Workaround to get link up in both NIU ports */
123 		if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK)
124 			goto fail;
125 	}
126 	NXGE_DELAY(200000);
127 	/* Initialize internal serdes */
128 	if ((status = nxge_serdes_init(nxgep)) != NXGE_OK)
129 		goto fail;
130 	NXGE_DELAY(200000);
131 	if ((status = nxge_xcvr_init(nxgep)) != NXGE_OK)
132 		goto fail;
133 
134 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_init: port<%d>", portn));
135 
136 	return (NXGE_OK);
137 
138 fail:
139 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
140 		"nxge_link_init: ",
141 		"failed to initialize Ethernet link on port<%d>",
142 		portn));
143 
144 	return (status);
145 }
146 
147 
148 /* Initialize the XIF sub-block within the MAC */
149 
150 nxge_status_t
151 nxge_xif_init(p_nxge_t nxgep)
152 {
153 	uint32_t		xif_cfg = 0;
154 	npi_attr_t		ap;
155 	uint8_t			portn;
156 	nxge_port_t		portt;
157 	nxge_port_mode_t	portmode;
158 	p_nxge_stats_t		statsp;
159 	npi_status_t		rs = NPI_SUCCESS;
160 	npi_handle_t		handle;
161 
162 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
163 
164 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xif_init: port<%d>", portn));
165 
166 	handle = nxgep->npi_handle;
167 	portmode = nxgep->mac.portmode;
168 	portt = nxgep->mac.porttype;
169 	statsp = nxgep->statsp;
170 
171 	if (portt == PORT_TYPE_XMAC) {
172 
173 		/* Setup XIF Configuration for XMAC */
174 
175 		if ((portmode == PORT_10G_FIBER) ||
176 					(portmode == PORT_10G_COPPER))
177 			xif_cfg |= CFG_XMAC_XIF_LFS;
178 
179 		if (portmode == PORT_1G_COPPER) {
180 			xif_cfg |= CFG_XMAC_XIF_1G_PCS_BYPASS;
181 		}
182 
183 		/* Set MAC Internal Loopback if necessary */
184 		if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
185 			xif_cfg |= CFG_XMAC_XIF_LOOPBACK;
186 
187 		if (statsp->mac_stats.link_speed == 100)
188 			xif_cfg |= CFG_XMAC_XIF_SEL_CLK_25MHZ;
189 
190 		xif_cfg |= CFG_XMAC_XIF_TX_OUTPUT;
191 
192 		if (portmode == PORT_10G_FIBER) {
193 			if (statsp->mac_stats.link_up) {
194 				xif_cfg |= CFG_XMAC_XIF_LED_POLARITY;
195 			} else {
196 				xif_cfg |= CFG_XMAC_XIF_LED_FORCE;
197 			}
198 		}
199 
200 		rs = npi_xmac_xif_config(handle, INIT, portn, xif_cfg);
201 		if (rs != NPI_SUCCESS)
202 			goto fail;
203 
204 		nxgep->mac.xif_config = xif_cfg;
205 
206 		/* Set Port Mode */
207 		if ((portmode == PORT_10G_FIBER) ||
208 					(portmode == PORT_10G_COPPER)) {
209 			SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
210 						MAC_XGMII_MODE, rs);
211 			if (rs != NPI_SUCCESS)
212 				goto fail;
213 			if (statsp->mac_stats.link_up) {
214 				if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
215 					goto fail;
216 			} else {
217 				if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
218 					goto fail;
219 			}
220 		} else if ((portmode == PORT_1G_FIBER) ||
221 						(portmode == PORT_1G_COPPER)) {
222 			if (statsp->mac_stats.link_speed == 1000) {
223 				SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
224 							MAC_GMII_MODE, rs);
225 			} else {
226 				SET_MAC_ATTR1(handle, ap, portn, MAC_PORT_MODE,
227 							MAC_MII_MODE, rs);
228 			}
229 			if (rs != NPI_SUCCESS)
230 				goto fail;
231 		} else {
232 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
233 					"nxge_xif_init: Unknown port mode (%d)"
234 					" for port<%d>", portmode, portn));
235 			goto fail;
236 		}
237 
238 	} else if (portt == PORT_TYPE_BMAC) {
239 
240 		/* Setup XIF Configuration for BMAC */
241 
242 		if (portmode == PORT_1G_COPPER) {
243 			if (statsp->mac_stats.link_speed == 100)
244 				xif_cfg |= CFG_BMAC_XIF_SEL_CLK_25MHZ;
245 		}
246 
247 		if (statsp->port_stats.lb_mode == nxge_lb_mac1000)
248 			xif_cfg |= CFG_BMAC_XIF_LOOPBACK;
249 
250 		if (statsp->mac_stats.link_speed == 1000)
251 			xif_cfg |= CFG_BMAC_XIF_GMII_MODE;
252 
253 		xif_cfg |= CFG_BMAC_XIF_TX_OUTPUT;
254 
255 		rs = npi_bmac_xif_config(handle, INIT, portn, xif_cfg);
256 		if (rs != NPI_SUCCESS)
257 			goto fail;
258 		nxgep->mac.xif_config = xif_cfg;
259 	}
260 
261 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xif_init: port<%d>", portn));
262 	return (NXGE_OK);
263 fail:
264 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
265 			"nxge_xif_init: Failed to initialize XIF port<%d>",
266 			portn));
267 	return (NXGE_ERROR | rs);
268 }
269 
270 /* Initialize the PCS sub-block in the MAC */
271 
272 nxge_status_t
273 nxge_pcs_init(p_nxge_t nxgep)
274 {
275 	pcs_cfg_t		pcs_cfg;
276 	uint32_t		val;
277 	uint8_t			portn;
278 	nxge_port_mode_t	portmode;
279 	npi_handle_t		handle;
280 	p_nxge_stats_t		statsp;
281 	npi_status_t		rs = NPI_SUCCESS;
282 
283 	handle = nxgep->npi_handle;
284 	portmode = nxgep->mac.portmode;
285 	portn = nxgep->mac.portnum;
286 	statsp = nxgep->statsp;
287 
288 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_pcs_init: port<%d>", portn));
289 
290 	if (portmode == PORT_1G_FIBER) {
291 		/* Initialize port's PCS */
292 		pcs_cfg.value = 0;
293 		pcs_cfg.bits.w0.enable = 1;
294 		pcs_cfg.bits.w0.mask = 1;
295 		PCS_REG_WR(handle, portn, PCS_CONFIG_REG, pcs_cfg.value);
296 		PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG, 0);
297 		if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS)
298 			goto fail;
299 
300 	} else if ((portmode == PORT_10G_FIBER) ||
301 						(portmode == PORT_10G_COPPER)) {
302 		/* Use internal XPCS, bypass 1G PCS */
303 		XMAC_REG_RD(handle, portn, XMAC_CONFIG_REG, &val);
304 		val &= ~XMAC_XIF_XPCS_BYPASS;
305 		XMAC_REG_WR(handle, portn, XMAC_CONFIG_REG, val);
306 
307 		if ((rs = npi_xmac_xpcs_reset(handle, portn)) != NPI_SUCCESS)
308 			goto fail;
309 
310 		/* Set XPCS Internal Loopback if necessary */
311 		if ((rs = npi_xmac_xpcs_read(handle, portn,
312 						XPCS_REG_CONTROL1, &val))
313 						!= NPI_SUCCESS)
314 			goto fail;
315 		if ((statsp->port_stats.lb_mode == nxge_lb_mac10g) ||
316 			(statsp->port_stats.lb_mode == nxge_lb_mac1000))
317 			val |= XPCS_CTRL1_LOOPBK;
318 		else
319 			val &= ~XPCS_CTRL1_LOOPBK;
320 		if ((rs = npi_xmac_xpcs_write(handle, portn,
321 						XPCS_REG_CONTROL1, val))
322 						!= NPI_SUCCESS)
323 			goto fail;
324 
325 		/* Clear descw errors */
326 		if ((rs = npi_xmac_xpcs_write(handle, portn,
327 						XPCS_REG_DESCWERR_COUNTER, 0))
328 						!= NPI_SUCCESS)
329 			goto fail;
330 		/* Clear symbol errors */
331 		if ((rs = npi_xmac_xpcs_read(handle, portn,
332 					XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val))
333 					!= NPI_SUCCESS)
334 			goto fail;
335 		if ((rs = npi_xmac_xpcs_read(handle, portn,
336 					XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val))
337 					!= NPI_SUCCESS)
338 			goto fail;
339 
340 	} else if (portmode == PORT_1G_COPPER) {
341 		if (portn < 4) {
342 			PCS_REG_WR(handle, portn, PCS_DATAPATH_MODE_REG,
343 					PCS_DATAPATH_MODE_MII);
344 		}
345 		if ((rs = npi_mac_pcs_reset(handle, portn)) != NPI_SUCCESS)
346 			goto fail;
347 
348 	} else {
349 		goto fail;
350 	}
351 pass:
352 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_pcs_init: port<%d>", portn));
353 	return (NXGE_OK);
354 fail:
355 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
356 			"nxge_pcs_init: Failed to initialize PCS port<%d>",
357 			portn));
358 	return (NXGE_ERROR | rs);
359 }
360 
361 /* Initialize the Internal Serdes */
362 
363 nxge_status_t
364 nxge_serdes_init(p_nxge_t nxgep)
365 {
366 	p_nxge_stats_t		statsp;
367 #ifdef	NXGE_DEBUG
368 	uint8_t			portn;
369 #endif
370 	nxge_status_t		status = NXGE_OK;
371 
372 #ifdef	NXGE_DEBUG
373 	portn = nxgep->mac.portnum;
374 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
375 		"==> nxge_serdes_init port<%d>", portn));
376 #endif
377 
378 	statsp = nxgep->statsp;
379 
380 	if (nxgep->niu_type == N2_NIU) {
381 		if (nxge_n2_serdes_init(nxgep) != NXGE_OK)
382 			goto fail;
383 	} else if ((nxgep->niu_type == NEPTUNE) ||
384 				(nxgep->niu_type == NEPTUNE_2)) {
385 			if ((status = nxge_neptune_serdes_init(nxgep))
386 								!= NXGE_OK)
387 				goto fail;
388 	} else {
389 		goto fail;
390 	}
391 
392 	statsp->mac_stats.serdes_inits++;
393 
394 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_serdes_init port<%d>",
395 			portn));
396 
397 	return (NXGE_OK);
398 
399 fail:
400 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
401 		"nxge_serdes_init: Failed to initialize serdes for port<%d>",
402 			portn));
403 
404 	return (status);
405 }
406 
407 /* Initialize the TI Hedwig Internal Serdes (N2-NIU only) */
408 
409 nxge_status_t
410 nxge_n2_serdes_init(p_nxge_t nxgep)
411 {
412 	uint8_t portn;
413 	int chan;
414 	esr_ti_cfgpll_l_t pll_cfg_l;
415 	esr_ti_cfgrx_l_t rx_cfg_l;
416 	esr_ti_cfgrx_h_t rx_cfg_h;
417 	esr_ti_cfgtx_l_t tx_cfg_l;
418 	esr_ti_cfgtx_h_t tx_cfg_h;
419 	esr_ti_testcfg_t test_cfg;
420 	nxge_status_t status = NXGE_OK;
421 
422 	portn = nxgep->mac.portnum;
423 
424 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_n2_serdes_init port<%d>",
425 			portn));
426 
427 	tx_cfg_l.value = 0;
428 	tx_cfg_h.value = 0;
429 	rx_cfg_l.value = 0;
430 	rx_cfg_h.value = 0;
431 	pll_cfg_l.value = 0;
432 	test_cfg.value = 0;
433 
434 	if (nxgep->mac.portmode == PORT_10G_FIBER) {
435 		/* 0x0E01 */
436 		tx_cfg_l.bits.entx = 1;
437 		tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
438 
439 		/* 0x9101 */
440 		rx_cfg_l.bits.enrx = 1;
441 		rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
442 		rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
443 		rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
444 
445 		/* 0x0008 */
446 		rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
447 
448 		/* Set loopback mode if necessary */
449 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_serdes10g) {
450 			tx_cfg_l.bits.entest = 1;
451 			rx_cfg_l.bits.entest = 1;
452 			test_cfg.bits.loopback = TESTCFG_INNER_CML_DIS_LOOPBACK;
453 			if ((status = nxge_mdio_write(nxgep, portn,
454 				ESR_N2_DEV_ADDR,
455 				ESR_N2_TEST_CFG_REG, test_cfg.value))
456 				!= NXGE_OK)
457 			goto fail;
458 		}
459 
460 		/* Use default PLL value */
461 
462 	} else if (nxgep->mac.portmode == PORT_1G_FIBER) {
463 
464 		/* 0x0E21 */
465 		tx_cfg_l.bits.entx = 1;
466 		tx_cfg_l.bits.rate = CFGTX_RATE_HALF;
467 		tx_cfg_l.bits.swing = CFGTX_SWING_1375MV;
468 
469 		/* 0x9121 */
470 		rx_cfg_l.bits.enrx = 1;
471 		rx_cfg_l.bits.rate = CFGRX_RATE_HALF;
472 		rx_cfg_l.bits.term = CFGRX_TERM_0P8VDDT;
473 		rx_cfg_l.bits.align = CFGRX_ALIGN_EN;
474 		rx_cfg_l.bits.los = CFGRX_LOS_LOTHRES;
475 
476 		/* 0x8 */
477 		rx_cfg_h.bits.eq = CFGRX_EQ_ADAPTIVE_LP_ADAPTIVE_ZF;
478 
479 		/* MPY = 0x100 */
480 		pll_cfg_l.bits.mpy = CFGPLL_MPY_8X;
481 
482 		/* Set PLL */
483 		pll_cfg_l.bits.enpll = 1;
484 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
485 				ESR_N2_PLL_CFG_L_REG, pll_cfg_l.value))
486 				!= NXGE_OK)
487 			goto fail;
488 	} else {
489 		goto fail;
490 	}
491 
492 	/*   MIF_REG_WR(handle, MIF_MASK_REG, ~mask); */
493 
494 	NXGE_DELAY(20);
495 
496 	/* init TX channels */
497 	for (chan = 0; chan < 4; chan++) {
498 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
499 				ESR_N2_TX_CFG_L_REG_ADDR(chan), tx_cfg_l.value))
500 				!= NXGE_OK)
501 			goto fail;
502 
503 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
504 				ESR_N2_TX_CFG_H_REG_ADDR(chan), tx_cfg_h.value))
505 				!= NXGE_OK)
506 			goto fail;
507 	}
508 
509 	/* init RX channels */
510 	for (chan = 0; chan < 4; chan++) {
511 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
512 				ESR_N2_RX_CFG_L_REG_ADDR(chan), rx_cfg_l.value))
513 				!= NXGE_OK)
514 			goto fail;
515 
516 		if ((status = nxge_mdio_write(nxgep, portn, ESR_N2_DEV_ADDR,
517 				ESR_N2_RX_CFG_H_REG_ADDR(chan), rx_cfg_h.value))
518 				!= NXGE_OK)
519 			goto fail;
520 	}
521 
522 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_n2_serdes_init port<%d>",
523 			portn));
524 
525 	return (NXGE_OK);
526 fail:
527 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
528 	"nxge_n2_serdes_init: Failed to initialize N2 serdes for port<%d>",
529 				portn));
530 
531 	return (status);
532 }
533 
534 /* Initialize Neptune Internal Serdes (Neptune only) */
535 
536 nxge_status_t
537 nxge_neptune_serdes_init(p_nxge_t nxgep)
538 {
539 	npi_handle_t		handle;
540 	uint8_t			portn;
541 	nxge_port_mode_t	portmode;
542 	int			chan;
543 	sr_rx_tx_ctrl_l_t	rx_tx_ctrl_l;
544 	sr_rx_tx_ctrl_h_t	rx_tx_ctrl_h;
545 	sr_glue_ctrl0_l_t	glue_ctrl0_l;
546 	sr_glue_ctrl0_h_t	glue_ctrl0_h;
547 	uint64_t		val;
548 	uint16_t		val16l;
549 	uint16_t		val16h;
550 	nxge_status_t		status = NXGE_OK;
551 
552 	portn = nxgep->mac.portnum;
553 
554 	if ((portn != 0) && (portn != 1))
555 		return (NXGE_OK);
556 
557 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_neptune_serdes_init port<%d>",
558 			portn));
559 
560 	handle = nxgep->npi_handle;
561 	portmode = nxgep->mac.portmode;
562 
563 	if ((portmode == PORT_10G_FIBER) || (portmode == PORT_10G_COPPER)) {
564 
565 		switch (portn) {
566 		case 0:
567 			ESR_REG_WR(handle, ESR_0_CONTROL_REG,
568 				ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
569 				ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
570 				(0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
571 				(0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
572 				(0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
573 				(0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
574 				(0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
575 				(0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
576 				(0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
577 				(0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
578 				(0x1 << ESR_CTL_LOSADJ_3_SHIFT));
579 
580 				/* Set Serdes0 Internal Loopback if necessary */
581 				if (nxgep->statsp->port_stats.lb_mode ==
582 							nxge_lb_serdes10g) {
583 					ESR_REG_WR(handle,
584 						ESR_0_TEST_CONFIG_REG,
585 						ESR_PAD_LOOPBACK_CH3 |
586 						ESR_PAD_LOOPBACK_CH2 |
587 						ESR_PAD_LOOPBACK_CH1 |
588 						ESR_PAD_LOOPBACK_CH0);
589 				} else {
590 					ESR_REG_WR(handle,
591 						ESR_0_TEST_CONFIG_REG, 0);
592 				}
593 			break;
594 		case 1:
595 			ESR_REG_WR(handle, ESR_1_CONTROL_REG,
596 				ESR_CTL_EN_SYNCDET_0 | ESR_CTL_EN_SYNCDET_1 |
597 				ESR_CTL_EN_SYNCDET_2 | ESR_CTL_EN_SYNCDET_3 |
598 				(0x5 << ESR_CTL_OUT_EMPH_0_SHIFT) |
599 				(0x5 << ESR_CTL_OUT_EMPH_1_SHIFT) |
600 				(0x5 << ESR_CTL_OUT_EMPH_2_SHIFT) |
601 				(0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
602 				(0x5 << ESR_CTL_OUT_EMPH_3_SHIFT) |
603 				(0x1 << ESR_CTL_LOSADJ_0_SHIFT) |
604 				(0x1 << ESR_CTL_LOSADJ_1_SHIFT) |
605 				(0x1 << ESR_CTL_LOSADJ_2_SHIFT) |
606 				(0x1 << ESR_CTL_LOSADJ_3_SHIFT));
607 
608 				/* Set Serdes1 Internal Loopback if necessary */
609 				if (nxgep->statsp->port_stats.lb_mode ==
610 							nxge_lb_serdes10g) {
611 					ESR_REG_WR(handle,
612 						ESR_1_TEST_CONFIG_REG,
613 						ESR_PAD_LOOPBACK_CH3 |
614 						ESR_PAD_LOOPBACK_CH2 |
615 						ESR_PAD_LOOPBACK_CH1 |
616 						ESR_PAD_LOOPBACK_CH0);
617 				} else {
618 					ESR_REG_WR(handle,
619 						ESR_1_TEST_CONFIG_REG, 0);
620 				}
621 			break;
622 		default:
623 			/* Nothing to do here */
624 			goto done;
625 		}
626 
627 		/* init TX RX channels */
628 		for (chan = 0; chan < 4; chan++) {
629 			if ((status = nxge_mdio_read(nxgep, portn,
630 					ESR_NEPTUNE_DEV_ADDR,
631 					ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
632 					&rx_tx_ctrl_l.value)) != NXGE_OK)
633 				goto fail;
634 			if ((status = nxge_mdio_read(nxgep, portn,
635 					ESR_NEPTUNE_DEV_ADDR,
636 					ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
637 					&rx_tx_ctrl_h.value)) != NXGE_OK)
638 				goto fail;
639 			if ((status = nxge_mdio_read(nxgep, portn,
640 					ESR_NEPTUNE_DEV_ADDR,
641 					ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
642 					&glue_ctrl0_l.value)) != NXGE_OK)
643 				goto fail;
644 			if ((status = nxge_mdio_read(nxgep, portn,
645 					ESR_NEPTUNE_DEV_ADDR,
646 					ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
647 					&glue_ctrl0_h.value)) != NXGE_OK)
648 				goto fail;
649 			rx_tx_ctrl_l.bits.enstretch = 1;
650 			rx_tx_ctrl_h.bits.vmuxlo = 2;
651 			rx_tx_ctrl_h.bits.vpulselo = 2;
652 			glue_ctrl0_l.bits.rxlosenable = 1;
653 			glue_ctrl0_l.bits.samplerate = 0xF;
654 			glue_ctrl0_l.bits.thresholdcount = 0xFF;
655 			glue_ctrl0_h.bits.bitlocktime = BITLOCKTIME_300_CYCLES;
656 			if ((status = nxge_mdio_write(nxgep, portn,
657 					ESR_NEPTUNE_DEV_ADDR,
658 					ESR_NEP_RX_TX_CONTROL_L_ADDR(chan),
659 					rx_tx_ctrl_l.value)) != NXGE_OK)
660 				goto fail;
661 			if ((status = nxge_mdio_write(nxgep, portn,
662 					ESR_NEPTUNE_DEV_ADDR,
663 					ESR_NEP_RX_TX_CONTROL_H_ADDR(chan),
664 					rx_tx_ctrl_h.value)) != NXGE_OK)
665 				goto fail;
666 			if ((status = nxge_mdio_write(nxgep, portn,
667 					ESR_NEPTUNE_DEV_ADDR,
668 					ESR_NEP_GLUE_CONTROL0_L_ADDR(chan),
669 					glue_ctrl0_l.value)) != NXGE_OK)
670 				goto fail;
671 			if ((status = nxge_mdio_write(nxgep, portn,
672 					ESR_NEPTUNE_DEV_ADDR,
673 					ESR_NEP_GLUE_CONTROL0_H_ADDR(chan),
674 					glue_ctrl0_h.value)) != NXGE_OK)
675 				goto fail;
676 		}
677 
678 		/* Apply Tx core reset */
679 		if ((status = nxge_mdio_write(nxgep, portn,
680 					ESR_NEPTUNE_DEV_ADDR,
681 					ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
682 					(uint16_t)0)) != NXGE_OK)
683 			goto fail;
684 
685 		if ((status = nxge_mdio_write(nxgep, portn,
686 					ESR_NEPTUNE_DEV_ADDR,
687 					ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(),
688 					(uint16_t)0xffff)) != NXGE_OK)
689 			goto fail;
690 
691 		NXGE_DELAY(200);
692 
693 		/* Apply Rx core reset */
694 		if ((status = nxge_mdio_write(nxgep, portn,
695 					ESR_NEPTUNE_DEV_ADDR,
696 					ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
697 					(uint16_t)0xffff)) != NXGE_OK)
698 			goto fail;
699 
700 		NXGE_DELAY(200);
701 		if ((status = nxge_mdio_write(nxgep, portn,
702 					ESR_NEPTUNE_DEV_ADDR,
703 					ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(),
704 					(uint16_t)0)) != NXGE_OK)
705 			goto fail;
706 
707 		NXGE_DELAY(200);
708 		if ((status = nxge_mdio_read(nxgep, portn,
709 					ESR_NEPTUNE_DEV_ADDR,
710 					ESR_NEP_RX_TX_RESET_CONTROL_L_ADDR(),
711 					&val16l)) != NXGE_OK)
712 			goto fail;
713 		if ((status = nxge_mdio_read(nxgep, portn,
714 					ESR_NEPTUNE_DEV_ADDR,
715 					ESR_NEP_RX_TX_RESET_CONTROL_H_ADDR(),
716 					&val16h)) != NXGE_OK)
717 			goto fail;
718 		if ((val16l != 0) || (val16h != 0)) {
719 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
720 					"Failed to reset port<%d> XAUI Serdes",
721 					portn));
722 		}
723 
724 		ESR_REG_RD(handle, ESR_INTERNAL_SIGNALS_REG, &val);
725 
726 		if (portn == 0) {
727 			if ((val & ESR_SIG_P0_BITS_MASK) !=
728 				(ESR_SIG_SERDES_RDY0_P0 | ESR_SIG_DETECT0_P0 |
729 					ESR_SIG_XSERDES_RDY_P0 |
730 					ESR_SIG_XDETECT_P0_CH3 |
731 					ESR_SIG_XDETECT_P0_CH2 |
732 					ESR_SIG_XDETECT_P0_CH1 |
733 					ESR_SIG_XDETECT_P0_CH0)) {
734 				goto fail;
735 			}
736 		} else if (portn == 1) {
737 			if ((val & ESR_SIG_P1_BITS_MASK) !=
738 				(ESR_SIG_SERDES_RDY0_P1 | ESR_SIG_DETECT0_P1 |
739 					ESR_SIG_XSERDES_RDY_P1 |
740 					ESR_SIG_XDETECT_P1_CH3 |
741 					ESR_SIG_XDETECT_P1_CH2 |
742 					ESR_SIG_XDETECT_P1_CH1 |
743 					ESR_SIG_XDETECT_P1_CH0)) {
744 				goto fail;
745 			}
746 		}
747 
748 	} else if (portmode == PORT_1G_FIBER) {
749 		ESR_REG_RD(handle, ESR_1_PLL_CONFIG_REG, &val)
750 		val &= ~ESR_PLL_CFG_FBDIV_2;
751 		switch (portn) {
752 		case 0:
753 			val |= ESR_PLL_CFG_HALF_RATE_0;
754 			break;
755 		case 1:
756 			val |= ESR_PLL_CFG_HALF_RATE_1;
757 			break;
758 		case 2:
759 			val |= ESR_PLL_CFG_HALF_RATE_2;
760 			break;
761 		case 3:
762 			val |= ESR_PLL_CFG_HALF_RATE_3;
763 			break;
764 		default:
765 			goto fail;
766 		}
767 
768 		ESR_REG_WR(handle, ESR_1_PLL_CONFIG_REG, val);
769 	}
770 
771 done:
772 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_neptune_serdes_init port<%d>",
773 			portn));
774 	return (NXGE_OK);
775 fail:
776 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
777 			"nxge_neptune_serdes_init: "
778 			"Failed to initialize Neptune serdes for port<%d>",
779 			portn));
780 
781 	return (status);
782 }
783 
784 /* Look for transceiver type */
785 
786 nxge_status_t
787 nxge_xcvr_find(p_nxge_t nxgep)
788 {
789 	uint8_t		portn;
790 
791 	portn = nxgep->mac.portnum;
792 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_find: port<%d>", portn));
793 
794 	if (nxge_get_xcvr_type(nxgep) != NXGE_OK)
795 		return (NXGE_ERROR);
796 
797 	nxgep->mac.linkchkmode = LINKCHK_TIMER;
798 	if (nxgep->mac.portmode == PORT_10G_FIBER) {
799 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
800 		if ((nxgep->niu_type == NEPTUNE) ||
801 			(nxgep->niu_type == NEPTUNE_2)) {
802 			nxgep->statsp->mac_stats.xcvr_portn =
803 					BCM8704_NEPTUNE_PORT_ADDR_BASE + portn;
804 		} else if (nxgep->niu_type == N2_NIU) {
805 			nxgep->statsp->mac_stats.xcvr_portn =
806 					BCM8704_N2_PORT_ADDR_BASE + portn;
807 		} else
808 			return (NXGE_ERROR);
809 	} else if (nxgep->mac.portmode == PORT_1G_COPPER) {
810 		nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
811 		/*
812 		 * For Altas, Xcvr port numbers are swapped with ethernet
813 		 * port number. This is designed for better signal
814 		 * integrity in routing.
815 		 */
816 
817 		switch (portn) {
818 		case 0:
819 			nxgep->statsp->mac_stats.xcvr_portn =
820 					BCM5464_NEPTUNE_PORT_ADDR_BASE + 3;
821 			break;
822 		case 1:
823 			nxgep->statsp->mac_stats.xcvr_portn =
824 					BCM5464_NEPTUNE_PORT_ADDR_BASE + 2;
825 			break;
826 		case 2:
827 			nxgep->statsp->mac_stats.xcvr_portn =
828 					BCM5464_NEPTUNE_PORT_ADDR_BASE + 1;
829 			break;
830 		case 3:
831 			nxgep->statsp->mac_stats.xcvr_portn =
832 					BCM5464_NEPTUNE_PORT_ADDR_BASE;
833 			break;
834 		default:
835 			return (NXGE_ERROR);
836 		}
837 	} else if (nxgep->mac.portmode == PORT_1G_FIBER) {
838 		nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
839 		nxgep->statsp->mac_stats.xcvr_portn = portn;
840 	} else {
841 		return (NXGE_ERROR);
842 	}
843 
844 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_xcvr_find: xcvr_inuse = %d",
845 					nxgep->statsp->mac_stats.xcvr_inuse));
846 	return (NXGE_OK);
847 }
848 
849 /* Initialize transceiver */
850 
851 nxge_status_t
852 nxge_xcvr_init(p_nxge_t nxgep)
853 {
854 	p_nxge_param_t		param_arr;
855 	p_nxge_stats_t		statsp;
856 	uint16_t		val;
857 #ifdef	NXGE_DEBUG
858 	uint8_t			portn;
859 	uint16_t		val1;
860 #endif
861 	uint8_t			phy_port_addr;
862 	pmd_tx_control_t	tx_ctl;
863 	control_t		ctl;
864 	phyxs_control_t		phyxs_ctl;
865 	pcs_control_t		pcs_ctl;
866 	uint32_t		delay = 0;
867 	optics_dcntr_t		op_ctr;
868 	nxge_status_t		status = NXGE_OK;
869 #ifdef	NXGE_DEBUG
870 	portn = nxgep->mac.portnum;
871 #endif
872 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn));
873 
874 	param_arr = nxgep->param_arr;
875 	statsp = nxgep->statsp;
876 
877 	/*
878 	 * Initialize the xcvr statistics.
879 	 */
880 	statsp->mac_stats.cap_autoneg = 0;
881 	statsp->mac_stats.cap_100T4 = 0;
882 	statsp->mac_stats.cap_100fdx = 0;
883 	statsp->mac_stats.cap_100hdx = 0;
884 	statsp->mac_stats.cap_10fdx = 0;
885 	statsp->mac_stats.cap_10hdx = 0;
886 	statsp->mac_stats.cap_asmpause = 0;
887 	statsp->mac_stats.cap_pause = 0;
888 	statsp->mac_stats.cap_1000fdx = 0;
889 	statsp->mac_stats.cap_1000hdx = 0;
890 	statsp->mac_stats.cap_10gfdx = 0;
891 	statsp->mac_stats.cap_10ghdx = 0;
892 
893 	/*
894 	 * Initialize the link statistics.
895 	 */
896 	statsp->mac_stats.link_T4 = 0;
897 	statsp->mac_stats.link_asmpause = 0;
898 	statsp->mac_stats.link_pause = 0;
899 
900 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
901 
902 	switch (nxgep->mac.portmode) {
903 	case PORT_10G_FIBER:
904 		/* Disable Link LEDs */
905 		if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
906 			goto fail;
907 
908 		/* Set Clause 45 */
909 		npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_TRUE);
910 
911 		/* Reset the transceiver */
912 		if ((status = nxge_mdio_read(nxgep,
913 				phy_port_addr,
914 				BCM8704_PHYXS_ADDR,
915 				BCM8704_PHYXS_CONTROL_REG,
916 				&phyxs_ctl.value)) != NXGE_OK)
917 			goto fail;
918 
919 		phyxs_ctl.bits.reset = 1;
920 		if ((status = nxge_mdio_write(nxgep,
921 				phy_port_addr,
922 				BCM8704_PHYXS_ADDR,
923 				BCM8704_PHYXS_CONTROL_REG,
924 				phyxs_ctl.value)) != NXGE_OK)
925 			goto fail;
926 
927 		do {
928 			drv_usecwait(500);
929 			if ((status = nxge_mdio_read(nxgep,
930 					phy_port_addr,
931 					BCM8704_PHYXS_ADDR,
932 					BCM8704_PHYXS_CONTROL_REG,
933 					&phyxs_ctl.value)) != NXGE_OK)
934 				goto fail;
935 			delay++;
936 		} while ((phyxs_ctl.bits.reset) && (delay < 100));
937 		if (delay == 100) {
938 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
939 				"nxge_xcvr_init: "
940 				"failed to reset Transceiver on port<%d>",
941 				portn));
942 			status = NXGE_ERROR;
943 			goto fail;
944 		}
945 
946 		/* Set to 0x7FBF */
947 		ctl.value = 0;
948 		ctl.bits.res1 = 0x3F;
949 		ctl.bits.optxon_lvl = 1;
950 		ctl.bits.oprxflt_lvl = 1;
951 		ctl.bits.optrxlos_lvl = 1;
952 		ctl.bits.optxflt_lvl = 1;
953 		ctl.bits.opprflt_lvl = 1;
954 		ctl.bits.obtmpflt_lvl = 1;
955 		ctl.bits.opbiasflt_lvl = 1;
956 		ctl.bits.optxrst_lvl = 1;
957 		if ((status = nxge_mdio_write(nxgep,
958 				phy_port_addr,
959 				BCM8704_USER_DEV3_ADDR,
960 				BCM8704_USER_CONTROL_REG, ctl.value))
961 				!= NXGE_OK)
962 			goto fail;
963 
964 		/* Set to 0x164 */
965 		tx_ctl.value = 0;
966 		tx_ctl.bits.tsck_lpwren = 1;
967 		tx_ctl.bits.tx_dac_txck = 0x2;
968 		tx_ctl.bits.tx_dac_txd = 0x1;
969 		tx_ctl.bits.xfp_clken = 1;
970 		if ((status = nxge_mdio_write(nxgep,
971 				phy_port_addr,
972 				BCM8704_USER_DEV3_ADDR,
973 				BCM8704_USER_PMD_TX_CONTROL_REG, tx_ctl.value))
974 				!= NXGE_OK)
975 			goto fail;
976 		/*
977 		 * According to Broadcom's instruction, SW needs to read
978 		 * back these registers twice after written.
979 		 */
980 		if ((status = nxge_mdio_read(nxgep,
981 				phy_port_addr,
982 				BCM8704_USER_DEV3_ADDR,
983 				BCM8704_USER_CONTROL_REG, &val))
984 				!= NXGE_OK)
985 			goto fail;
986 
987 		if ((status = nxge_mdio_read(nxgep,
988 				phy_port_addr,
989 				BCM8704_USER_DEV3_ADDR,
990 				BCM8704_USER_CONTROL_REG, &val))
991 				!= NXGE_OK)
992 			goto fail;
993 
994 		if ((status = nxge_mdio_read(nxgep,
995 				phy_port_addr,
996 				BCM8704_USER_DEV3_ADDR,
997 				BCM8704_USER_PMD_TX_CONTROL_REG, &val))
998 				!= NXGE_OK)
999 			goto fail;
1000 
1001 		if ((status = nxge_mdio_read(nxgep,
1002 				phy_port_addr,
1003 				BCM8704_USER_DEV3_ADDR,
1004 				BCM8704_USER_PMD_TX_CONTROL_REG, &val))
1005 				!= NXGE_OK)
1006 			goto fail;
1007 
1008 
1009 		/* Enable Tx and Rx LEDs to be driven by traffic */
1010 		if ((status = nxge_mdio_read(nxgep,
1011 					phy_port_addr,
1012 					BCM8704_USER_DEV3_ADDR,
1013 					BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
1014 					&op_ctr.value)) != NXGE_OK)
1015 			goto fail;
1016 		op_ctr.bits.gpio_sel = 0x3;
1017 		if ((status = nxge_mdio_write(nxgep,
1018 					phy_port_addr,
1019 					BCM8704_USER_DEV3_ADDR,
1020 					BCM8704_USER_OPTICS_DIGITAL_CTRL_REG,
1021 					op_ctr.value)) != NXGE_OK)
1022 			goto fail;
1023 
1024 		NXGE_DELAY(1000000);
1025 
1026 		/* Set BCM8704 Internal Loopback mode if necessary */
1027 		if ((status = nxge_mdio_read(nxgep,
1028 					phy_port_addr,
1029 					BCM8704_PCS_DEV_ADDR,
1030 					BCM8704_PCS_CONTROL_REG,
1031 					&pcs_ctl.value)) != NXGE_OK)
1032 			goto fail;
1033 		if (nxgep->statsp->port_stats.lb_mode == nxge_lb_phy10g)
1034 			pcs_ctl.bits.loopback = 1;
1035 		else
1036 			pcs_ctl.bits.loopback = 0;
1037 		if ((status = nxge_mdio_write(nxgep,
1038 					phy_port_addr,
1039 					BCM8704_PCS_DEV_ADDR,
1040 					BCM8704_PCS_CONTROL_REG,
1041 					pcs_ctl.value)) != NXGE_OK)
1042 			goto fail;
1043 
1044 		status = nxge_mdio_read(nxgep, phy_port_addr,
1045 				0x1, 0xA, &val);
1046 		if (status != NXGE_OK)
1047 			goto fail;
1048 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1049 				"BCM8704 port<%d> Dev 1 Reg 0xA = 0x%x\n",
1050 				portn, val));
1051 		status = nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0x20, &val);
1052 		if (status != NXGE_OK)
1053 			goto fail;
1054 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1055 				"BCM8704 port<%d> Dev 3 Reg 0x20 = 0x%x\n",
1056 				portn, val));
1057 		status = nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18, &val);
1058 		if (status != NXGE_OK)
1059 			goto fail;
1060 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1061 				"BCM8704 port<%d> Dev 4 Reg 0x18 = 0x%x\n",
1062 				portn, val));
1063 
1064 #ifdef	NXGE_DEBUG
1065 		/* Diagnose link issue if link is not up */
1066 		status = nxge_mdio_read(nxgep, phy_port_addr,
1067 					BCM8704_USER_DEV3_ADDR,
1068 					BCM8704_USER_ANALOG_STATUS0_REG,
1069 					&val);
1070 		if (status != NXGE_OK)
1071 			goto fail;
1072 
1073 		status = nxge_mdio_read(nxgep, phy_port_addr,
1074 					BCM8704_USER_DEV3_ADDR,
1075 					BCM8704_USER_ANALOG_STATUS0_REG,
1076 					&val);
1077 		if (status != NXGE_OK)
1078 			goto fail;
1079 
1080 		status = nxge_mdio_read(nxgep, phy_port_addr,
1081 					BCM8704_USER_DEV3_ADDR,
1082 					BCM8704_USER_TX_ALARM_STATUS_REG,
1083 					&val1);
1084 		if (status != NXGE_OK)
1085 			goto fail;
1086 
1087 		status = nxge_mdio_read(nxgep, phy_port_addr,
1088 					BCM8704_USER_DEV3_ADDR,
1089 					BCM8704_USER_TX_ALARM_STATUS_REG,
1090 					&val1);
1091 		if (status != NXGE_OK)
1092 			goto fail;
1093 
1094 		if (val != 0x3FC) {
1095 			if ((val == 0x43BC) && (val1 != 0)) {
1096 				NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1097 					"Cable not connected to peer or bad"
1098 					" cable on port<%d>\n", portn));
1099 			} else if (val == 0x639C) {
1100 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1101 					"Optical module (XFP) is bad or absence"
1102 					" on port<%d>\n", portn));
1103 			}
1104 		}
1105 #endif
1106 
1107 		statsp->mac_stats.cap_10gfdx = 1;
1108 		statsp->mac_stats.lp_cap_10gfdx = 1;
1109 		break;
1110 	case PORT_10G_COPPER:
1111 		break;
1112 	case PORT_1G_FIBER:
1113 	case PORT_1G_COPPER:
1114 		/* Set Clause 22 */
1115 		npi_mac_mif_set_indirect_mode(nxgep->npi_handle, B_FALSE);
1116 
1117 		/* Set capability flags */
1118 		statsp->mac_stats.cap_1000fdx =
1119 					param_arr[param_anar_1000fdx].value;
1120 		statsp->mac_stats.cap_100fdx =
1121 					param_arr[param_anar_100fdx].value;
1122 		statsp->mac_stats.cap_10fdx = param_arr[param_anar_10fdx].value;
1123 
1124 		if ((status = nxge_mii_xcvr_init(nxgep)) != NXGE_OK)
1125 			goto fail;
1126 		break;
1127 	default:
1128 		goto fail;
1129 	}
1130 
1131 	statsp->mac_stats.xcvr_inits++;
1132 
1133 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_xcvr_init: port<%d>", portn));
1134 	return (NXGE_OK);
1135 
1136 fail:
1137 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1138 		"nxge_xcvr_init: failed to initialize transceiver for port<%d>",
1139 		portn));
1140 	return (status);
1141 }
1142 
1143 
1144 /* Initialize the TxMAC sub-block */
1145 
1146 nxge_status_t
1147 nxge_tx_mac_init(p_nxge_t nxgep)
1148 {
1149 	npi_attr_t		ap;
1150 	uint8_t			portn;
1151 	nxge_port_mode_t	portmode;
1152 	nxge_port_t		portt;
1153 	npi_handle_t		handle;
1154 	npi_status_t		rs = NPI_SUCCESS;
1155 
1156 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
1157 	portt    = nxgep->mac.porttype;
1158 	handle   = nxgep->npi_handle;
1159 	portmode = nxgep->mac.portmode;
1160 
1161 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_init: port<%d>",
1162 			portn));
1163 
1164 	/* Set Max and Min Frame Size */
1165 	if (nxgep->param_arr[param_accept_jumbo].value || nxge_jumbo_enable) {
1166 		SET_MAC_ATTR2(handle, ap, portn,
1167 		    MAC_PORT_FRAME_SIZE, 64, 0x2400, rs);
1168 	} else {
1169 		SET_MAC_ATTR2(handle, ap, portn,
1170 		    MAC_PORT_FRAME_SIZE, 64, 0x5EE + 4, rs);
1171 	}
1172 
1173 	if (rs != NPI_SUCCESS)
1174 		goto fail;
1175 	if (nxgep->param_arr[param_accept_jumbo].value ||
1176 		nxgep->mac.is_jumbo == B_TRUE)
1177 		nxgep->mac.maxframesize = 0x2400;
1178 	else
1179 		nxgep->mac.maxframesize = 0x5EE + 4;
1180 	nxgep->mac.minframesize = 64;
1181 
1182 	if (portt == PORT_TYPE_XMAC) {
1183 		if ((rs = npi_xmac_tx_iconfig(handle, INIT, portn,
1184 				0)) != NPI_SUCCESS)
1185 			goto fail;
1186 		nxgep->mac.tx_iconfig = NXGE_XMAC_TX_INTRS;
1187 		if ((portmode == PORT_10G_FIBER) ||
1188 					(portmode == PORT_10G_COPPER)) {
1189 			SET_MAC_ATTR1(handle, ap, portn, XMAC_10G_PORT_IPG,
1190 					XGMII_IPG_12_15, rs);
1191 			if (rs != NPI_SUCCESS)
1192 				goto fail;
1193 			nxgep->mac.ipg[0] = XGMII_IPG_12_15;
1194 		} else {
1195 			SET_MAC_ATTR1(handle, ap, portn, XMAC_PORT_IPG,
1196 					MII_GMII_IPG_12, rs);
1197 			if (rs != NPI_SUCCESS)
1198 				goto fail;
1199 			nxgep->mac.ipg[0] = MII_GMII_IPG_12;
1200 		}
1201 		if ((rs = npi_xmac_tx_config(handle, INIT, portn,
1202 				CFG_XMAC_TX_CRC | CFG_XMAC_TX)) != NPI_SUCCESS)
1203 			goto fail;
1204 		nxgep->mac.tx_config = CFG_XMAC_TX_CRC | CFG_XMAC_TX;
1205 		nxgep->mac.maxburstsize = 0;	/* not programmable */
1206 		nxgep->mac.ctrltype = 0;	/* not programmable */
1207 		nxgep->mac.pa_size = 0;		/* not programmable */
1208 
1209 		if ((rs = npi_xmac_zap_tx_counters(handle, portn))
1210 							!= NPI_SUCCESS)
1211 			goto fail;
1212 
1213 	} else {
1214 		if ((rs = npi_bmac_tx_iconfig(handle, INIT, portn,
1215 				0)) != NPI_SUCCESS)
1216 			goto fail;
1217 		nxgep->mac.tx_iconfig = NXGE_BMAC_TX_INTRS;
1218 
1219 		SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_CTRL_TYPE, 0x8808,
1220 				rs);
1221 		if (rs != NPI_SUCCESS)
1222 			goto fail;
1223 		nxgep->mac.ctrltype = 0x8808;
1224 
1225 		SET_MAC_ATTR1(handle, ap, portn, BMAC_PORT_PA_SIZE, 0x7, rs);
1226 		if (rs != NPI_SUCCESS)
1227 			goto fail;
1228 		nxgep->mac.pa_size = 0x7;
1229 
1230 		if ((rs = npi_bmac_tx_config(handle, INIT, portn,
1231 				CFG_BMAC_TX_CRC | CFG_BMAC_TX)) != NPI_SUCCESS)
1232 			goto fail;
1233 		nxgep->mac.tx_config = CFG_BMAC_TX_CRC | CFG_BMAC_TX;
1234 	}
1235 
1236 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_init: port<%d>",
1237 			portn));
1238 
1239 	return (NXGE_OK);
1240 fail:
1241 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1242 		"nxge_tx_mac_init: failed to initialize port<%d> TXMAC",
1243 					portn));
1244 
1245 	return (NXGE_ERROR | rs);
1246 }
1247 
1248 /* Initialize the RxMAC sub-block */
1249 
1250 nxge_status_t
1251 nxge_rx_mac_init(p_nxge_t nxgep)
1252 {
1253 	npi_attr_t		ap;
1254 	uint32_t		i;
1255 	uint16_t		hashtab_e;
1256 	p_hash_filter_t		hash_filter;
1257 	nxge_port_t		portt;
1258 	uint8_t			portn;
1259 	npi_handle_t		handle;
1260 	npi_status_t		rs = NPI_SUCCESS;
1261 	uint16_t 		*addr16p;
1262 	uint16_t 		addr0, addr1, addr2;
1263 	xmac_rx_config_t	xconfig;
1264 	bmac_rx_config_t	bconfig;
1265 
1266 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
1267 
1268 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_init: port<%d>\n",
1269 			portn));
1270 	handle = nxgep->npi_handle;
1271 	portt = nxgep->mac.porttype;
1272 
1273 	addr16p = (uint16_t *)nxgep->ouraddr.ether_addr_octet;
1274 	addr0 = ntohs(addr16p[2]);
1275 	addr1 = ntohs(addr16p[1]);
1276 	addr2 = ntohs(addr16p[0]);
1277 	SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR, addr0, addr1, addr2,
1278 		rs);
1279 
1280 	if (rs != NPI_SUCCESS)
1281 		goto fail;
1282 	SET_MAC_ATTR3(handle, ap, portn, MAC_PORT_ADDR_FILTER, 0, 0, 0, rs);
1283 	if (rs != NPI_SUCCESS)
1284 		goto fail;
1285 	SET_MAC_ATTR2(handle, ap, portn, MAC_PORT_ADDR_FILTER_MASK, 0, 0, rs);
1286 	if (rs != NPI_SUCCESS)
1287 		goto fail;
1288 
1289 	/*
1290 	 * Load the multicast hash filter bits.
1291 	 */
1292 	hash_filter = nxgep->hash_filter;
1293 	for (i = 0; i < MAC_MAX_HASH_ENTRY; i++) {
1294 		if (hash_filter != NULL) {
1295 			hashtab_e = (uint16_t)hash_filter->hash_filter_regs[
1296 				(NMCFILTER_REGS - 1) - i];
1297 		} else {
1298 			hashtab_e = 0;
1299 		}
1300 
1301 		if ((rs = npi_mac_hashtab_entry(handle, OP_SET, portn, i,
1302 					(uint16_t *)&hashtab_e)) != NPI_SUCCESS)
1303 			goto fail;
1304 	}
1305 
1306 	if (portt == PORT_TYPE_XMAC) {
1307 		if ((rs = npi_xmac_rx_iconfig(handle, INIT, portn,
1308 				0)) != NPI_SUCCESS)
1309 			goto fail;
1310 		nxgep->mac.rx_iconfig = NXGE_XMAC_RX_INTRS;
1311 
1312 		(void) nxge_fflp_init_hostinfo(nxgep);
1313 
1314 		xconfig = CFG_XMAC_RX_ERRCHK | CFG_XMAC_RX_CRC_CHK |
1315 			CFG_XMAC_RX | CFG_XMAC_RX_CODE_VIO_CHK &
1316 			~CFG_XMAC_RX_STRIP_CRC;
1317 
1318 		if (nxgep->filter.all_phys_cnt != 0)
1319 			xconfig |= CFG_XMAC_RX_PROMISCUOUS;
1320 
1321 		if (nxgep->filter.all_multicast_cnt != 0)
1322 			xconfig |= CFG_XMAC_RX_PROMISCUOUSGROUP;
1323 
1324 		xconfig |= CFG_XMAC_RX_HASH_FILTER;
1325 
1326 		if ((rs = npi_xmac_rx_config(handle, INIT, portn,
1327 					xconfig)) != NPI_SUCCESS)
1328 			goto fail;
1329 		nxgep->mac.rx_config = xconfig;
1330 
1331 		/* Comparison of mac unique address is always enabled on XMAC */
1332 
1333 		if ((rs = npi_xmac_zap_rx_counters(handle, portn))
1334 							!= NPI_SUCCESS)
1335 			goto fail;
1336 	} else {
1337 		(void) nxge_fflp_init_hostinfo(nxgep);
1338 
1339 		if (npi_bmac_rx_iconfig(nxgep->npi_handle, INIT, portn,
1340 					0) != NPI_SUCCESS)
1341 			goto fail;
1342 		nxgep->mac.rx_iconfig = NXGE_BMAC_RX_INTRS;
1343 
1344 		bconfig = CFG_BMAC_RX_DISCARD_ON_ERR | CFG_BMAC_RX &
1345 			~CFG_BMAC_RX_STRIP_CRC;
1346 
1347 		if (nxgep->filter.all_phys_cnt != 0)
1348 			bconfig |= CFG_BMAC_RX_PROMISCUOUS;
1349 
1350 		if (nxgep->filter.all_multicast_cnt != 0)
1351 			bconfig |= CFG_BMAC_RX_PROMISCUOUSGROUP;
1352 
1353 		bconfig |= CFG_BMAC_RX_HASH_FILTER;
1354 		if ((rs = npi_bmac_rx_config(handle, INIT, portn,
1355 					bconfig)) != NPI_SUCCESS)
1356 			goto fail;
1357 		nxgep->mac.rx_config = bconfig;
1358 
1359 		/* Always enable comparison of mac unique address */
1360 		if ((rs = npi_mac_altaddr_enable(handle, portn, 0))
1361 					!= NPI_SUCCESS)
1362 			goto fail;
1363 	}
1364 
1365 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_init: port<%d>\n",
1366 			portn));
1367 
1368 	return (NXGE_OK);
1369 
1370 fail:
1371 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1372 		"nxge_rx_mac_init: Failed to Initialize port<%d> RxMAC",
1373 				portn));
1374 
1375 	return (NXGE_ERROR | rs);
1376 }
1377 
1378 /* Enable TXMAC */
1379 
1380 nxge_status_t
1381 nxge_tx_mac_enable(p_nxge_t nxgep)
1382 {
1383 	npi_handle_t	handle;
1384 	npi_status_t	rs = NPI_SUCCESS;
1385 	nxge_status_t	status = NXGE_OK;
1386 
1387 	handle = nxgep->npi_handle;
1388 
1389 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_enable: port<%d>",
1390 			nxgep->mac.portnum));
1391 
1392 	if ((status = nxge_tx_mac_init(nxgep)) != NXGE_OK)
1393 		goto fail;
1394 
1395 	/* based on speed */
1396 	nxgep->msg_min = ETHERMIN;
1397 
1398 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
1399 		if ((rs = npi_xmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
1400 						CFG_XMAC_TX)) != NPI_SUCCESS)
1401 			goto fail;
1402 	} else {
1403 		if ((rs = npi_bmac_tx_config(handle, ENABLE, nxgep->mac.portnum,
1404 						CFG_BMAC_TX)) != NPI_SUCCESS)
1405 			goto fail;
1406 	}
1407 
1408 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_enable: port<%d>",
1409 			nxgep->mac.portnum));
1410 
1411 	return (NXGE_OK);
1412 fail:
1413 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1414 			"nxgep_tx_mac_enable: Failed to enable port<%d> TxMAC",
1415 			nxgep->mac.portnum));
1416 	if (rs != NPI_SUCCESS)
1417 		return (NXGE_ERROR | rs);
1418 	else
1419 		return (status);
1420 }
1421 
1422 /* Disable TXMAC */
1423 
1424 nxge_status_t
1425 nxge_tx_mac_disable(p_nxge_t nxgep)
1426 {
1427 	npi_handle_t	handle;
1428 	npi_status_t	rs = NPI_SUCCESS;
1429 
1430 	handle = nxgep->npi_handle;
1431 
1432 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_disable: port<%d>",
1433 			nxgep->mac.portnum));
1434 
1435 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
1436 		if ((rs = npi_xmac_tx_config(handle, DISABLE,
1437 			nxgep->mac.portnum, CFG_XMAC_TX)) != NPI_SUCCESS)
1438 			goto fail;
1439 	} else {
1440 		if ((rs = npi_bmac_tx_config(handle, DISABLE,
1441 			nxgep->mac.portnum, CFG_BMAC_TX)) != NPI_SUCCESS)
1442 			goto fail;
1443 	}
1444 
1445 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_disable: port<%d>",
1446 			nxgep->mac.portnum));
1447 	return (NXGE_OK);
1448 fail:
1449 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1450 			"nxge_tx_mac_disable: Failed to disable port<%d> TxMAC",
1451 			nxgep->mac.portnum));
1452 	return (NXGE_ERROR | rs);
1453 }
1454 
1455 /* Enable RXMAC */
1456 
1457 nxge_status_t
1458 nxge_rx_mac_enable(p_nxge_t nxgep)
1459 {
1460 	npi_handle_t	handle;
1461 	uint8_t 	portn;
1462 	npi_status_t	rs = NPI_SUCCESS;
1463 	nxge_status_t	status = NXGE_OK;
1464 
1465 	handle = nxgep->npi_handle;
1466 	portn = nxgep->mac.portnum;
1467 
1468 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_enable: port<%d>",
1469 			portn));
1470 
1471 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
1472 		goto fail;
1473 
1474 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
1475 		if ((rs = npi_xmac_rx_config(handle, ENABLE, portn,
1476 						CFG_XMAC_RX)) != NPI_SUCCESS)
1477 			goto fail;
1478 	} else {
1479 		if ((rs = npi_bmac_rx_config(handle, ENABLE, portn,
1480 						CFG_BMAC_RX)) != NPI_SUCCESS)
1481 			goto fail;
1482 	}
1483 
1484 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_enable: port<%d>",
1485 			portn));
1486 
1487 	return (NXGE_OK);
1488 fail:
1489 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1490 			"nxgep_rx_mac_enable: Failed to enable port<%d> RxMAC",
1491 			portn));
1492 
1493 	if (rs != NPI_SUCCESS)
1494 		return (NXGE_ERROR | rs);
1495 	else
1496 		return (status);
1497 }
1498 
1499 /* Disable RXMAC */
1500 
1501 nxge_status_t
1502 nxge_rx_mac_disable(p_nxge_t nxgep)
1503 {
1504 	npi_handle_t	handle;
1505 	uint8_t		portn;
1506 	npi_status_t	rs = NPI_SUCCESS;
1507 
1508 	handle = nxgep->npi_handle;
1509 	portn = nxgep->mac.portnum;
1510 
1511 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_disable: port<%d>",
1512 			portn));
1513 
1514 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
1515 		if ((rs = npi_xmac_rx_config(handle, DISABLE, portn,
1516 						CFG_XMAC_RX)) != NPI_SUCCESS)
1517 			goto fail;
1518 	} else {
1519 		if ((rs = npi_bmac_rx_config(handle, DISABLE, portn,
1520 						CFG_BMAC_RX)) != NPI_SUCCESS)
1521 			goto fail;
1522 	}
1523 
1524 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_disable: port<%d>",
1525 			portn));
1526 	return (NXGE_OK);
1527 fail:
1528 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1529 			"nxgep_rx_mac_disable: ",
1530 			"Failed to disable port<%d> RxMAC",
1531 			portn));
1532 
1533 	return (NXGE_ERROR | rs);
1534 }
1535 
1536 /* Reset TXMAC */
1537 
1538 nxge_status_t
1539 nxge_tx_mac_reset(p_nxge_t nxgep)
1540 {
1541 	npi_handle_t	handle;
1542 	uint8_t		portn;
1543 	npi_status_t	rs = NPI_SUCCESS;
1544 
1545 	handle = nxgep->npi_handle;
1546 	portn = nxgep->mac.portnum;
1547 
1548 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_tx_mac_reset: port<%d>",
1549 			portn));
1550 
1551 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
1552 		if ((rs = npi_xmac_reset(handle, portn, XTX_MAC_RESET_ALL))
1553 		    != NPI_SUCCESS)
1554 			goto fail;
1555 	} else {
1556 		if ((rs = npi_bmac_reset(handle, portn, TX_MAC_RESET))
1557 					!= NPI_SUCCESS)
1558 			goto fail;
1559 	}
1560 
1561 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_tx_mac_reset: port<%d>",
1562 			portn));
1563 
1564 	return (NXGE_OK);
1565 fail:
1566 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1567 			"nxge_tx_mac_reset: Failed to Reset TxMAC port<%d>",
1568 			portn));
1569 
1570 	return (NXGE_ERROR | rs);
1571 }
1572 
1573 /* Reset RXMAC */
1574 
1575 nxge_status_t
1576 nxge_rx_mac_reset(p_nxge_t nxgep)
1577 {
1578 	npi_handle_t	handle;
1579 	uint8_t		portn;
1580 	npi_status_t	rs = NPI_SUCCESS;
1581 
1582 	handle = nxgep->npi_handle;
1583 	portn = nxgep->mac.portnum;
1584 
1585 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_rx_mac_reset: port<%d>",
1586 			portn));
1587 
1588 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
1589 		if ((rs = npi_xmac_reset(handle, portn, XRX_MAC_RESET_ALL))
1590 		    != NPI_SUCCESS)
1591 		goto fail;
1592 	} else {
1593 		if ((rs = npi_bmac_reset(handle, portn, RX_MAC_RESET))
1594 					!= NPI_SUCCESS)
1595 		goto fail;
1596 	}
1597 
1598 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_rx_mac_reset: port<%d>",
1599 			portn));
1600 
1601 	return (NXGE_OK);
1602 fail:
1603 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1604 			"nxge_rx_mac_reset: Failed to Reset RxMAC port<%d>",
1605 			portn));
1606 	return (NXGE_ERROR | rs);
1607 }
1608 
1609 
1610 /* Enable/Disable MII Link Status change interrupt */
1611 
1612 nxge_status_t
1613 nxge_link_intr(p_nxge_t nxgep, link_intr_enable_t enable)
1614 {
1615 	uint8_t			portn;
1616 	nxge_port_mode_t	portmode;
1617 	npi_status_t		rs = NPI_SUCCESS;
1618 
1619 	portn = nxgep->mac.portnum;
1620 	portmode = nxgep->mac.portmode;
1621 
1622 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_intr: port<%d>", portn));
1623 
1624 	if (enable == LINK_INTR_START) {
1625 		if (portmode == PORT_10G_FIBER) {
1626 			if ((rs = npi_xmac_xpcs_link_intr_enable(
1627 						nxgep->npi_handle,
1628 						portn)) != NPI_SUCCESS)
1629 				goto fail;
1630 		} else if (portmode == PORT_1G_FIBER) {
1631 			if ((rs = npi_mac_pcs_link_intr_enable(
1632 						nxgep->npi_handle,
1633 						portn)) != NPI_SUCCESS)
1634 				goto fail;
1635 		} else if (portmode == PORT_1G_COPPER) {
1636 			if ((rs = npi_mac_mif_link_intr_enable(
1637 				nxgep->npi_handle,
1638 				portn, MII_BMSR, BMSR_LSTATUS)) != NPI_SUCCESS)
1639 				goto fail;
1640 		} else
1641 			goto fail;
1642 	} else if (enable == LINK_INTR_STOP) {
1643 		if (portmode == PORT_10G_FIBER) {
1644 			if ((rs = npi_xmac_xpcs_link_intr_disable(
1645 						nxgep->npi_handle,
1646 						portn)) != NPI_SUCCESS)
1647 				goto fail;
1648 		} else  if (portmode == PORT_1G_FIBER) {
1649 			if ((rs = npi_mac_pcs_link_intr_disable(
1650 						nxgep->npi_handle,
1651 						portn)) != NPI_SUCCESS)
1652 				goto fail;
1653 		} else if (portmode == PORT_1G_COPPER) {
1654 			if ((rs = npi_mac_mif_link_intr_disable(
1655 						nxgep->npi_handle,
1656 						portn)) != NPI_SUCCESS)
1657 				goto fail;
1658 		} else
1659 			goto fail;
1660 	}
1661 
1662 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_intr: port<%d>", portn));
1663 
1664 	return (NXGE_OK);
1665 fail:
1666 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1667 			"nxge_link_intr: Failed to set port<%d> mif intr mode",
1668 			portn));
1669 
1670 	return (NXGE_ERROR | rs);
1671 }
1672 
1673 /* Initialize 1G Fiber / Copper transceiver using Clause 22 */
1674 
1675 nxge_status_t
1676 nxge_mii_xcvr_init(p_nxge_t nxgep)
1677 {
1678 	p_nxge_param_t	param_arr;
1679 	p_nxge_stats_t	statsp;
1680 	uint8_t		xcvr_portn;
1681 	p_mii_regs_t	mii_regs;
1682 	mii_bmcr_t	bmcr;
1683 	mii_bmsr_t	bmsr;
1684 	mii_anar_t	anar;
1685 	mii_gcr_t	gcr;
1686 	mii_esr_t	esr;
1687 	mii_aux_ctl_t	bcm5464r_aux;
1688 	int		status = NXGE_OK;
1689 
1690 	uint_t delay;
1691 
1692 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_xcvr_init"));
1693 
1694 	param_arr = nxgep->param_arr;
1695 	statsp = nxgep->statsp;
1696 	xcvr_portn = statsp->mac_stats.xcvr_portn;
1697 
1698 	mii_regs = NULL;
1699 
1700 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1701 		"nxge_param_autoneg = 0x%02x", param_arr[param_autoneg].value));
1702 
1703 	/*
1704 	 * Reset the transceiver.
1705 	 */
1706 	delay = 0;
1707 	bmcr.value = 0;
1708 	bmcr.bits.reset = 1;
1709 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
1710 		(uint8_t)(uint64_t)&mii_regs->bmcr, bmcr.value)) != NXGE_OK)
1711 		goto fail;
1712 	do {
1713 		drv_usecwait(500);
1714 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
1715 			(uint8_t)(uint64_t)&mii_regs->bmcr, &bmcr.value))
1716 				!= NXGE_OK)
1717 			goto fail;
1718 		delay++;
1719 	} while ((bmcr.bits.reset) && (delay < 1000));
1720 	if (delay == 1000) {
1721 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Xcvr reset failed."));
1722 		goto fail;
1723 	}
1724 
1725 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
1726 			(uint8_t)(uint64_t)(&mii_regs->bmsr),
1727 			&bmsr.value)) != NXGE_OK)
1728 		goto fail;
1729 
1730 	param_arr[param_autoneg].value &= bmsr.bits.auto_neg_able;
1731 	param_arr[param_anar_100T4].value &= bmsr.bits.link_100T4;
1732 	param_arr[param_anar_100fdx].value &= bmsr.bits.link_100fdx;
1733 	param_arr[param_anar_100hdx].value = 0;
1734 	param_arr[param_anar_10fdx].value &= bmsr.bits.link_10fdx;
1735 	param_arr[param_anar_10hdx].value = 0;
1736 
1737 	/*
1738 	 * Initialize the xcvr statistics.
1739 	 */
1740 	statsp->mac_stats.cap_autoneg = bmsr.bits.auto_neg_able;
1741 	statsp->mac_stats.cap_100T4 = bmsr.bits.link_100T4;
1742 	statsp->mac_stats.cap_100fdx = bmsr.bits.link_100fdx;
1743 	statsp->mac_stats.cap_100hdx = 0;
1744 	statsp->mac_stats.cap_10fdx = bmsr.bits.link_10fdx;
1745 	statsp->mac_stats.cap_10hdx = 0;
1746 	statsp->mac_stats.cap_asmpause = param_arr[param_anar_asmpause].value;
1747 	statsp->mac_stats.cap_pause = param_arr[param_anar_pause].value;
1748 
1749 	/*
1750 	 * Initialise the xcvr advertised capability statistics.
1751 	 */
1752 	statsp->mac_stats.adv_cap_autoneg = param_arr[param_autoneg].value;
1753 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
1754 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
1755 	statsp->mac_stats.adv_cap_100T4 = param_arr[param_anar_100T4].value;
1756 	statsp->mac_stats.adv_cap_100fdx = param_arr[param_anar_100fdx].value;
1757 	statsp->mac_stats.adv_cap_100hdx = param_arr[param_anar_100hdx].value;
1758 	statsp->mac_stats.adv_cap_10fdx = param_arr[param_anar_10fdx].value;
1759 	statsp->mac_stats.adv_cap_10hdx = param_arr[param_anar_10hdx].value;
1760 	statsp->mac_stats.adv_cap_asmpause =
1761 					param_arr[param_anar_asmpause].value;
1762 	statsp->mac_stats.adv_cap_pause = param_arr[param_anar_pause].value;
1763 
1764 
1765 	/*
1766 	 * Check for extended status just in case we're
1767 	 * running a Gigibit phy.
1768 	 */
1769 	if (bmsr.bits.extend_status) {
1770 		if ((status = nxge_mii_read(nxgep, xcvr_portn,
1771 			(uint8_t)(uint64_t)(&mii_regs->esr), &esr.value))
1772 				!= NXGE_OK)
1773 			goto fail;
1774 		param_arr[param_anar_1000fdx].value &=
1775 					esr.bits.link_1000fdx;
1776 		param_arr[param_anar_1000hdx].value = 0;
1777 
1778 		statsp->mac_stats.cap_1000fdx =
1779 			(esr.bits.link_1000Xfdx ||
1780 				esr.bits.link_1000fdx);
1781 		statsp->mac_stats.cap_1000hdx = 0;
1782 	} else {
1783 		param_arr[param_anar_1000fdx].value = 0;
1784 		param_arr[param_anar_1000hdx].value = 0;
1785 	}
1786 
1787 	/*
1788 	 * Initialize 1G Statistics once the capability is established.
1789 	 */
1790 	statsp->mac_stats.adv_cap_1000fdx = param_arr[param_anar_1000fdx].value;
1791 	statsp->mac_stats.adv_cap_1000hdx = param_arr[param_anar_1000hdx].value;
1792 
1793 	/*
1794 	 * Initialise the link statistics.
1795 	 */
1796 	statsp->mac_stats.link_T4 = 0;
1797 	statsp->mac_stats.link_asmpause = 0;
1798 	statsp->mac_stats.link_pause = 0;
1799 	statsp->mac_stats.link_speed = 0;
1800 	statsp->mac_stats.link_duplex = 0;
1801 	statsp->mac_stats.link_up = 0;
1802 
1803 	/*
1804 	 * Switch off Auto-negotiation, 100M and full duplex.
1805 	 */
1806 	bmcr.value = 0;
1807 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
1808 		(uint8_t)(uint64_t)(&mii_regs->bmcr), bmcr.value)) != NXGE_OK)
1809 		goto fail;
1810 
1811 	if ((statsp->port_stats.lb_mode == nxge_lb_phy) ||
1812 			(statsp->port_stats.lb_mode == nxge_lb_phy1000)) {
1813 		bmcr.bits.loopback = 1;
1814 		bmcr.bits.enable_autoneg = 0;
1815 		if (statsp->port_stats.lb_mode == nxge_lb_phy1000)
1816 			bmcr.bits.speed_1000_sel = 1;
1817 		bmcr.bits.duplex_mode = 1;
1818 		param_arr[param_autoneg].value = 0;
1819 	} else {
1820 		bmcr.bits.loopback = 0;
1821 	}
1822 
1823 	if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
1824 		(statsp->port_stats.lb_mode == nxge_lb_ext100) ||
1825 		(statsp->port_stats.lb_mode == nxge_lb_ext10)) {
1826 		param_arr[param_autoneg].value = 0;
1827 		bcm5464r_aux.value = 0;
1828 		bcm5464r_aux.bits.ext_lb = 1;
1829 		bcm5464r_aux.bits.write_1 = 1;
1830 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
1831 				BCM5464R_AUX_CTL, bcm5464r_aux.value))
1832 				!= NXGE_OK)
1833 			goto fail;
1834 	}
1835 
1836 	if (param_arr[param_autoneg].value) {
1837 		NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1838 				"Restarting Auto-negotiation."));
1839 		/*
1840 		 * Setup our Auto-negotiation advertisement register.
1841 		 */
1842 		anar.value = 0;
1843 		anar.bits.selector = 1;
1844 		anar.bits.cap_100T4 = param_arr[param_anar_100T4].value;
1845 		anar.bits.cap_100fdx = param_arr[param_anar_100fdx].value;
1846 		anar.bits.cap_100hdx = param_arr[param_anar_100hdx].value;
1847 		anar.bits.cap_10fdx = param_arr[param_anar_10fdx].value;
1848 		anar.bits.cap_10hdx = param_arr[param_anar_10hdx].value;
1849 		anar.bits.cap_asmpause = 0;
1850 		anar.bits.cap_pause = 0;
1851 		if (param_arr[param_anar_1000fdx].value ||
1852 			param_arr[param_anar_100fdx].value ||
1853 			param_arr[param_anar_10fdx].value) {
1854 			anar.bits.cap_asmpause = statsp->mac_stats.cap_asmpause;
1855 			anar.bits.cap_pause = statsp->mac_stats.cap_pause;
1856 		}
1857 
1858 		if ((status = nxge_mii_write(nxgep, xcvr_portn,
1859 			(uint8_t)(uint64_t)(&mii_regs->anar), anar.value))
1860 				!= NXGE_OK)
1861 			goto fail;
1862 		if (bmsr.bits.extend_status) {
1863 			gcr.value = 0;
1864 			gcr.bits.ms_mode_en =
1865 				param_arr[param_master_cfg_enable].value;
1866 			gcr.bits.master =
1867 				param_arr[param_master_cfg_value].value;
1868 			gcr.bits.link_1000fdx =
1869 				param_arr[param_anar_1000fdx].value;
1870 			gcr.bits.link_1000hdx =
1871 				param_arr[param_anar_1000hdx].value;
1872 			if ((status = nxge_mii_write(nxgep, xcvr_portn,
1873 				(uint8_t)(uint64_t)(&mii_regs->gcr), gcr.value))
1874 				!= NXGE_OK)
1875 				goto fail;
1876 		}
1877 
1878 		bmcr.bits.enable_autoneg = 1;
1879 		bmcr.bits.restart_autoneg = 1;
1880 
1881 	} else {
1882 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "Going into forced mode."));
1883 		bmcr.bits.speed_1000_sel =
1884 			param_arr[param_anar_1000fdx].value |
1885 				param_arr[param_anar_1000hdx].value;
1886 		bmcr.bits.speed_sel = (~bmcr.bits.speed_1000_sel) &
1887 			(param_arr[param_anar_100fdx].value |
1888 				param_arr[param_anar_100hdx].value);
1889 		if (bmcr.bits.speed_1000_sel) {
1890 			statsp->mac_stats.link_speed = 1000;
1891 			gcr.value = 0;
1892 			gcr.bits.ms_mode_en =
1893 				param_arr[param_master_cfg_enable].value;
1894 			gcr.bits.master =
1895 				param_arr[param_master_cfg_value].value;
1896 			if ((status = nxge_mii_write(nxgep, xcvr_portn,
1897 				(uint8_t)(uint64_t)(&mii_regs->gcr),
1898 				gcr.value))
1899 				!= NXGE_OK)
1900 				goto fail;
1901 			if (param_arr[param_anar_1000fdx].value) {
1902 				bmcr.bits.duplex_mode = 1;
1903 				statsp->mac_stats.link_duplex = 2;
1904 			} else
1905 				statsp->mac_stats.link_duplex = 1;
1906 		} else if (bmcr.bits.speed_sel) {
1907 			statsp->mac_stats.link_speed = 100;
1908 			if (param_arr[param_anar_100fdx].value) {
1909 				bmcr.bits.duplex_mode = 1;
1910 				statsp->mac_stats.link_duplex = 2;
1911 			} else
1912 				statsp->mac_stats.link_duplex = 1;
1913 		} else {
1914 			statsp->mac_stats.link_speed = 10;
1915 			if (param_arr[param_anar_10fdx].value) {
1916 				bmcr.bits.duplex_mode = 1;
1917 				statsp->mac_stats.link_duplex = 2;
1918 			} else
1919 				statsp->mac_stats.link_duplex = 1;
1920 		}
1921 		if (statsp->mac_stats.link_duplex != 1) {
1922 			statsp->mac_stats.link_asmpause =
1923 						statsp->mac_stats.cap_asmpause;
1924 			statsp->mac_stats.link_pause =
1925 						statsp->mac_stats.cap_pause;
1926 		}
1927 
1928 		if ((statsp->port_stats.lb_mode == nxge_lb_ext1000) ||
1929 			(statsp->port_stats.lb_mode == nxge_lb_ext100) ||
1930 			(statsp->port_stats.lb_mode == nxge_lb_ext10)) {
1931 			if (statsp->port_stats.lb_mode == nxge_lb_ext1000) {
1932 				/* BCM5464R 1000mbps external loopback mode */
1933 				gcr.value = 0;
1934 				gcr.bits.ms_mode_en = 1;
1935 				gcr.bits.master = 1;
1936 				if ((status = nxge_mii_write(nxgep, xcvr_portn,
1937 					(uint8_t)(uint64_t)(&mii_regs->gcr),
1938 					gcr.value))
1939 					!= NXGE_OK)
1940 					goto fail;
1941 				bmcr.value = 0;
1942 				bmcr.bits.speed_1000_sel = 1;
1943 				statsp->mac_stats.link_speed = 1000;
1944 			} else if (statsp->port_stats.lb_mode
1945 			    == nxge_lb_ext100) {
1946 				/* BCM5464R 100mbps external loopback mode */
1947 				bmcr.value = 0;
1948 				bmcr.bits.speed_sel = 1;
1949 				bmcr.bits.duplex_mode = 1;
1950 				statsp->mac_stats.link_speed = 100;
1951 			} else if (statsp->port_stats.lb_mode
1952 			    == nxge_lb_ext10) {
1953 				/* BCM5464R 10mbps external loopback mode */
1954 				bmcr.value = 0;
1955 				bmcr.bits.duplex_mode = 1;
1956 				statsp->mac_stats.link_speed = 10;
1957 			}
1958 		}
1959 	}
1960 
1961 	if ((status = nxge_mii_write(nxgep, xcvr_portn,
1962 			(uint8_t)(uint64_t)(&mii_regs->bmcr),
1963 			bmcr.value)) != NXGE_OK)
1964 		goto fail;
1965 
1966 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
1967 		(uint8_t)(uint64_t)(&mii_regs->bmcr), &bmcr.value)) != NXGE_OK)
1968 		goto fail;
1969 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "bmcr = 0x%04X", bmcr.value));
1970 
1971 	/*
1972 	 * Initialize the xcvr status kept in the context structure.
1973 	 */
1974 	nxgep->soft_bmsr.value = 0;
1975 
1976 	if ((status = nxge_mii_read(nxgep, xcvr_portn,
1977 		(uint8_t)(uint64_t)(&mii_regs->bmsr),
1978 			&nxgep->bmsr.value)) != NXGE_OK)
1979 		goto fail;
1980 
1981 	statsp->mac_stats.xcvr_inits++;
1982 	nxgep->bmsr.value = 0;
1983 
1984 fail:
1985 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
1986 			"<== nxge_mii_xcvr_init status 0x%x", status));
1987 	return (status);
1988 }
1989 
1990 /* Read from a MII compliant register */
1991 
1992 nxge_status_t
1993 nxge_mii_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
1994 		uint16_t *value)
1995 {
1996 	npi_status_t rs = NPI_SUCCESS;
1997 
1998 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_read: xcvr_port<%d>"
1999 			"xcvr_reg<%d>", xcvr_portn, xcvr_reg));
2000 
2001 	MUTEX_ENTER(&nxge_mii_lock);
2002 
2003 	if (nxgep->mac.portmode == PORT_1G_COPPER) {
2004 		if ((rs = npi_mac_mif_mii_read(nxgep->npi_handle,
2005 				xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
2006 			goto fail;
2007 	} else if (nxgep->mac.portmode == PORT_1G_FIBER) {
2008 		if ((rs = npi_mac_pcs_mii_read(nxgep->npi_handle,
2009 				xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
2010 			goto fail;
2011 	} else
2012 		goto fail;
2013 
2014 	MUTEX_EXIT(&nxge_mii_lock);
2015 
2016 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_read: xcvr_port<%d>"
2017 			"xcvr_reg<%d> value=0x%x",
2018 			xcvr_portn, xcvr_reg, *value));
2019 	return (NXGE_OK);
2020 fail:
2021 	MUTEX_EXIT(&nxge_mii_lock);
2022 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2023 			"nxge_mii_read: Failed to read mii on xcvr %d",
2024 			xcvr_portn));
2025 
2026 	return (NXGE_ERROR | rs);
2027 }
2028 
2029 /* Write to a MII compliant Register */
2030 
2031 nxge_status_t
2032 nxge_mii_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t xcvr_reg,
2033 		uint16_t value)
2034 {
2035 	npi_status_t rs = NPI_SUCCESS;
2036 
2037 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mii_write: xcvr_port<%d>"
2038 			"xcvr_reg<%d> value=0x%x", xcvr_portn, xcvr_reg,
2039 			value));
2040 
2041 	MUTEX_ENTER(&nxge_mii_lock);
2042 
2043 	if (nxgep->mac.portmode == PORT_1G_COPPER) {
2044 		if ((rs = npi_mac_mif_mii_write(nxgep->npi_handle,
2045 				xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
2046 			goto fail;
2047 	} else if (nxgep->mac.portmode == PORT_1G_FIBER) {
2048 		if ((rs = npi_mac_pcs_mii_write(nxgep->npi_handle,
2049 				xcvr_portn, xcvr_reg, value)) != NPI_SUCCESS)
2050 			goto fail;
2051 	} else
2052 		goto fail;
2053 
2054 	MUTEX_EXIT(&nxge_mii_lock);
2055 
2056 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mii_write: xcvr_port<%d>"
2057 			"xcvr_reg<%d>", xcvr_portn, xcvr_reg));
2058 	return (NXGE_OK);
2059 fail:
2060 	MUTEX_EXIT(&nxge_mii_lock);
2061 
2062 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2063 			"nxge_mii_write: Failed to write mii on xcvr %d",
2064 			xcvr_portn));
2065 
2066 	return (NXGE_ERROR | rs);
2067 }
2068 
2069 /* Perform read from Clause45 serdes / transceiver device */
2070 
2071 nxge_status_t
2072 nxge_mdio_read(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
2073 		uint16_t xcvr_reg, uint16_t *value)
2074 {
2075 	npi_status_t rs = NPI_SUCCESS;
2076 
2077 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_read: xcvr_port<%d>",
2078 			xcvr_portn));
2079 
2080 	MUTEX_ENTER(&nxge_mdio_lock);
2081 
2082 	if ((rs = npi_mac_mif_mdio_read(nxgep->npi_handle,
2083 			xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
2084 		goto fail;
2085 
2086 	MUTEX_EXIT(&nxge_mdio_lock);
2087 
2088 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_read: xcvr_port<%d>",
2089 			xcvr_portn));
2090 	return (NXGE_OK);
2091 fail:
2092 	MUTEX_EXIT(&nxge_mdio_lock);
2093 
2094 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2095 			"nxge_mdio_read: Failed to read mdio on xcvr %d",
2096 			xcvr_portn));
2097 
2098 	return (NXGE_ERROR | rs);
2099 }
2100 
2101 /* Perform write to Clause45 serdes / transceiver device */
2102 
2103 nxge_status_t
2104 nxge_mdio_write(p_nxge_t nxgep, uint8_t xcvr_portn, uint8_t device,
2105 		uint16_t xcvr_reg, uint16_t value)
2106 {
2107 	npi_status_t rs = NPI_SUCCESS;
2108 
2109 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "==> nxge_mdio_write: xcvr_port<%d>",
2110 			xcvr_portn));
2111 
2112 	MUTEX_ENTER(&nxge_mdio_lock);
2113 
2114 	if ((rs = npi_mac_mif_mdio_write(nxgep->npi_handle,
2115 			xcvr_portn, device, xcvr_reg, value)) != NPI_SUCCESS)
2116 		goto fail;
2117 
2118 	MUTEX_EXIT(&nxge_mdio_lock);
2119 
2120 	NXGE_DEBUG_MSG((nxgep, MIF_CTL, "<== nxge_mdio_write: xcvr_port<%d>",
2121 			xcvr_portn));
2122 	return (NXGE_OK);
2123 fail:
2124 	MUTEX_EXIT(&nxge_mdio_lock);
2125 
2126 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2127 			"nxge_mdio_write: Failed to write mdio on xcvr %d",
2128 			xcvr_portn));
2129 
2130 	return (NXGE_ERROR | rs);
2131 }
2132 
2133 
2134 /* Check MII to see if there is any link status change */
2135 
2136 nxge_status_t
2137 nxge_mii_check(p_nxge_t nxgep, mii_bmsr_t bmsr, mii_bmsr_t bmsr_ints,
2138 		nxge_link_state_t *link_up)
2139 {
2140 	p_nxge_param_t	param_arr;
2141 	p_nxge_stats_t	statsp;
2142 	p_mii_regs_t	mii_regs;
2143 	p_mii_bmsr_t	soft_bmsr;
2144 	mii_anar_t	anar;
2145 	mii_anlpar_t	anlpar;
2146 	mii_anar_t	an_common;
2147 	mii_aner_t	aner;
2148 	mii_gsr_t	gsr;
2149 	nxge_status_t	status = NXGE_OK;
2150 
2151 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_mii_check"));
2152 
2153 	mii_regs = NULL;
2154 	param_arr = nxgep->param_arr;
2155 	statsp = nxgep->statsp;
2156 	soft_bmsr = &nxgep->soft_bmsr;
2157 	*link_up = LINK_NO_CHANGE;
2158 
2159 	if (bmsr_ints.bits.link_status) {
2160 		if (bmsr.bits.link_status) {
2161 			soft_bmsr->bits.link_status = 1;
2162 		} else {
2163 			statsp->mac_stats.link_up = 0;
2164 			soft_bmsr->bits.link_status = 0;
2165 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2166 					"Link down cable problem"));
2167 			*link_up = LINK_IS_DOWN;
2168 		}
2169 	}
2170 
2171 	if (param_arr[param_autoneg].value) {
2172 		if (bmsr_ints.bits.auto_neg_complete) {
2173 			if (bmsr.bits.auto_neg_complete)
2174 				soft_bmsr->bits.auto_neg_complete = 1;
2175 			else
2176 				soft_bmsr->bits.auto_neg_complete = 0;
2177 		}
2178 		if (soft_bmsr->bits.link_status == 0) {
2179 			statsp->mac_stats.link_T4 = 0;
2180 			statsp->mac_stats.link_speed = 0;
2181 			statsp->mac_stats.link_duplex = 0;
2182 			statsp->mac_stats.link_asmpause = 0;
2183 			statsp->mac_stats.link_pause = 0;
2184 			statsp->mac_stats.lp_cap_autoneg = 0;
2185 			statsp->mac_stats.lp_cap_100T4 = 0;
2186 			statsp->mac_stats.lp_cap_1000fdx = 0;
2187 			statsp->mac_stats.lp_cap_1000hdx = 0;
2188 			statsp->mac_stats.lp_cap_100fdx = 0;
2189 			statsp->mac_stats.lp_cap_100hdx = 0;
2190 			statsp->mac_stats.lp_cap_10fdx = 0;
2191 			statsp->mac_stats.lp_cap_10hdx = 0;
2192 			statsp->mac_stats.lp_cap_10gfdx = 0;
2193 			statsp->mac_stats.lp_cap_10ghdx = 0;
2194 			statsp->mac_stats.lp_cap_asmpause = 0;
2195 			statsp->mac_stats.lp_cap_pause = 0;
2196 		}
2197 	} else
2198 		soft_bmsr->bits.auto_neg_complete = 1;
2199 
2200 	if ((bmsr_ints.bits.link_status ||
2201 		bmsr_ints.bits.auto_neg_complete) &&
2202 		soft_bmsr->bits.link_status &&
2203 		soft_bmsr->bits.auto_neg_complete) {
2204 		statsp->mac_stats.link_up = 1;
2205 		if (param_arr[param_autoneg].value) {
2206 			if ((status = nxge_mii_read(nxgep,
2207 				statsp->mac_stats.xcvr_portn,
2208 				(uint8_t)(uint64_t)(&mii_regs->anar),
2209 					&anar.value)) != NXGE_OK)
2210 				goto fail;
2211 			if ((status = nxge_mii_read(nxgep,
2212 				statsp->mac_stats.xcvr_portn,
2213 				(uint8_t)(uint64_t)(&mii_regs->anlpar),
2214 					&anlpar.value)) != NXGE_OK)
2215 				goto fail;
2216 			if ((status = nxge_mii_read(nxgep,
2217 				statsp->mac_stats.xcvr_portn,
2218 				(uint8_t)(uint64_t)(&mii_regs->aner),
2219 					&aner.value)) != NXGE_OK)
2220 				goto fail;
2221 			statsp->mac_stats.lp_cap_autoneg = aner.bits.lp_an_able;
2222 			statsp->mac_stats.lp_cap_100T4 = anlpar.bits.cap_100T4;
2223 			statsp->mac_stats.lp_cap_100fdx =
2224 							anlpar.bits.cap_100fdx;
2225 			statsp->mac_stats.lp_cap_100hdx =
2226 							anlpar.bits.cap_100hdx;
2227 			statsp->mac_stats.lp_cap_10fdx = anlpar.bits.cap_10fdx;
2228 			statsp->mac_stats.lp_cap_10hdx = anlpar.bits.cap_10hdx;
2229 			statsp->mac_stats.lp_cap_asmpause =
2230 						anlpar.bits.cap_asmpause;
2231 			statsp->mac_stats.lp_cap_pause = anlpar.bits.cap_pause;
2232 			an_common.value = anar.value & anlpar.value;
2233 			if (param_arr[param_anar_1000fdx].value ||
2234 				param_arr[param_anar_1000hdx].value) {
2235 				if ((status = nxge_mii_read(nxgep,
2236 					statsp->mac_stats.xcvr_portn,
2237 					(uint8_t)(uint64_t)(&mii_regs->gsr),
2238 						&gsr.value))
2239 						!= NXGE_OK)
2240 					goto fail;
2241 				statsp->mac_stats.lp_cap_1000fdx =
2242 					gsr.bits.link_1000fdx;
2243 				statsp->mac_stats.lp_cap_1000hdx =
2244 					gsr.bits.link_1000hdx;
2245 				if (param_arr[param_anar_1000fdx].value &&
2246 					gsr.bits.link_1000fdx) {
2247 					statsp->mac_stats.link_speed = 1000;
2248 					statsp->mac_stats.link_duplex = 2;
2249 				} else if (
2250 					param_arr[param_anar_1000hdx].value &&
2251 						gsr.bits.link_1000hdx) {
2252 					statsp->mac_stats.link_speed = 1000;
2253 					statsp->mac_stats.link_duplex = 1;
2254 				}
2255 			}
2256 			if ((an_common.value != 0) &&
2257 					!(statsp->mac_stats.link_speed)) {
2258 				if (an_common.bits.cap_100T4) {
2259 					statsp->mac_stats.link_T4 = 1;
2260 					statsp->mac_stats.link_speed = 100;
2261 					statsp->mac_stats.link_duplex = 1;
2262 				} else if (an_common.bits.cap_100fdx) {
2263 					statsp->mac_stats.link_speed = 100;
2264 					statsp->mac_stats.link_duplex = 2;
2265 				} else if (an_common.bits.cap_100hdx) {
2266 					statsp->mac_stats.link_speed = 100;
2267 					statsp->mac_stats.link_duplex = 1;
2268 				} else if (an_common.bits.cap_10fdx) {
2269 					statsp->mac_stats.link_speed = 10;
2270 					statsp->mac_stats.link_duplex = 2;
2271 				} else if (an_common.bits.cap_10hdx) {
2272 					statsp->mac_stats.link_speed = 10;
2273 					statsp->mac_stats.link_duplex = 1;
2274 				} else {
2275 					goto fail;
2276 				}
2277 			}
2278 			if (statsp->mac_stats.link_duplex != 1) {
2279 				statsp->mac_stats.link_asmpause =
2280 					an_common.bits.cap_asmpause;
2281 				if (statsp->mac_stats.link_asmpause)
2282 				if ((statsp->mac_stats.cap_pause == 0) &&
2283 						(statsp->mac_stats.lp_cap_pause
2284 						== 1))
2285 						statsp->mac_stats.link_pause
2286 						= 0;
2287 					else
2288 						statsp->mac_stats.link_pause
2289 						= 1;
2290 				else
2291 					statsp->mac_stats.link_pause =
2292 						an_common.bits.cap_pause;
2293 			}
2294 		}
2295 		*link_up = LINK_IS_UP;
2296 	}
2297 
2298 	if (nxgep->link_notify) {
2299 		*link_up = ((statsp->mac_stats.link_up) ? LINK_IS_UP :
2300 				LINK_IS_DOWN);
2301 		nxgep->link_notify = B_FALSE;
2302 	}
2303 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_mii_check"));
2304 	return (NXGE_OK);
2305 fail:
2306 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2307 			"nxge_mii_check: Unable to check MII"));
2308 	return (status);
2309 }
2310 
2311 /* Add a multicast address entry into the HW hash table */
2312 
2313 nxge_status_t
2314 nxge_add_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
2315 {
2316 	uint32_t mchash;
2317 	p_hash_filter_t hash_filter;
2318 	uint16_t hash_bit;
2319 	boolean_t rx_init = B_FALSE;
2320 	uint_t j;
2321 	nxge_status_t status = NXGE_OK;
2322 
2323 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_add_mcast_addr"));
2324 
2325 	RW_ENTER_WRITER(&nxgep->filter_lock);
2326 	mchash = crc32_mchash(addrp);
2327 	if (nxgep->hash_filter == NULL) {
2328 		NXGE_DEBUG_MSG((NULL, STR_CTL,
2329 			"Allocating hash filter storage."));
2330 		nxgep->hash_filter = KMEM_ZALLOC(sizeof (hash_filter_t),
2331 					KM_SLEEP);
2332 	}
2333 	hash_filter = nxgep->hash_filter;
2334 	j = mchash / HASH_REG_WIDTH;
2335 	hash_bit = (1 << (mchash % HASH_REG_WIDTH));
2336 	hash_filter->hash_filter_regs[j] |= hash_bit;
2337 	hash_filter->hash_bit_ref_cnt[mchash]++;
2338 	if (hash_filter->hash_bit_ref_cnt[mchash] == 1) {
2339 		hash_filter->hash_ref_cnt++;
2340 		rx_init = B_TRUE;
2341 	}
2342 	if (rx_init) {
2343 		if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
2344 			goto fail;
2345 		if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
2346 			goto fail;
2347 	}
2348 
2349 	RW_EXIT(&nxgep->filter_lock);
2350 
2351 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_add_mcast_addr"));
2352 
2353 	return (NXGE_OK);
2354 fail:
2355 	RW_EXIT(&nxgep->filter_lock);
2356 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_mcast_addr: "
2357 					"Unable to add multicast address"));
2358 	return (status);
2359 }
2360 
2361 /* Remove a multicast address entry from the HW hash table */
2362 
2363 nxge_status_t
2364 nxge_del_mcast_addr(p_nxge_t nxgep, struct ether_addr *addrp)
2365 {
2366 	uint32_t mchash;
2367 	p_hash_filter_t hash_filter;
2368 	uint16_t hash_bit;
2369 	boolean_t rx_init = B_FALSE;
2370 	uint_t j;
2371 	nxge_status_t status = NXGE_OK;
2372 
2373 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_del_mcast_addr"));
2374 	RW_ENTER_WRITER(&nxgep->filter_lock);
2375 	mchash = crc32_mchash(addrp);
2376 	if (nxgep->hash_filter == NULL) {
2377 		NXGE_DEBUG_MSG((NULL, STR_CTL,
2378 			"Hash filter already de_allocated."));
2379 		RW_EXIT(&nxgep->filter_lock);
2380 		NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
2381 		return (NXGE_OK);
2382 	}
2383 	hash_filter = nxgep->hash_filter;
2384 	hash_filter->hash_bit_ref_cnt[mchash]--;
2385 	if (hash_filter->hash_bit_ref_cnt[mchash] == 0) {
2386 		j = mchash / HASH_REG_WIDTH;
2387 		hash_bit = (1 << (mchash % HASH_REG_WIDTH));
2388 		hash_filter->hash_filter_regs[j] &= ~hash_bit;
2389 		hash_filter->hash_ref_cnt--;
2390 		rx_init = B_TRUE;
2391 	}
2392 	if (hash_filter->hash_ref_cnt == 0) {
2393 		NXGE_DEBUG_MSG((NULL, STR_CTL,
2394 			"De-allocating hash filter storage."));
2395 		KMEM_FREE(hash_filter, sizeof (hash_filter_t));
2396 		nxgep->hash_filter = NULL;
2397 	}
2398 
2399 	if (rx_init) {
2400 		if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
2401 			goto fail;
2402 		if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
2403 			goto fail;
2404 	}
2405 	RW_EXIT(&nxgep->filter_lock);
2406 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_del_mcast_addr"));
2407 
2408 	return (NXGE_OK);
2409 fail:
2410 	RW_EXIT(&nxgep->filter_lock);
2411 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_mcast_addr: "
2412 			"Unable to remove multicast address"));
2413 
2414 	return (status);
2415 }
2416 
2417 /* Set MAC address into MAC address HW registers */
2418 
2419 nxge_status_t
2420 nxge_set_mac_addr(p_nxge_t nxgep, struct ether_addr *addrp)
2421 {
2422 	nxge_status_t status = NXGE_OK;
2423 
2424 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_set_mac_addr"));
2425 
2426 	MUTEX_ENTER(&nxgep->ouraddr_lock);
2427 	/*
2428 	 * Exit if the address is same as ouraddr or multicast or broadcast
2429 	 */
2430 	if (((addrp->ether_addr_octet[0] & 01) == 1) ||
2431 		(ether_cmp(addrp, &etherbroadcastaddr) == 0) ||
2432 		(ether_cmp(addrp, &nxgep->ouraddr) == 0)) {
2433 		goto nxge_set_mac_addr_exit;
2434 	}
2435 	nxgep->ouraddr = *addrp;
2436 	/*
2437 	 * Set new interface local address and re-init device.
2438 	 * This is destructive to any other streams attached
2439 	 * to this device.
2440 	 */
2441 	RW_ENTER_WRITER(&nxgep->filter_lock);
2442 	if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK)
2443 		goto fail;
2444 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK)
2445 		goto fail;
2446 
2447 	RW_EXIT(&nxgep->filter_lock);
2448 	MUTEX_EXIT(&nxgep->ouraddr_lock);
2449 	goto nxge_set_mac_addr_end;
2450 nxge_set_mac_addr_exit:
2451 	MUTEX_EXIT(&nxgep->ouraddr_lock);
2452 nxge_set_mac_addr_end:
2453 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_mac_addr"));
2454 
2455 	return (NXGE_OK);
2456 fail:
2457 	MUTEX_EXIT(&nxgep->ouraddr_lock);
2458 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_mac_addr: "
2459 			"Unable to set mac address"));
2460 	return (status);
2461 }
2462 
2463 /* Check status of MII (MIF or PCS) link */
2464 
2465 nxge_status_t
2466 nxge_check_mii_link(p_nxge_t nxgep)
2467 {
2468 	mii_bmsr_t bmsr_ints, bmsr_data;
2469 	mii_anlpar_t anlpar;
2470 	mii_gsr_t gsr;
2471 	p_mii_regs_t mii_regs;
2472 	nxge_status_t status = NXGE_OK;
2473 	uint8_t portn;
2474 	nxge_link_state_t link_up;
2475 
2476 	portn = nxgep->mac.portnum;
2477 
2478 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_mii_link port<%d>",
2479 				portn));
2480 
2481 	mii_regs = NULL;
2482 
2483 	RW_ENTER_WRITER(&nxgep->filter_lock);
2484 
2485 	if (nxgep->statsp->port_stats.lb_mode > nxge_lb_ext10)
2486 		goto nxge_check_mii_link_exit;
2487 
2488 	if ((status = nxge_mii_read(nxgep, nxgep->statsp->mac_stats.xcvr_portn,
2489 		(uint8_t)(uint64_t)(&mii_regs->bmsr),
2490 		&bmsr_data.value)) != NXGE_OK)
2491 		goto fail;
2492 
2493 	if (nxgep->param_arr[param_autoneg].value) {
2494 		if ((status = nxge_mii_read(nxgep,
2495 			nxgep->statsp->mac_stats.xcvr_portn,
2496 			(uint8_t)(uint64_t)(&mii_regs->gsr),
2497 			&gsr.value)) != NXGE_OK)
2498 			goto fail;
2499 		if ((status = nxge_mii_read(nxgep,
2500 			nxgep->statsp->mac_stats.xcvr_portn,
2501 			(uint8_t)(uint64_t)(&mii_regs->anlpar),
2502 			&anlpar.value)) != NXGE_OK)
2503 			goto fail;
2504 		if (nxgep->statsp->mac_stats.link_up &&
2505 			((nxgep->statsp->mac_stats.lp_cap_1000fdx ^
2506 				gsr.bits.link_1000fdx) ||
2507 			(nxgep->statsp->mac_stats.lp_cap_1000hdx ^
2508 				gsr.bits.link_1000hdx) ||
2509 			(nxgep->statsp->mac_stats.lp_cap_100T4 ^
2510 				anlpar.bits.cap_100T4) ||
2511 			(nxgep->statsp->mac_stats.lp_cap_100fdx ^
2512 				anlpar.bits.cap_100fdx) ||
2513 			(nxgep->statsp->mac_stats.lp_cap_100hdx ^
2514 				anlpar.bits.cap_100hdx) ||
2515 			(nxgep->statsp->mac_stats.lp_cap_10fdx ^
2516 				anlpar.bits.cap_10fdx) ||
2517 			(nxgep->statsp->mac_stats.lp_cap_10hdx ^
2518 				anlpar.bits.cap_10hdx))) {
2519 			bmsr_data.bits.link_status = 0;
2520 		}
2521 	}
2522 
2523 	/* Workaround for link down issue */
2524 	if (bmsr_data.value == 0) {
2525 		cmn_err(CE_NOTE, "!LINK DEBUG: Read zero bmsr\n");
2526 		goto nxge_check_mii_link_exit;
2527 	}
2528 
2529 	bmsr_ints.value = nxgep->bmsr.value ^ bmsr_data.value;
2530 	nxgep->bmsr.value = bmsr_data.value;
2531 	if ((status = nxge_mii_check(nxgep, bmsr_data, bmsr_ints, &link_up))
2532 			!= NXGE_OK)
2533 		goto fail;
2534 
2535 nxge_check_mii_link_exit:
2536 	RW_EXIT(&nxgep->filter_lock);
2537 	if (link_up == LINK_IS_UP) {
2538 		nxge_link_is_up(nxgep);
2539 	} else if (link_up == LINK_IS_DOWN) {
2540 		nxge_link_is_down(nxgep);
2541 	}
2542 
2543 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
2544 
2545 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_mii_link port<%d>",
2546 				portn));
2547 	return (NXGE_OK);
2548 
2549 fail:
2550 	RW_EXIT(&nxgep->filter_lock);
2551 
2552 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
2553 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2554 			"nxge_check_mii_link: Failed to check link port<%d>",
2555 			portn));
2556 	return (status);
2557 }
2558 
2559 
2560 /*ARGSUSED*/
2561 nxge_status_t
2562 nxge_check_10g_link(p_nxge_t nxgep)
2563 {
2564 	uint8_t		portn;
2565 
2566 	nxge_status_t	status = NXGE_OK;
2567 	boolean_t	link_up;
2568 
2569 	portn = nxgep->mac.portnum;
2570 
2571 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_check_10g_link port<%d>",
2572 				portn));
2573 
2574 	status = nxge_check_bcm8704_link(nxgep, &link_up);
2575 
2576 	if (status != NXGE_OK)
2577 		goto fail;
2578 
2579 	if (link_up) {
2580 		if (nxgep->link_notify ||
2581 			nxgep->statsp->mac_stats.link_up == 0) {
2582 			if (nxge_10g_link_led_on(nxgep) != NXGE_OK)
2583 				goto fail;
2584 			nxgep->statsp->mac_stats.link_up = 1;
2585 			nxgep->statsp->mac_stats.link_speed = 10000;
2586 			nxgep->statsp->mac_stats.link_duplex = 2;
2587 
2588 			nxge_link_is_up(nxgep);
2589 			nxgep->link_notify = B_FALSE;
2590 		}
2591 	} else {
2592 		if (nxgep->link_notify ||
2593 			nxgep->statsp->mac_stats.link_up == 1) {
2594 			if (nxge_10g_link_led_off(nxgep) != NXGE_OK)
2595 				goto fail;
2596 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2597 					"Link down cable problem"));
2598 			nxgep->statsp->mac_stats.link_up = 0;
2599 			nxgep->statsp->mac_stats.link_speed = 0;
2600 			nxgep->statsp->mac_stats.link_duplex = 0;
2601 
2602 			nxge_link_is_down(nxgep);
2603 			nxgep->link_notify = B_FALSE;
2604 		}
2605 	}
2606 
2607 	(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
2608 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_check_10g_link port<%d>",
2609 				portn));
2610 	return (NXGE_OK);
2611 
2612 fail:
2613 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2614 			"nxge_check_10g_link: Failed to check link port<%d>",
2615 			portn));
2616 	return (status);
2617 }
2618 
2619 
2620 /* Declare link down */
2621 
2622 void
2623 nxge_link_is_down(p_nxge_t nxgep)
2624 {
2625 	p_nxge_stats_t statsp;
2626 	char link_stat_msg[64];
2627 
2628 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_down"));
2629 
2630 	statsp = nxgep->statsp;
2631 	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link down",
2632 			statsp->mac_stats.xcvr_portn);
2633 
2634 	mac_link_update(nxgep->mach, LINK_STATE_DOWN);
2635 
2636 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_down"));
2637 }
2638 
2639 /* Declare link up */
2640 
2641 void
2642 nxge_link_is_up(p_nxge_t nxgep)
2643 {
2644 	p_nxge_stats_t statsp;
2645 	char link_stat_msg[64];
2646 	uint32_t val;
2647 
2648 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "==> nxge_link_is_up"));
2649 
2650 	statsp = nxgep->statsp;
2651 	(void) sprintf(link_stat_msg, "xcvr addr:0x%02x - link up %d Mbps ",
2652 				statsp->mac_stats.xcvr_portn,
2653 				statsp->mac_stats.link_speed);
2654 
2655 	if (statsp->mac_stats.link_T4)
2656 		(void) strcat(link_stat_msg, "T4");
2657 	else if (statsp->mac_stats.link_duplex == 2)
2658 		(void) strcat(link_stat_msg, "full duplex");
2659 	else
2660 		(void) strcat(link_stat_msg, "half duplex");
2661 
2662 	(void) nxge_xif_init(nxgep);
2663 
2664 	/* Clean up symbol errors incurred during link transition */
2665 	if (nxgep->mac.portmode == PORT_10G_FIBER) {
2666 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
2667 					XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
2668 		(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
2669 					XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
2670 	}
2671 
2672 	mac_link_update(nxgep->mach, LINK_STATE_UP);
2673 
2674 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_link_is_up"));
2675 }
2676 
2677 /*
2678  * Calculate the bit in the multicast address filter
2679  * that selects the given * address.
2680  * Note: For GEM, the last 8-bits are used.
2681  */
2682 uint32_t
2683 crc32_mchash(p_ether_addr_t addr)
2684 {
2685 	uint8_t *cp;
2686 	uint32_t crc;
2687 	uint32_t c;
2688 	int byte;
2689 	int bit;
2690 
2691 	cp = (uint8_t *)addr;
2692 	crc = (uint32_t)0xffffffff;
2693 	for (byte = 0; byte < 6; byte++) {
2694 		c = (uint32_t)cp[byte];
2695 		for (bit = 0; bit < 8; bit++) {
2696 			if ((c & 0x1) ^ (crc & 0x1))
2697 				crc = (crc >> 1)^0xedb88320;
2698 			else
2699 				crc = (crc >> 1);
2700 			c >>= 1;
2701 		}
2702 	}
2703 	return ((~crc) >> (32 - HASH_BITS));
2704 }
2705 
2706 /* Reset serdes */
2707 
2708 nxge_status_t
2709 nxge_serdes_reset(p_nxge_t nxgep)
2710 {
2711 	npi_handle_t		handle;
2712 
2713 	handle = nxgep->npi_handle;
2714 
2715 	ESR_REG_WR(handle, ESR_RESET_REG, ESR_RESET_0 | ESR_RESET_1);
2716 	drv_usecwait(500);
2717 	ESR_REG_WR(handle, ESR_CONFIG_REG, 0);
2718 
2719 	return (NXGE_OK);
2720 }
2721 
2722 /* Monitor link status using interrupt or polling */
2723 
2724 nxge_status_t
2725 nxge_link_monitor(p_nxge_t nxgep, link_mon_enable_t enable)
2726 {
2727 	nxge_status_t status = NXGE_OK;
2728 
2729 	/*
2730 	 * Make sure that we don't check the link if this happen to
2731 	 * be not port0 or 1 and it is not BMAC port.
2732 	 */
2733 	if ((nxgep->mac.portmode == PORT_10G_FIBER) && (nxgep->mac.portnum > 1))
2734 		return (NXGE_OK);
2735 
2736 	if (nxgep->statsp == NULL) {
2737 		/* stats has not been allocated. */
2738 		return (NXGE_OK);
2739 	}
2740 	/* Don't check link if we're not in internal loopback mode */
2741 	if (nxgep->statsp->port_stats.lb_mode != nxge_lb_normal)
2742 		return (NXGE_OK);
2743 
2744 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2745 			"==> nxge_link_monitor port<%d> enable=%d",
2746 			nxgep->mac.portnum, enable));
2747 	if (enable == LINK_MONITOR_START) {
2748 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
2749 			if ((status = nxge_link_intr(nxgep, LINK_INTR_START))
2750 							!= NXGE_OK)
2751 				goto fail;
2752 		} else {
2753 			switch (nxgep->mac.portmode) {
2754 			case PORT_10G_FIBER:
2755 				nxgep->nxge_link_poll_timerid = timeout(
2756 						(fptrv_t)nxge_check_10g_link,
2757 						nxgep,
2758 						drv_usectohz(1000 * 1000));
2759 			break;
2760 
2761 			case PORT_1G_COPPER:
2762 			case PORT_1G_FIBER:
2763 				nxgep->nxge_link_poll_timerid = timeout(
2764 						(fptrv_t)nxge_check_mii_link,
2765 						nxgep,
2766 						drv_usectohz(1000 * 1000));
2767 			break;
2768 			default:
2769 				;
2770 			}
2771 		}
2772 	} else {
2773 		if (nxgep->mac.linkchkmode == LINKCHK_INTR) {
2774 			if ((status = nxge_link_intr(nxgep, LINK_INTR_STOP))
2775 							!= NXGE_OK)
2776 				goto fail;
2777 		} else {
2778 			if (nxgep->nxge_link_poll_timerid != 0) {
2779 				(void) untimeout(nxgep->nxge_link_poll_timerid);
2780 				nxgep->nxge_link_poll_timerid = 0;
2781 			}
2782 		}
2783 	}
2784 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2785 			"<== nxge_link_monitor port<%d> enable=%d",
2786 			nxgep->mac.portnum, enable));
2787 	return (NXGE_OK);
2788 fail:
2789 	return (status);
2790 }
2791 
2792 /* Set promiscous mode */
2793 
2794 nxge_status_t
2795 nxge_set_promisc(p_nxge_t nxgep, boolean_t on)
2796 {
2797 	nxge_status_t status = NXGE_OK;
2798 
2799 	NXGE_DEBUG_MSG((nxgep, MAC_CTL,
2800 		"==> nxge_set_promisc: on %d", on));
2801 
2802 	nxgep->filter.all_phys_cnt = ((on) ? 1 : 0);
2803 
2804 	RW_ENTER_WRITER(&nxgep->filter_lock);
2805 
2806 	if ((status = nxge_rx_mac_disable(nxgep)) != NXGE_OK) {
2807 		goto fail;
2808 	}
2809 	if ((status = nxge_rx_mac_enable(nxgep)) != NXGE_OK) {
2810 		goto fail;
2811 	}
2812 
2813 	RW_EXIT(&nxgep->filter_lock);
2814 
2815 	if (on)
2816 		nxgep->statsp->mac_stats.promisc = B_TRUE;
2817 	else
2818 		nxgep->statsp->mac_stats.promisc = B_FALSE;
2819 
2820 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_set_promisc"));
2821 
2822 	return (NXGE_OK);
2823 fail:
2824 	RW_EXIT(&nxgep->filter_lock);
2825 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_set_promisc: "
2826 			"Unable to set promisc (%d)", on));
2827 
2828 	return (status);
2829 }
2830 
2831 /*ARGSUSED*/
2832 uint_t
2833 nxge_mif_intr(void *arg1, void *arg2)
2834 {
2835 #ifdef	NXGE_DEBUG
2836 	p_nxge_t		nxgep = (p_nxge_t)arg2;
2837 #endif
2838 #if NXGE_MIF
2839 	p_nxge_ldv_t		ldvp = (p_nxge_ldv_t)arg1;
2840 	uint32_t		status;
2841 	npi_handle_t		handle;
2842 	uint8_t			portn;
2843 	p_nxge_stats_t		statsp;
2844 #endif
2845 
2846 #ifdef	NXGE_MIF
2847 	if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
2848 		nxgep = ldvp->nxgep;
2849 	}
2850 	nxgep = ldvp->nxgep;
2851 #endif
2852 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mif_intr"));
2853 
2854 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
2855 	return (DDI_INTR_CLAIMED);
2856 
2857 mif_intr_fail:
2858 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mif_intr"));
2859 	return (DDI_INTR_UNCLAIMED);
2860 }
2861 
2862 /*ARGSUSED*/
2863 uint_t
2864 nxge_mac_intr(void *arg1, void *arg2)
2865 {
2866 	p_nxge_t		nxgep = (p_nxge_t)arg2;
2867 	p_nxge_ldv_t		ldvp = (p_nxge_ldv_t)arg1;
2868 	p_nxge_ldg_t		ldgp;
2869 	uint32_t		status;
2870 	npi_handle_t		handle;
2871 	uint8_t			portn;
2872 	p_nxge_stats_t		statsp;
2873 	npi_status_t		rs = NPI_SUCCESS;
2874 
2875 	if (arg2 == NULL || (void *)ldvp->nxgep != arg2) {
2876 		nxgep = ldvp->nxgep;
2877 	}
2878 
2879 	ldgp = ldvp->ldgp;
2880 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_mac_intr: "
2881 		"group %d", ldgp->ldg));
2882 
2883 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
2884 	/*
2885 	 * This interrupt handler is for a specific
2886 	 * mac port.
2887 	 */
2888 	statsp = (p_nxge_stats_t)nxgep->statsp;
2889 	portn = nxgep->mac.portnum;
2890 
2891 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
2892 		"==> nxge_mac_intr: reading mac stats: port<%d>", portn));
2893 
2894 	if (nxgep->mac.porttype == PORT_TYPE_XMAC) {
2895 		rs = npi_xmac_tx_get_istatus(handle, portn,
2896 					(xmac_tx_iconfig_t *)&status);
2897 		if (rs != NPI_SUCCESS)
2898 			goto npi_fail;
2899 		if (status & ICFG_XMAC_TX_ALL) {
2900 			if (status & ICFG_XMAC_TX_UNDERRUN) {
2901 				statsp->xmac_stats.tx_underflow_err++;
2902 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
2903 					NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
2904 			}
2905 			if (status & ICFG_XMAC_TX_MAX_PACKET_ERR) {
2906 				statsp->xmac_stats.tx_maxpktsize_err++;
2907 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
2908 					NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR);
2909 			}
2910 			if (status & ICFG_XMAC_TX_OVERFLOW) {
2911 				statsp->xmac_stats.tx_overflow_err++;
2912 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
2913 					NXGE_FM_EREPORT_TXMAC_OVERFLOW);
2914 			}
2915 			if (status & ICFG_XMAC_TX_FIFO_XFR_ERR) {
2916 				statsp->xmac_stats.tx_fifo_xfr_err++;
2917 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
2918 					NXGE_FM_EREPORT_TXMAC_TXFIFO_XFR_ERR);
2919 			}
2920 			if (status & ICFG_XMAC_TX_BYTE_CNT_EXP) {
2921 				statsp->xmac_stats.tx_byte_cnt +=
2922 							XTXMAC_BYTE_CNT_MASK;
2923 			}
2924 			if (status & ICFG_XMAC_TX_FRAME_CNT_EXP) {
2925 				statsp->xmac_stats.tx_frame_cnt +=
2926 							XTXMAC_FRM_CNT_MASK;
2927 			}
2928 		}
2929 
2930 		rs = npi_xmac_rx_get_istatus(handle, portn,
2931 					(xmac_rx_iconfig_t *)&status);
2932 		if (rs != NPI_SUCCESS)
2933 			goto npi_fail;
2934 		if (status & ICFG_XMAC_RX_ALL) {
2935 			if (status & ICFG_XMAC_RX_OVERFLOW)
2936 				statsp->xmac_stats.rx_overflow_err++;
2937 			if (status & ICFG_XMAC_RX_UNDERFLOW) {
2938 				statsp->xmac_stats.rx_underflow_err++;
2939 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
2940 					NXGE_FM_EREPORT_RXMAC_UNDERFLOW);
2941 			}
2942 			if (status & ICFG_XMAC_RX_CRC_ERR_CNT_EXP) {
2943 				statsp->xmac_stats.rx_crc_err_cnt +=
2944 							XRXMAC_CRC_ER_CNT_MASK;
2945 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
2946 					NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP);
2947 			}
2948 			if (status & ICFG_XMAC_RX_LEN_ERR_CNT_EXP) {
2949 				statsp->xmac_stats.rx_len_err_cnt +=
2950 							MAC_LEN_ER_CNT_MASK;
2951 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
2952 				NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP);
2953 			}
2954 			if (status & ICFG_XMAC_RX_VIOL_ERR_CNT_EXP) {
2955 				statsp->xmac_stats.rx_viol_err_cnt +=
2956 							XRXMAC_CD_VIO_CNT_MASK;
2957 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
2958 					NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP);
2959 			}
2960 			if (status & ICFG_XMAC_RX_OCT_CNT_EXP) {
2961 				statsp->xmac_stats.rx_byte_cnt +=
2962 							XRXMAC_BT_CNT_MASK;
2963 			}
2964 			if (status & ICFG_XMAC_RX_HST_CNT1_EXP) {
2965 				statsp->xmac_stats.rx_hist1_cnt +=
2966 							XRXMAC_HIST_CNT1_MASK;
2967 			}
2968 			if (status & ICFG_XMAC_RX_HST_CNT2_EXP) {
2969 				statsp->xmac_stats.rx_hist2_cnt +=
2970 							XRXMAC_HIST_CNT2_MASK;
2971 			}
2972 			if (status & ICFG_XMAC_RX_HST_CNT3_EXP) {
2973 				statsp->xmac_stats.rx_hist3_cnt +=
2974 							XRXMAC_HIST_CNT3_MASK;
2975 			}
2976 			if (status & ICFG_XMAC_RX_HST_CNT4_EXP) {
2977 				statsp->xmac_stats.rx_hist4_cnt +=
2978 							XRXMAC_HIST_CNT4_MASK;
2979 			}
2980 			if (status & ICFG_XMAC_RX_HST_CNT5_EXP) {
2981 				statsp->xmac_stats.rx_hist5_cnt +=
2982 							XRXMAC_HIST_CNT5_MASK;
2983 			}
2984 			if (status & ICFG_XMAC_RX_HST_CNT6_EXP) {
2985 				statsp->xmac_stats.rx_hist6_cnt +=
2986 							XRXMAC_HIST_CNT6_MASK;
2987 			}
2988 			if (status & ICFG_XMAC_RX_BCAST_CNT_EXP) {
2989 				statsp->xmac_stats.rx_broadcast_cnt +=
2990 							XRXMAC_BC_FRM_CNT_MASK;
2991 			}
2992 			if (status & ICFG_XMAC_RX_MCAST_CNT_EXP) {
2993 				statsp->xmac_stats.rx_mult_cnt +=
2994 							XRXMAC_MC_FRM_CNT_MASK;
2995 			}
2996 			if (status & ICFG_XMAC_RX_FRAG_CNT_EXP) {
2997 				statsp->xmac_stats.rx_frag_cnt +=
2998 							XRXMAC_FRAG_CNT_MASK;
2999 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
3000 					NXGE_FM_EREPORT_RXMAC_RXFRAG_CNT_EXP);
3001 			}
3002 			if (status & ICFG_XMAC_RX_ALIGNERR_CNT_EXP) {
3003 				statsp->xmac_stats.rx_frame_align_err_cnt +=
3004 							XRXMAC_AL_ER_CNT_MASK;
3005 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
3006 					NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP);
3007 			}
3008 			if (status & ICFG_XMAC_RX_LINK_FLT_CNT_EXP) {
3009 				statsp->xmac_stats.rx_linkfault_err_cnt +=
3010 							XMAC_LINK_FLT_CNT_MASK;
3011 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
3012 				NXGE_FM_EREPORT_RXMAC_LINKFAULT_CNT_EXP);
3013 			}
3014 			if (status & ICFG_XMAC_RX_REMOTE_FLT_DET) {
3015 				statsp->xmac_stats.rx_remotefault_err++;
3016 			}
3017 			if (status & ICFG_XMAC_RX_LOCAL_FLT_DET) {
3018 				statsp->xmac_stats.rx_localfault_err++;
3019 			}
3020 		}
3021 
3022 		rs = npi_xmac_ctl_get_istatus(handle, portn,
3023 						(xmac_ctl_iconfig_t *)&status);
3024 		if (rs != NPI_SUCCESS)
3025 			goto npi_fail;
3026 		if (status & ICFG_XMAC_CTRL_ALL) {
3027 			if (status & ICFG_XMAC_CTRL_PAUSE_RCVD)
3028 				statsp->xmac_stats.rx_pause_cnt++;
3029 			if (status & ICFG_XMAC_CTRL_PAUSE_STATE)
3030 				statsp->xmac_stats.tx_pause_state++;
3031 			if (status & ICFG_XMAC_CTRL_NOPAUSE_STATE)
3032 				statsp->xmac_stats.tx_nopause_state++;
3033 		}
3034 	} else if (nxgep->mac.porttype == PORT_TYPE_BMAC) {
3035 		rs = npi_bmac_tx_get_istatus(handle, portn,
3036 						(bmac_tx_iconfig_t *)&status);
3037 		if (rs != NPI_SUCCESS)
3038 			goto npi_fail;
3039 		if (status & ICFG_BMAC_TX_ALL) {
3040 			if (status & ICFG_BMAC_TX_UNDERFLOW) {
3041 				statsp->bmac_stats.tx_underrun_err++;
3042 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
3043 					NXGE_FM_EREPORT_TXMAC_UNDERFLOW);
3044 			}
3045 			if (status & ICFG_BMAC_TX_MAXPKTSZ_ERR) {
3046 				statsp->bmac_stats.tx_max_pkt_err++;
3047 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
3048 					NXGE_FM_EREPORT_TXMAC_MAX_PKT_ERR);
3049 			}
3050 			if (status & ICFG_BMAC_TX_BYTE_CNT_EXP) {
3051 				statsp->bmac_stats.tx_byte_cnt +=
3052 							BTXMAC_BYTE_CNT_MASK;
3053 			}
3054 			if (status & ICFG_BMAC_TX_FRAME_CNT_EXP) {
3055 				statsp->bmac_stats.tx_frame_cnt +=
3056 							BTXMAC_FRM_CNT_MASK;
3057 			}
3058 		}
3059 
3060 		rs = npi_bmac_rx_get_istatus(handle, portn,
3061 						(bmac_rx_iconfig_t *)&status);
3062 		if (rs != NPI_SUCCESS)
3063 			goto npi_fail;
3064 		if (status & ICFG_BMAC_RX_ALL) {
3065 			if (status & ICFG_BMAC_RX_OVERFLOW) {
3066 				statsp->bmac_stats.rx_overflow_err++;
3067 			}
3068 			if (status & ICFG_BMAC_RX_FRAME_CNT_EXP) {
3069 				statsp->bmac_stats.rx_frame_cnt +=
3070 							RXMAC_FRM_CNT_MASK;
3071 			}
3072 			if (status & ICFG_BMAC_RX_CRC_ERR_CNT_EXP) {
3073 				statsp->bmac_stats.rx_crc_err_cnt +=
3074 							BMAC_CRC_ER_CNT_MASK;
3075 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
3076 					NXGE_FM_EREPORT_RXMAC_CRC_ERRCNT_EXP);
3077 			}
3078 			if (status & ICFG_BMAC_RX_LEN_ERR_CNT_EXP) {
3079 				statsp->bmac_stats.rx_len_err_cnt +=
3080 							MAC_LEN_ER_CNT_MASK;
3081 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
3082 				NXGE_FM_EREPORT_RXMAC_LENGTH_ERRCNT_EXP);
3083 			}
3084 			if (status & ICFG_BMAC_RX_VIOL_ERR_CNT_EXP)
3085 				statsp->bmac_stats.rx_viol_err_cnt +=
3086 							BMAC_CD_VIO_CNT_MASK;
3087 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
3088 					NXGE_FM_EREPORT_RXMAC_VIOL_ERRCNT_EXP);
3089 			}
3090 			if (status & ICFG_BMAC_RX_BYTE_CNT_EXP) {
3091 				statsp->bmac_stats.rx_byte_cnt +=
3092 							BRXMAC_BYTE_CNT_MASK;
3093 			}
3094 			if (status & ICFG_BMAC_RX_ALIGNERR_CNT_EXP) {
3095 				statsp->bmac_stats.rx_align_err_cnt +=
3096 							BMAC_AL_ER_CNT_MASK;
3097 				NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
3098 					NXGE_FM_EREPORT_RXMAC_ALIGN_ECNT_EXP);
3099 			}
3100 
3101 			rs = npi_bmac_ctl_get_istatus(handle, portn,
3102 						(bmac_ctl_iconfig_t *)&status);
3103 			if (rs != NPI_SUCCESS)
3104 				goto npi_fail;
3105 
3106 			if (status & ICFG_BMAC_CTL_ALL) {
3107 				if (status & ICFG_BMAC_CTL_RCVPAUSE)
3108 					statsp->bmac_stats.rx_pause_cnt++;
3109 				if (status & ICFG_BMAC_CTL_INPAUSE_ST)
3110 					statsp->bmac_stats.tx_pause_state++;
3111 				if (status & ICFG_BMAC_CTL_INNOTPAUSE_ST)
3112 					statsp->bmac_stats.tx_nopause_state++;
3113 			}
3114 		}
3115 
3116 	if (ldgp->nldvs == 1) {
3117 		(void) npi_intr_ldg_mgmt_set(handle, ldgp->ldg,
3118 			B_TRUE, ldgp->ldg_timer);
3119 	}
3120 
3121 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
3122 	return (DDI_INTR_CLAIMED);
3123 
3124 npi_fail:
3125 	NXGE_ERROR_MSG((nxgep, INT_CTL, "<== nxge_mac_intr"));
3126 	return (DDI_INTR_UNCLAIMED);
3127 }
3128 
3129 nxge_status_t
3130 nxge_check_bcm8704_link(p_nxge_t nxgep, boolean_t *link_up)
3131 {
3132 	uint8_t		phy_port_addr;
3133 	nxge_status_t	status = NXGE_OK;
3134 	boolean_t	rx_sig_ok;
3135 	boolean_t	pcs_blk_lock;
3136 	boolean_t	link_align;
3137 	uint16_t	val1, val2, val3;
3138 #ifdef	NXGE_DEBUG_SYMBOL_ERR
3139 	uint16_t	val_debug;
3140 	uint16_t	val;
3141 #endif
3142 
3143 	phy_port_addr = nxgep->statsp->mac_stats.xcvr_portn;
3144 
3145 #ifdef	NXGE_DEBUG_SYMBOL_ERR
3146 	/* Check Device 3 Register Device 3 0xC809 */
3147 	(void) nxge_mdio_read(nxgep, phy_port_addr, 0x3, 0xC809, &val_debug);
3148 	if ((val_debug & ~0x200) != 0) {
3149 		cmn_err(CE_NOTE, "!Port%d BCM8704 Dev3 Reg 0xc809 = 0x%x\n",
3150 				nxgep->mac.portnum, val_debug);
3151 		(void) nxge_mdio_read(nxgep, phy_port_addr, 0x4, 0x18,
3152 				&val_debug);
3153 		cmn_err(CE_NOTE, "!Port%d BCM8704 Dev4 Reg 0x18 = 0x%x\n",
3154 				nxgep->mac.portnum, val_debug);
3155 	}
3156 
3157 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
3158 					XPCS_REG_DESCWERR_COUNTER, &val);
3159 	if (val != 0)
3160 		cmn_err(CE_NOTE, "!XPCS DESCWERR = 0x%x\n", val);
3161 
3162 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
3163 					XPCS_REG_SYMBOL_ERR_L0_1_COUNTER, &val);
3164 	if (val != 0)
3165 		cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L0_1 = 0x%x\n", val);
3166 
3167 	(void) npi_xmac_xpcs_read(nxgep->npi_handle, nxgep->mac.portnum,
3168 					XPCS_REG_SYMBOL_ERR_L2_3_COUNTER, &val);
3169 	if (val != 0)
3170 		cmn_err(CE_NOTE, "!XPCS SYMBOL_ERR_L2_3 = 0x%x\n", val);
3171 #endif
3172 
3173 	/* Check from BCM8704 if 10G link is up or down */
3174 
3175 	/* Check Device 1 Register 0xA bit0 */
3176 	status = nxge_mdio_read(nxgep, phy_port_addr,
3177 			BCM8704_PMA_PMD_DEV_ADDR,
3178 			BCM8704_PMD_RECEIVE_SIG_DETECT,
3179 			&val1);
3180 	if (status != NXGE_OK)
3181 		goto fail;
3182 	rx_sig_ok = ((val1 & GLOB_PMD_RX_SIG_OK) ? B_TRUE : B_FALSE);
3183 
3184 	/* Check Device 3 Register 0x20 bit0 */
3185 	if ((status = nxge_mdio_read(nxgep, phy_port_addr,
3186 			BCM8704_PCS_DEV_ADDR,
3187 			BCM8704_10GBASE_R_PCS_STATUS_REG,
3188 			&val2)) != NPI_SUCCESS)
3189 		goto fail;
3190 	pcs_blk_lock = ((val2 & PCS_10GBASE_R_PCS_BLK_LOCK) ? B_TRUE : B_FALSE);
3191 
3192 	/* Check Device 4 Register 0x18 bit12 */
3193 	status = nxge_mdio_read(nxgep, phy_port_addr,
3194 			BCM8704_PHYXS_ADDR,
3195 			BCM8704_PHYXS_XGXS_LANE_STATUS_REG,
3196 			&val3);
3197 	if (status != NXGE_OK)
3198 		goto fail;
3199 	link_align = (val3 == (XGXS_LANE_ALIGN_STATUS | XGXS_LANE3_SYNC |
3200 				XGXS_LANE2_SYNC | XGXS_LANE1_SYNC |
3201 				XGXS_LANE0_SYNC | 0x400)) ? B_TRUE : B_FALSE;
3202 
3203 #ifdef	NXGE_DEBUG_ALIGN_ERR
3204 	/* Temp workaround for link down issue */
3205 	if (pcs_blk_lock == B_FALSE) {
3206 		if (val2 != 0x4) {
3207 			pcs_blk_lock = B_TRUE;
3208 			cmn_err(CE_NOTE,
3209 				"!LINK DEBUG: port%d PHY Dev3 "
3210 				"Reg 0x20 = 0x%x\n",
3211 				nxgep->mac.portnum, val2);
3212 		}
3213 	}
3214 
3215 	if (link_align == B_FALSE) {
3216 		if (val3 != 0x140f) {
3217 			link_align = B_TRUE;
3218 			cmn_err(CE_NOTE,
3219 				"!LINK DEBUG: port%d PHY Dev4 "
3220 				"Reg 0x18 = 0x%x\n",
3221 				nxgep->mac.portnum, val3);
3222 		}
3223 	}
3224 
3225 	if (rx_sig_ok == B_FALSE) {
3226 		if ((val2 == 0) || (val3 == 0)) {
3227 			rx_sig_ok = B_TRUE;
3228 			cmn_err(CE_NOTE,
3229 				"!LINK DEBUG: port %d Dev3 or Dev4 read zero\n",
3230 				nxgep->mac.portnum);
3231 		}
3232 	}
3233 #endif
3234 
3235 	*link_up = ((rx_sig_ok == B_TRUE) && (pcs_blk_lock == B_TRUE) &&
3236 			(link_align == B_TRUE)) ? B_TRUE : B_FALSE;
3237 
3238 	return (NXGE_OK);
3239 fail:
3240 	return (status);
3241 }
3242 
3243 
3244 nxge_status_t
3245 nxge_get_xcvr_type(p_nxge_t nxgep)
3246 {
3247 	nxge_status_t status = NXGE_OK;
3248 
3249 #if defined(_BIG_ENDIAN)
3250 	char *prop_val;
3251 
3252 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0,
3253 		"phy-type", &prop_val) == DDI_PROP_SUCCESS) {
3254 		if (strcmp("xgf", prop_val) == 0) {
3255 			nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3256 			nxgep->mac.portmode = PORT_10G_FIBER;
3257 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Fiber Xcvr"));
3258 		} else if (strcmp("mif", prop_val)	== 0) {
3259 			nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
3260 			nxgep->mac.portmode = PORT_1G_COPPER;
3261 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Copper Xcvr"));
3262 		} else if (strcmp("pcs", prop_val) == 0) {
3263 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
3264 			nxgep->mac.portmode = PORT_1G_FIBER;
3265 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "1G Fiber Xcvr"));
3266 		} else if (strcmp("xgc", prop_val) == 0) {
3267 			nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3268 			nxgep->mac.portmode = PORT_10G_COPPER;
3269 			NXGE_DEBUG_MSG((nxgep, MAC_CTL, "10G Copper Xcvr"));
3270 		} else {
3271 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3272 					    "Unknown phy-type: %s",
3273 					    prop_val));
3274 			ddi_prop_free(prop_val);
3275 			return (NXGE_ERROR);
3276 		}
3277 		status = NXGE_OK;
3278 		(void) ddi_prop_update_string(DDI_DEV_T_NONE, nxgep->dip,
3279 						    "phy-type", prop_val);
3280 		ddi_prop_free(prop_val);
3281 	} else {
3282 		/*
3283 		 * This should really be an error. But for now default
3284 		 * this to 10G fiber.
3285 		 */
3286 		if (nxgep->niu_type == N2_NIU) {
3287 			nxgep->statsp->mac_stats.xcvr_inuse = XPCS_XCVR;
3288 			nxgep->mac.portmode = PORT_10G_FIBER;
3289 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3290 					    "Cannot find phy-type: "
3291 					    " Default to 10G Fiber Xcvr"));
3292 			status = NXGE_OK;
3293 		} else {
3294 			NXGE_DEBUG_MSG((nxgep, MAC_CTL,
3295 					    "Cannot get phy-type"));
3296 			return (NXGE_ERROR);
3297 		}
3298 	}
3299 #else
3300 	status = nxge_espc_phy_type_get(nxgep);
3301 #endif
3302 
3303 	NXGE_DEBUG_MSG((nxgep, MAC_CTL, "<== nxge_get_xcvr_type"));
3304 	return (status);
3305 }
3306 
3307 nxge_status_t
3308 nxge_10g_link_led_on(p_nxge_t nxgep)
3309 {
3310 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_TRUE)
3311 							!= NPI_SUCCESS)
3312 		return (NXGE_ERROR);
3313 	else
3314 		return (NXGE_OK);
3315 }
3316 
3317 nxge_status_t
3318 nxge_10g_link_led_off(p_nxge_t nxgep)
3319 {
3320 	if (npi_xmac_xif_led(nxgep->npi_handle, nxgep->mac.portnum, B_FALSE)
3321 							!= NPI_SUCCESS)
3322 		return (NXGE_ERROR);
3323 	else
3324 		return (NXGE_OK);
3325 }
3326