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