xref: /onnv-gate/usr/src/uts/common/io/nxge/nxge_zcp.c (revision 6929:a596171cbf16)
13859Sml29623 /*
23859Sml29623  * CDDL HEADER START
33859Sml29623  *
43859Sml29623  * The contents of this file are subject to the terms of the
53859Sml29623  * Common Development and Distribution License (the "License").
63859Sml29623  * You may not use this file except in compliance with the License.
73859Sml29623  *
83859Sml29623  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93859Sml29623  * or http://www.opensolaris.org/os/licensing.
103859Sml29623  * See the License for the specific language governing permissions
113859Sml29623  * and limitations under the License.
123859Sml29623  *
133859Sml29623  * When distributing Covered Code, include this CDDL HEADER in each
143859Sml29623  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153859Sml29623  * If applicable, add the following below this CDDL HEADER, with the
163859Sml29623  * fields enclosed by brackets "[]" replaced with your own identifying
173859Sml29623  * information: Portions Copyright [yyyy] [name of copyright owner]
183859Sml29623  *
193859Sml29623  * CDDL HEADER END
203859Sml29623  */
213859Sml29623 /*
22*6929Smisaki  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
233859Sml29623  * Use is subject to license terms.
243859Sml29623  */
253859Sml29623 
263859Sml29623 #pragma ident	"%Z%%M%	%I%	%E% SMI"
273859Sml29623 
283859Sml29623 #include <nxge_impl.h>
293859Sml29623 #include <nxge_zcp.h>
303859Sml29623 #include <nxge_ipp.h>
313859Sml29623 
323859Sml29623 nxge_status_t
nxge_zcp_init(p_nxge_t nxgep)333859Sml29623 nxge_zcp_init(p_nxge_t nxgep)
343859Sml29623 {
353859Sml29623 	uint8_t portn;
363859Sml29623 	npi_handle_t handle;
373859Sml29623 	zcp_iconfig_t istatus;
383859Sml29623 	npi_status_t rs = NPI_SUCCESS;
393859Sml29623 	int i;
403859Sml29623 	zcp_ram_unit_t w_data;
413859Sml29623 	zcp_ram_unit_t r_data;
423859Sml29623 	uint32_t cfifo_depth;
433859Sml29623 
443859Sml29623 	handle = nxgep->npi_handle;
453859Sml29623 	portn = NXGE_GET_PORT_NUM(nxgep->function_num);
463859Sml29623 
474732Sdavemq 	if (nxgep->niu_type == N2_NIU) {
484732Sdavemq 		cfifo_depth = ZCP_NIU_CFIFO_DEPTH;
494977Sraghus 	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
503859Sml29623 		if (portn < 2)
513859Sml29623 			cfifo_depth = ZCP_P0_P1_CFIFO_DEPTH;
523859Sml29623 		else
533859Sml29623 			cfifo_depth = ZCP_P2_P3_CFIFO_DEPTH;
544732Sdavemq 	} else {
554732Sdavemq 		goto fail;
564732Sdavemq 	}
573859Sml29623 
583859Sml29623 	/* Clean up CFIFO */
593859Sml29623 	w_data.w0 = 0;
603859Sml29623 	w_data.w1 = 0;
613859Sml29623 	w_data.w2 = 0;
623859Sml29623 	w_data.w3 = 0;
633859Sml29623 	w_data.w4 = 0;
643859Sml29623 
653859Sml29623 	for (i = 0; i < cfifo_depth; i++) {
663859Sml29623 		if (npi_zcp_tt_cfifo_entry(handle, OP_SET,
67*6929Smisaki 		    portn, i, &w_data) != NPI_SUCCESS)
683859Sml29623 			goto fail;
693859Sml29623 		if (npi_zcp_tt_cfifo_entry(handle, OP_GET,
70*6929Smisaki 		    portn, i, &r_data) != NPI_SUCCESS)
713859Sml29623 			goto fail;
723859Sml29623 	}
733859Sml29623 
743859Sml29623 	if (npi_zcp_rest_cfifo_port(handle, portn) != NPI_SUCCESS)
753859Sml29623 		goto fail;
763859Sml29623 
773859Sml29623 	/*
783859Sml29623 	 * Making sure that error source is cleared if this is an injected
793859Sml29623 	 * error.
803859Sml29623 	 */
813859Sml29623 	switch (portn) {
823859Sml29623 	case 0:
833859Sml29623 		NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT0_REG, 0);
843859Sml29623 		break;
853859Sml29623 	case 1:
863859Sml29623 		NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT1_REG, 0);
873859Sml29623 		break;
883859Sml29623 	case 2:
893859Sml29623 		NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT2_REG, 0);
903859Sml29623 		break;
913859Sml29623 	case 3:
923859Sml29623 		NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT3_REG, 0);
933859Sml29623 		break;
943859Sml29623 	}
953859Sml29623 
963859Sml29623 	if ((rs = npi_zcp_clear_istatus(handle)) != NPI_SUCCESS)
973859Sml29623 		return (NXGE_ERROR | rs);
983859Sml29623 	if ((rs = npi_zcp_get_istatus(handle, &istatus)) != NPI_SUCCESS)
993859Sml29623 		return (NXGE_ERROR | rs);
1003859Sml29623 	if ((rs = npi_zcp_iconfig(handle, INIT, ICFG_ZCP_ALL)) != NPI_SUCCESS)
1013859Sml29623 		goto fail;
1023859Sml29623 
1033859Sml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_zcp_init: port%d", portn));
1043859Sml29623 	return (NXGE_OK);
1053859Sml29623 
1063859Sml29623 fail:
1073859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
108*6929Smisaki 	    "nxge_zcp_init: Fail to initialize ZCP Port #%d\n", portn));
1093859Sml29623 	return (NXGE_ERROR | rs);
1103859Sml29623 }
1113859Sml29623 
1123859Sml29623 nxge_status_t
nxge_zcp_handle_sys_errors(p_nxge_t nxgep)1133859Sml29623 nxge_zcp_handle_sys_errors(p_nxge_t nxgep)
1143859Sml29623 {
1153859Sml29623 	npi_handle_t handle;
1163859Sml29623 	npi_status_t rs = NPI_SUCCESS;
1173859Sml29623 	p_nxge_zcp_stats_t statsp;
1183859Sml29623 	uint8_t portn;
1193859Sml29623 	zcp_iconfig_t istatus;
1203859Sml29623 	boolean_t rxport_fatal = B_FALSE;
1213859Sml29623 	nxge_status_t status = NXGE_OK;
1223859Sml29623 
1233859Sml29623 	handle = nxgep->npi_handle;
1243859Sml29623 	statsp = (p_nxge_zcp_stats_t)&nxgep->statsp->zcp_stats;
1253859Sml29623 	portn = nxgep->mac.portnum;
1263859Sml29623 
1273859Sml29623 	if ((rs = npi_zcp_get_istatus(handle, &istatus)) != NPI_SUCCESS)
1283859Sml29623 		return (NXGE_ERROR | rs);
1293859Sml29623 
1303859Sml29623 	if (istatus & ICFG_ZCP_RRFIFO_UNDERRUN) {
1313859Sml29623 		statsp->rrfifo_underrun++;
1323859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
133*6929Smisaki 		    NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN);
1343859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
135*6929Smisaki 		    "nxge_zcp_err_evnts: rrfifo_underrun"));
1363859Sml29623 	}
1373859Sml29623 
1383859Sml29623 	if (istatus & ICFG_ZCP_RRFIFO_OVERRUN) {
1393859Sml29623 		statsp->rrfifo_overrun++;
1403859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
141*6929Smisaki 		    NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN);
1423859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
143*6929Smisaki 		    "nxge_zcp_err_evnts: buf_rrfifo_overrun"));
1443859Sml29623 	}
1453859Sml29623 
1463859Sml29623 	if (istatus & ICFG_ZCP_RSPFIFO_UNCORR_ERR) {
1473859Sml29623 		statsp->rspfifo_uncorr_err++;
1483859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
149*6929Smisaki 		    NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR);
1503859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
151*6929Smisaki 		    "nxge_zcp_err_evnts: rspfifo_uncorr_err"));
1523859Sml29623 	}
1533859Sml29623 
1543859Sml29623 	if (istatus & ICFG_ZCP_BUFFER_OVERFLOW) {
1553859Sml29623 		statsp->buffer_overflow++;
1563859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
157*6929Smisaki 		    NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW);
1583859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
159*6929Smisaki 		    "nxge_zcp_err_evnts: buffer_overflow"));
1603859Sml29623 		rxport_fatal = B_TRUE;
1613859Sml29623 	}
1623859Sml29623 
1633859Sml29623 	if (istatus & ICFG_ZCP_STAT_TBL_PERR) {
1643859Sml29623 		statsp->stat_tbl_perr++;
1653859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
166*6929Smisaki 		    NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR);
1673859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
168*6929Smisaki 		    "nxge_zcp_err_evnts: stat_tbl_perr"));
1693859Sml29623 	}
1703859Sml29623 
1713859Sml29623 	if (istatus & ICFG_ZCP_DYN_TBL_PERR) {
1723859Sml29623 		statsp->dyn_tbl_perr++;
1733859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
174*6929Smisaki 		    NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR);
1753859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
176*6929Smisaki 		    "nxge_zcp_err_evnts: dyn_tbl_perr"));
1773859Sml29623 	}
1783859Sml29623 
1793859Sml29623 	if (istatus & ICFG_ZCP_BUF_TBL_PERR) {
1803859Sml29623 		statsp->buf_tbl_perr++;
1813859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
182*6929Smisaki 		    NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR);
1833859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
184*6929Smisaki 		    "nxge_zcp_err_evnts: buf_tbl_perr"));
1853859Sml29623 	}
1863859Sml29623 
1873859Sml29623 	if (istatus & ICFG_ZCP_TT_PROGRAM_ERR) {
1883859Sml29623 		statsp->tt_program_err++;
1893859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
190*6929Smisaki 		    NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR);
1913859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
192*6929Smisaki 		    "nxge_zcp_err_evnts: tt_program_err"));
1933859Sml29623 	}
1943859Sml29623 
1953859Sml29623 	if (istatus & ICFG_ZCP_RSP_TT_INDEX_ERR) {
1963859Sml29623 		statsp->rsp_tt_index_err++;
1973859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
198*6929Smisaki 		    NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR);
1993859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
200*6929Smisaki 		    "nxge_zcp_err_evnts: rsp_tt_index_err"));
2013859Sml29623 	}
2023859Sml29623 
2033859Sml29623 	if (istatus & ICFG_ZCP_SLV_TT_INDEX_ERR) {
2043859Sml29623 		statsp->slv_tt_index_err++;
2053859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
206*6929Smisaki 		    NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR);
2073859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
208*6929Smisaki 		    "nxge_zcp_err_evnts: slv_tt_index_err"));
2093859Sml29623 	}
2103859Sml29623 
2113859Sml29623 	if (istatus & ICFG_ZCP_TT_INDEX_ERR) {
2123859Sml29623 		statsp->zcp_tt_index_err++;
2133859Sml29623 		NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
214*6929Smisaki 		    NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR);
2153859Sml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
216*6929Smisaki 		    "nxge_zcp_err_evnts: tt_index_err"));
2173859Sml29623 	}
2183859Sml29623 
2193859Sml29623 	if (((portn == 0) && (istatus & ICFG_ZCP_CFIFO_ECC0)) ||
220*6929Smisaki 	    ((portn == 1) && (istatus & ICFG_ZCP_CFIFO_ECC1)) ||
221*6929Smisaki 	    ((portn == 2) && (istatus & ICFG_ZCP_CFIFO_ECC2)) ||
222*6929Smisaki 	    ((portn == 3) && (istatus & ICFG_ZCP_CFIFO_ECC3))) {
2233859Sml29623 		boolean_t ue_ecc_valid;
2243859Sml29623 
2253859Sml29623 		if ((status = nxge_ipp_eccue_valid_check(nxgep,
226*6929Smisaki 		    &ue_ecc_valid)) != NXGE_OK)
2273859Sml29623 			return (status);
2283859Sml29623 
2293859Sml29623 		if (ue_ecc_valid) {
2303859Sml29623 			statsp->cfifo_ecc++;
2313859Sml29623 			NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
232*6929Smisaki 			    NXGE_FM_EREPORT_ZCP_CFIFO_ECC);
2333859Sml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
234*6929Smisaki 			    "nxge_zcp_err_evnts: port%d buf_cfifo_ecc",
235*6929Smisaki 			    portn));
2363859Sml29623 			rxport_fatal = B_TRUE;
2373859Sml29623 		}
2383859Sml29623 	}
2393859Sml29623 
2403859Sml29623 	/*
2413859Sml29623 	 * Making sure that error source is cleared if this is an injected
2423859Sml29623 	 * error.
2433859Sml29623 	 */
2443859Sml29623 	switch (portn) {
2453859Sml29623 	case 0:
2463859Sml29623 		NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT0_REG, 0);
2473859Sml29623 		break;
2483859Sml29623 	case 1:
2493859Sml29623 		NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT1_REG, 0);
2503859Sml29623 		break;
2513859Sml29623 	case 2:
2523859Sml29623 		NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT2_REG, 0);
2533859Sml29623 		break;
2543859Sml29623 	case 3:
2553859Sml29623 		NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT3_REG, 0);
2563859Sml29623 		break;
2573859Sml29623 	}
2583859Sml29623 
2593859Sml29623 	(void) npi_zcp_clear_istatus(handle);
2603859Sml29623 
2613859Sml29623 	if (rxport_fatal) {
2623859Sml29623 		NXGE_DEBUG_MSG((nxgep, IPP_CTL,
263*6929Smisaki 		    " nxge_zcp_handle_sys_errors:"
264*6929Smisaki 		    " fatal Error on  Port #%d\n", portn));
2653859Sml29623 		status = nxge_zcp_fatal_err_recover(nxgep);
2663859Sml29623 		if (status == NXGE_OK) {
2673859Sml29623 			FM_SERVICE_RESTORED(nxgep);
2683859Sml29623 		}
2693859Sml29623 	}
2703859Sml29623 	return (status);
2713859Sml29623 }
2723859Sml29623 
2733859Sml29623 void
nxge_zcp_inject_err(p_nxge_t nxgep,uint32_t err_id)2743859Sml29623 nxge_zcp_inject_err(p_nxge_t nxgep, uint32_t err_id)
2753859Sml29623 {
2763859Sml29623 	zcp_int_stat_reg_t zcps;
2773859Sml29623 	uint8_t portn = nxgep->mac.portnum;
2783859Sml29623 	zcp_ecc_ctrl_t ecc_ctrl;
2793859Sml29623 
2803859Sml29623 	switch (err_id) {
2813859Sml29623 	case NXGE_FM_EREPORT_ZCP_CFIFO_ECC:
2823859Sml29623 		ecc_ctrl.value = 0;
2833859Sml29623 		ecc_ctrl.bits.w0.cor_dbl = 1;
2843859Sml29623 		ecc_ctrl.bits.w0.cor_lst = 1;
2853859Sml29623 		ecc_ctrl.bits.w0.cor_all = 0;
2863859Sml29623 		switch (portn) {
2873859Sml29623 		case 0:
2883859Sml29623 			cmn_err(CE_NOTE,
289*6929Smisaki 			    "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n",
290*6929Smisaki 			    (unsigned long long) ecc_ctrl.value, portn);
2913859Sml29623 			NXGE_REG_WR64(nxgep->npi_handle,
292*6929Smisaki 			    ZCP_CFIFO_ECC_PORT0_REG,
293*6929Smisaki 			    ecc_ctrl.value);
2943859Sml29623 			break;
2953859Sml29623 		case 1:
2963859Sml29623 			cmn_err(CE_NOTE,
297*6929Smisaki 			    "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n",
298*6929Smisaki 			    (unsigned long long) ecc_ctrl.value, portn);
2993859Sml29623 			NXGE_REG_WR64(nxgep->npi_handle,
300*6929Smisaki 			    ZCP_CFIFO_ECC_PORT1_REG,
301*6929Smisaki 			    ecc_ctrl.value);
3023859Sml29623 			break;
3033859Sml29623 		case 2:
3043859Sml29623 			cmn_err(CE_NOTE,
305*6929Smisaki 			    "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n",
306*6929Smisaki 			    (unsigned long long) ecc_ctrl.value, portn);
3073859Sml29623 			NXGE_REG_WR64(nxgep->npi_handle,
308*6929Smisaki 			    ZCP_CFIFO_ECC_PORT2_REG,
309*6929Smisaki 			    ecc_ctrl.value);
3103859Sml29623 			break;
3113859Sml29623 		case 3:
3123859Sml29623 			cmn_err(CE_NOTE,
313*6929Smisaki 			    "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n",
314*6929Smisaki 			    (unsigned long long) ecc_ctrl.value, portn);
3153859Sml29623 			NXGE_REG_WR64(nxgep->npi_handle,
316*6929Smisaki 			    ZCP_CFIFO_ECC_PORT3_REG,
317*6929Smisaki 			    ecc_ctrl.value);
3183859Sml29623 			break;
3193859Sml29623 		}
3203859Sml29623 		break;
3213859Sml29623 
3223859Sml29623 	case NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN:
3233859Sml29623 	case NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR:
3243859Sml29623 	case NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR:
3253859Sml29623 	case NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR:
3263859Sml29623 	case NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR:
3273859Sml29623 	case NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN:
3283859Sml29623 	case NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW:
3293859Sml29623 	case NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR:
3303859Sml29623 	case NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR:
3313859Sml29623 	case NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR:
3323859Sml29623 	case NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR:
3333859Sml29623 		NXGE_REG_RD64(nxgep->npi_handle, ZCP_INT_STAT_TEST_REG,
334*6929Smisaki 		    &zcps.value);
3353859Sml29623 		if (err_id == NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN)
3363859Sml29623 			zcps.bits.ldw.rrfifo_urun = 1;
3373859Sml29623 		if (err_id == NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR)
3383859Sml29623 			zcps.bits.ldw.rspfifo_uc_err = 1;
3393859Sml29623 		if (err_id == NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR)
3403859Sml29623 			zcps.bits.ldw.stat_tbl_perr = 1;
3413859Sml29623 		if (err_id == NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR)
3423859Sml29623 			zcps.bits.ldw.dyn_tbl_perr = 1;
3433859Sml29623 		if (err_id == NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR)
3443859Sml29623 			zcps.bits.ldw.buf_tbl_perr = 1;
3453859Sml29623 		if (err_id == NXGE_FM_EREPORT_ZCP_CFIFO_ECC) {
3463859Sml29623 			switch (portn) {
3473859Sml29623 			case 0:
3483859Sml29623 				zcps.bits.ldw.cfifo_ecc0 = 1;
3493859Sml29623 				break;
3503859Sml29623 			case 1:
3513859Sml29623 				zcps.bits.ldw.cfifo_ecc1 = 1;
3523859Sml29623 				break;
3533859Sml29623 			case 2:
3543859Sml29623 				zcps.bits.ldw.cfifo_ecc2 = 1;
3553859Sml29623 				break;
3563859Sml29623 			case 3:
3573859Sml29623 				zcps.bits.ldw.cfifo_ecc3 = 1;
3583859Sml29623 				break;
3593859Sml29623 			}
3603859Sml29623 		}
3613859Sml29623 
3623859Sml29623 	default:
3633859Sml29623 		if (err_id == NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN)
3643859Sml29623 			zcps.bits.ldw.rrfifo_orun = 1;
3653859Sml29623 		if (err_id == NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW)
3663859Sml29623 			zcps.bits.ldw.buf_overflow = 1;
3673859Sml29623 		if (err_id == NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR)
3683859Sml29623 			zcps.bits.ldw.tt_tbl_perr = 1;
3693859Sml29623 		if (err_id == NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR)
3703859Sml29623 			zcps.bits.ldw.rsp_tt_index_err = 1;
3713859Sml29623 		if (err_id == NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR)
3723859Sml29623 			zcps.bits.ldw.slv_tt_index_err = 1;
3733859Sml29623 		if (err_id == NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR)
3743859Sml29623 			zcps.bits.ldw.zcp_tt_index_err = 1;
3755125Sjoycey #if defined(__i386)
3765125Sjoycey 		cmn_err(CE_NOTE, "!Write 0x%llx to ZCP_INT_STAT_TEST_REG\n",
377*6929Smisaki 		    zcps.value);
3785125Sjoycey #else
3793859Sml29623 		cmn_err(CE_NOTE, "!Write 0x%lx to ZCP_INT_STAT_TEST_REG\n",
380*6929Smisaki 		    zcps.value);
3815125Sjoycey #endif
3823859Sml29623 		NXGE_REG_WR64(nxgep->npi_handle, ZCP_INT_STAT_TEST_REG,
383*6929Smisaki 		    zcps.value);
3843859Sml29623 		break;
3853859Sml29623 	}
3863859Sml29623 }
3873859Sml29623 
3883859Sml29623 nxge_status_t
nxge_zcp_fatal_err_recover(p_nxge_t nxgep)3893859Sml29623 nxge_zcp_fatal_err_recover(p_nxge_t nxgep)
3903859Sml29623 {
3913859Sml29623 	npi_handle_t handle;
3923859Sml29623 	npi_status_t rs = NPI_SUCCESS;
3933859Sml29623 	nxge_status_t status = NXGE_OK;
3943859Sml29623 	uint8_t portn;
3953859Sml29623 	zcp_ram_unit_t w_data;
3963859Sml29623 	zcp_ram_unit_t r_data;
3973859Sml29623 	uint32_t cfifo_depth;
3983859Sml29623 	int i;
3993859Sml29623 
4003859Sml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_zcp_fatal_err_recover"));
4013859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
402*6929Smisaki 	    "Recovering from RxPort error..."));
4033859Sml29623 
4043859Sml29623 	handle = nxgep->npi_handle;
4053859Sml29623 	portn = nxgep->mac.portnum;
4063859Sml29623 
4073859Sml29623 	/* Disable RxMAC */
4083859Sml29623 	if (nxge_rx_mac_disable(nxgep) != NXGE_OK)
4093859Sml29623 		goto fail;
4103859Sml29623 
4113859Sml29623 	/* Make sure source is clear if this is an injected error */
4123859Sml29623 	switch (portn) {
4133859Sml29623 	case 0:
4143859Sml29623 		NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT0_REG, 0);
4153859Sml29623 		break;
4163859Sml29623 	case 1:
4173859Sml29623 		NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT1_REG, 0);
4183859Sml29623 		break;
4193859Sml29623 	case 2:
4203859Sml29623 		NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT2_REG, 0);
4213859Sml29623 		break;
4223859Sml29623 	case 3:
4233859Sml29623 		NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT3_REG, 0);
4243859Sml29623 		break;
4253859Sml29623 	}
4263859Sml29623 
4273859Sml29623 	/* Clear up CFIFO */
4284732Sdavemq 	if (nxgep->niu_type == N2_NIU) {
4294732Sdavemq 		cfifo_depth = ZCP_NIU_CFIFO_DEPTH;
4304977Sraghus 	} else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
4313859Sml29623 		if (portn < 2)
4323859Sml29623 			cfifo_depth = ZCP_P0_P1_CFIFO_DEPTH;
4333859Sml29623 		else
4343859Sml29623 			cfifo_depth = ZCP_P2_P3_CFIFO_DEPTH;
4354732Sdavemq 	} else {
4364732Sdavemq 		goto fail;
4374732Sdavemq 	}
4383859Sml29623 
4393859Sml29623 	w_data.w0 = 0;
4403859Sml29623 	w_data.w1 = 0;
4413859Sml29623 	w_data.w2 = 0;
4423859Sml29623 	w_data.w3 = 0;
4433859Sml29623 	w_data.w4 = 0;
4443859Sml29623 
4453859Sml29623 	for (i = 0; i < cfifo_depth; i++) {
4463859Sml29623 		if (npi_zcp_tt_cfifo_entry(handle, OP_SET,
447*6929Smisaki 		    portn, i, &w_data) != NPI_SUCCESS)
4483859Sml29623 			goto fail;
4493859Sml29623 		if (npi_zcp_tt_cfifo_entry(handle, OP_GET,
450*6929Smisaki 		    portn, i, &r_data) != NPI_SUCCESS)
4513859Sml29623 			goto fail;
4523859Sml29623 	}
4533859Sml29623 
4543859Sml29623 	/* When recovering from ZCP, RxDMA channel resets are not necessary */
4553859Sml29623 	/* Reset ZCP CFIFO */
4563859Sml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset ZCP CFIFO...", portn));
4573859Sml29623 	if ((rs = npi_zcp_rest_cfifo_port(handle, portn)) != NPI_SUCCESS)
4583859Sml29623 		goto fail;
4593859Sml29623 
4603859Sml29623 	/* Reset IPP */
4613859Sml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset IPP...", portn));
4623859Sml29623 	if ((rs = npi_ipp_reset(handle, portn)) != NPI_SUCCESS)
4633859Sml29623 		goto fail;
4643859Sml29623 
4653859Sml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset RxMAC...", portn));
4663859Sml29623 	if (nxge_rx_mac_reset(nxgep) != NXGE_OK)
4673859Sml29623 		goto fail;
4683859Sml29623 
4693859Sml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Initialize RxMAC...", portn));
4703859Sml29623 	if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
4713859Sml29623 		goto fail;
4723859Sml29623 
4733859Sml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Enable RxMAC...", portn));
4743859Sml29623 	if (nxge_rx_mac_enable(nxgep) != NXGE_OK)
4753859Sml29623 		goto fail;
4763859Sml29623 
4773859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
478*6929Smisaki 	    "Recovery Sucessful, RxPort Restored"));
4793859Sml29623 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_zcp_fatal_err_recover"));
4803859Sml29623 	return (NXGE_OK);
4813859Sml29623 fail:
4823859Sml29623 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Recovery failed"));
4833859Sml29623 	return (status | rs);
4843859Sml29623 }
485