144961713Sgirish /* 244961713Sgirish * CDDL HEADER START 344961713Sgirish * 444961713Sgirish * The contents of this file are subject to the terms of the 544961713Sgirish * Common Development and Distribution License (the "License"). 644961713Sgirish * You may not use this file except in compliance with the License. 744961713Sgirish * 844961713Sgirish * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 944961713Sgirish * or http://www.opensolaris.org/os/licensing. 1044961713Sgirish * See the License for the specific language governing permissions 1144961713Sgirish * and limitations under the License. 1244961713Sgirish * 1344961713Sgirish * When distributing Covered Code, include this CDDL HEADER in each 1444961713Sgirish * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1544961713Sgirish * If applicable, add the following below this CDDL HEADER, with the 1644961713Sgirish * fields enclosed by brackets "[]" replaced with your own identifying 1744961713Sgirish * information: Portions Copyright [yyyy] [name of copyright owner] 1844961713Sgirish * 1944961713Sgirish * CDDL HEADER END 2044961713Sgirish */ 2144961713Sgirish /* 22*52ccf843Smisaki * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2344961713Sgirish * Use is subject to license terms. 2444961713Sgirish */ 2544961713Sgirish 2644961713Sgirish #pragma ident "%Z%%M% %I% %E% SMI" 2744961713Sgirish 2844961713Sgirish #include <nxge_impl.h> 2944961713Sgirish #include <nxge_zcp.h> 3014ea4bb7Ssd #include <nxge_ipp.h> 3114ea4bb7Ssd 3244961713Sgirish nxge_status_t 3344961713Sgirish nxge_zcp_init(p_nxge_t nxgep) 3444961713Sgirish { 35a3c5bd6dSspeer uint8_t portn; 36a3c5bd6dSspeer npi_handle_t handle; 37a3c5bd6dSspeer zcp_iconfig_t istatus; 38a3c5bd6dSspeer npi_status_t rs = NPI_SUCCESS; 39a3c5bd6dSspeer int i; 40a3c5bd6dSspeer zcp_ram_unit_t w_data; 41a3c5bd6dSspeer zcp_ram_unit_t r_data; 42a3c5bd6dSspeer uint32_t cfifo_depth; 4344961713Sgirish 4444961713Sgirish handle = nxgep->npi_handle; 4544961713Sgirish portn = NXGE_GET_PORT_NUM(nxgep->function_num); 4644961713Sgirish 4759ac0c16Sdavemq if (nxgep->niu_type == N2_NIU) { 4859ac0c16Sdavemq cfifo_depth = ZCP_NIU_CFIFO_DEPTH; 492e59129aSraghus } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 5044961713Sgirish if (portn < 2) 5144961713Sgirish cfifo_depth = ZCP_P0_P1_CFIFO_DEPTH; 5244961713Sgirish else 5344961713Sgirish cfifo_depth = ZCP_P2_P3_CFIFO_DEPTH; 5459ac0c16Sdavemq } else { 5559ac0c16Sdavemq goto fail; 5659ac0c16Sdavemq } 5744961713Sgirish 5844961713Sgirish /* Clean up CFIFO */ 5944961713Sgirish w_data.w0 = 0; 6044961713Sgirish w_data.w1 = 0; 6144961713Sgirish w_data.w2 = 0; 6244961713Sgirish w_data.w3 = 0; 6344961713Sgirish w_data.w4 = 0; 64a3c5bd6dSspeer 6544961713Sgirish for (i = 0; i < cfifo_depth; i++) { 66a3c5bd6dSspeer if (npi_zcp_tt_cfifo_entry(handle, OP_SET, 67*52ccf843Smisaki portn, i, &w_data) != NPI_SUCCESS) 6844961713Sgirish goto fail; 69a3c5bd6dSspeer if (npi_zcp_tt_cfifo_entry(handle, OP_GET, 70*52ccf843Smisaki portn, i, &r_data) != NPI_SUCCESS) 7144961713Sgirish goto fail; 7244961713Sgirish } 7344961713Sgirish 7444961713Sgirish if (npi_zcp_rest_cfifo_port(handle, portn) != NPI_SUCCESS) 75a3c5bd6dSspeer goto fail; 76a3c5bd6dSspeer 7744961713Sgirish /* 78a3c5bd6dSspeer * Making sure that error source is cleared if this is an injected 79a3c5bd6dSspeer * error. 8044961713Sgirish */ 8144961713Sgirish switch (portn) { 8244961713Sgirish case 0: 8344961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT0_REG, 0); 8444961713Sgirish break; 8544961713Sgirish case 1: 8644961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT1_REG, 0); 8744961713Sgirish break; 8844961713Sgirish case 2: 8944961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT2_REG, 0); 9044961713Sgirish break; 9144961713Sgirish case 3: 9244961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT3_REG, 0); 9344961713Sgirish break; 9444961713Sgirish } 9544961713Sgirish 9614ea4bb7Ssd if ((rs = npi_zcp_clear_istatus(handle)) != NPI_SUCCESS) 9714ea4bb7Ssd return (NXGE_ERROR | rs); 9844961713Sgirish if ((rs = npi_zcp_get_istatus(handle, &istatus)) != NPI_SUCCESS) 9944961713Sgirish return (NXGE_ERROR | rs); 10044961713Sgirish if ((rs = npi_zcp_iconfig(handle, INIT, ICFG_ZCP_ALL)) != NPI_SUCCESS) 10144961713Sgirish goto fail; 10244961713Sgirish 10344961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_zcp_init: port%d", portn)); 10444961713Sgirish return (NXGE_OK); 10544961713Sgirish 10644961713Sgirish fail: 10744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 108*52ccf843Smisaki "nxge_zcp_init: Fail to initialize ZCP Port #%d\n", portn)); 10944961713Sgirish return (NXGE_ERROR | rs); 11044961713Sgirish } 11144961713Sgirish 11244961713Sgirish nxge_status_t 11344961713Sgirish nxge_zcp_handle_sys_errors(p_nxge_t nxgep) 11444961713Sgirish { 115a3c5bd6dSspeer npi_handle_t handle; 116a3c5bd6dSspeer npi_status_t rs = NPI_SUCCESS; 117a3c5bd6dSspeer p_nxge_zcp_stats_t statsp; 118a3c5bd6dSspeer uint8_t portn; 119a3c5bd6dSspeer zcp_iconfig_t istatus; 120a3c5bd6dSspeer boolean_t rxport_fatal = B_FALSE; 121a3c5bd6dSspeer nxge_status_t status = NXGE_OK; 12244961713Sgirish 12344961713Sgirish handle = nxgep->npi_handle; 12444961713Sgirish statsp = (p_nxge_zcp_stats_t)&nxgep->statsp->zcp_stats; 12544961713Sgirish portn = nxgep->mac.portnum; 12644961713Sgirish 12744961713Sgirish if ((rs = npi_zcp_get_istatus(handle, &istatus)) != NPI_SUCCESS) 12844961713Sgirish return (NXGE_ERROR | rs); 12944961713Sgirish 13044961713Sgirish if (istatus & ICFG_ZCP_RRFIFO_UNDERRUN) { 13144961713Sgirish statsp->rrfifo_underrun++; 13244961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 133*52ccf843Smisaki NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN); 13444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 135*52ccf843Smisaki "nxge_zcp_err_evnts: rrfifo_underrun")); 13644961713Sgirish } 137a3c5bd6dSspeer 13844961713Sgirish if (istatus & ICFG_ZCP_RRFIFO_OVERRUN) { 13944961713Sgirish statsp->rrfifo_overrun++; 14044961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 141*52ccf843Smisaki NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN); 14244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 143*52ccf843Smisaki "nxge_zcp_err_evnts: buf_rrfifo_overrun")); 14444961713Sgirish } 145a3c5bd6dSspeer 14644961713Sgirish if (istatus & ICFG_ZCP_RSPFIFO_UNCORR_ERR) { 14744961713Sgirish statsp->rspfifo_uncorr_err++; 14844961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 149*52ccf843Smisaki NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR); 15044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 151*52ccf843Smisaki "nxge_zcp_err_evnts: rspfifo_uncorr_err")); 15244961713Sgirish } 153a3c5bd6dSspeer 15444961713Sgirish if (istatus & ICFG_ZCP_BUFFER_OVERFLOW) { 15544961713Sgirish statsp->buffer_overflow++; 15644961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 157*52ccf843Smisaki NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW); 15844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 159*52ccf843Smisaki "nxge_zcp_err_evnts: buffer_overflow")); 16044961713Sgirish rxport_fatal = B_TRUE; 16144961713Sgirish } 162a3c5bd6dSspeer 16344961713Sgirish if (istatus & ICFG_ZCP_STAT_TBL_PERR) { 16444961713Sgirish statsp->stat_tbl_perr++; 16544961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 166*52ccf843Smisaki NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR); 16744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 168*52ccf843Smisaki "nxge_zcp_err_evnts: stat_tbl_perr")); 16944961713Sgirish } 170a3c5bd6dSspeer 17144961713Sgirish if (istatus & ICFG_ZCP_DYN_TBL_PERR) { 17244961713Sgirish statsp->dyn_tbl_perr++; 17344961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 174*52ccf843Smisaki NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR); 17544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 176*52ccf843Smisaki "nxge_zcp_err_evnts: dyn_tbl_perr")); 17744961713Sgirish } 178a3c5bd6dSspeer 17944961713Sgirish if (istatus & ICFG_ZCP_BUF_TBL_PERR) { 18044961713Sgirish statsp->buf_tbl_perr++; 18144961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 182*52ccf843Smisaki NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR); 18344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 184*52ccf843Smisaki "nxge_zcp_err_evnts: buf_tbl_perr")); 18544961713Sgirish } 186a3c5bd6dSspeer 18744961713Sgirish if (istatus & ICFG_ZCP_TT_PROGRAM_ERR) { 18844961713Sgirish statsp->tt_program_err++; 18944961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 190*52ccf843Smisaki NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR); 19144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 192*52ccf843Smisaki "nxge_zcp_err_evnts: tt_program_err")); 19344961713Sgirish } 194a3c5bd6dSspeer 19544961713Sgirish if (istatus & ICFG_ZCP_RSP_TT_INDEX_ERR) { 19644961713Sgirish statsp->rsp_tt_index_err++; 19744961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 198*52ccf843Smisaki NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR); 19944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 200*52ccf843Smisaki "nxge_zcp_err_evnts: rsp_tt_index_err")); 20144961713Sgirish } 202a3c5bd6dSspeer 20344961713Sgirish if (istatus & ICFG_ZCP_SLV_TT_INDEX_ERR) { 20444961713Sgirish statsp->slv_tt_index_err++; 20544961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 206*52ccf843Smisaki NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR); 20744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 208*52ccf843Smisaki "nxge_zcp_err_evnts: slv_tt_index_err")); 20944961713Sgirish } 210a3c5bd6dSspeer 21144961713Sgirish if (istatus & ICFG_ZCP_TT_INDEX_ERR) { 21244961713Sgirish statsp->zcp_tt_index_err++; 21344961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 214*52ccf843Smisaki NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR); 21544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 216*52ccf843Smisaki "nxge_zcp_err_evnts: tt_index_err")); 21744961713Sgirish } 218a3c5bd6dSspeer 21944961713Sgirish if (((portn == 0) && (istatus & ICFG_ZCP_CFIFO_ECC0)) || 220*52ccf843Smisaki ((portn == 1) && (istatus & ICFG_ZCP_CFIFO_ECC1)) || 221*52ccf843Smisaki ((portn == 2) && (istatus & ICFG_ZCP_CFIFO_ECC2)) || 222*52ccf843Smisaki ((portn == 3) && (istatus & ICFG_ZCP_CFIFO_ECC3))) { 22314ea4bb7Ssd boolean_t ue_ecc_valid; 22414ea4bb7Ssd 22514ea4bb7Ssd if ((status = nxge_ipp_eccue_valid_check(nxgep, 226*52ccf843Smisaki &ue_ecc_valid)) != NXGE_OK) 22714ea4bb7Ssd return (status); 22814ea4bb7Ssd 22914ea4bb7Ssd if (ue_ecc_valid) { 23014ea4bb7Ssd statsp->cfifo_ecc++; 23114ea4bb7Ssd NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 232*52ccf843Smisaki NXGE_FM_EREPORT_ZCP_CFIFO_ECC); 23314ea4bb7Ssd NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 234*52ccf843Smisaki "nxge_zcp_err_evnts: port%d buf_cfifo_ecc", 235*52ccf843Smisaki portn)); 23614ea4bb7Ssd rxport_fatal = B_TRUE; 23714ea4bb7Ssd } 23844961713Sgirish } 23944961713Sgirish 24044961713Sgirish /* 241a3c5bd6dSspeer * Making sure that error source is cleared if this is an injected 242a3c5bd6dSspeer * error. 24344961713Sgirish */ 24444961713Sgirish switch (portn) { 24544961713Sgirish case 0: 24644961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT0_REG, 0); 24744961713Sgirish break; 24844961713Sgirish case 1: 24944961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT1_REG, 0); 25044961713Sgirish break; 25144961713Sgirish case 2: 25244961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT2_REG, 0); 25344961713Sgirish break; 25444961713Sgirish case 3: 25544961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT3_REG, 0); 25644961713Sgirish break; 25744961713Sgirish } 25844961713Sgirish 25944961713Sgirish (void) npi_zcp_clear_istatus(handle); 26044961713Sgirish 26144961713Sgirish if (rxport_fatal) { 26244961713Sgirish NXGE_DEBUG_MSG((nxgep, IPP_CTL, 263*52ccf843Smisaki " nxge_zcp_handle_sys_errors:" 264*52ccf843Smisaki " fatal Error on Port #%d\n", portn)); 26544961713Sgirish status = nxge_zcp_fatal_err_recover(nxgep); 26644961713Sgirish if (status == NXGE_OK) { 26744961713Sgirish FM_SERVICE_RESTORED(nxgep); 26844961713Sgirish } 26944961713Sgirish } 27044961713Sgirish return (status); 27144961713Sgirish } 27244961713Sgirish 27344961713Sgirish void 27444961713Sgirish nxge_zcp_inject_err(p_nxge_t nxgep, uint32_t err_id) 27544961713Sgirish { 276a3c5bd6dSspeer zcp_int_stat_reg_t zcps; 277a3c5bd6dSspeer uint8_t portn = nxgep->mac.portnum; 278a3c5bd6dSspeer zcp_ecc_ctrl_t ecc_ctrl; 27944961713Sgirish 28044961713Sgirish switch (err_id) { 28144961713Sgirish case NXGE_FM_EREPORT_ZCP_CFIFO_ECC: 28244961713Sgirish ecc_ctrl.value = 0; 28344961713Sgirish ecc_ctrl.bits.w0.cor_dbl = 1; 28444961713Sgirish ecc_ctrl.bits.w0.cor_lst = 1; 28544961713Sgirish ecc_ctrl.bits.w0.cor_all = 0; 28644961713Sgirish switch (portn) { 28744961713Sgirish case 0: 28844961713Sgirish cmn_err(CE_NOTE, 289*52ccf843Smisaki "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 290*52ccf843Smisaki (unsigned long long) ecc_ctrl.value, portn); 29144961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, 292*52ccf843Smisaki ZCP_CFIFO_ECC_PORT0_REG, 293*52ccf843Smisaki ecc_ctrl.value); 29444961713Sgirish break; 29544961713Sgirish case 1: 29644961713Sgirish cmn_err(CE_NOTE, 297*52ccf843Smisaki "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 298*52ccf843Smisaki (unsigned long long) ecc_ctrl.value, portn); 29944961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, 300*52ccf843Smisaki ZCP_CFIFO_ECC_PORT1_REG, 301*52ccf843Smisaki ecc_ctrl.value); 30244961713Sgirish break; 30344961713Sgirish case 2: 30444961713Sgirish cmn_err(CE_NOTE, 305*52ccf843Smisaki "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 306*52ccf843Smisaki (unsigned long long) ecc_ctrl.value, portn); 30744961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, 308*52ccf843Smisaki ZCP_CFIFO_ECC_PORT2_REG, 309*52ccf843Smisaki ecc_ctrl.value); 31044961713Sgirish break; 31144961713Sgirish case 3: 31244961713Sgirish cmn_err(CE_NOTE, 313*52ccf843Smisaki "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 314*52ccf843Smisaki (unsigned long long) ecc_ctrl.value, portn); 31544961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, 316*52ccf843Smisaki ZCP_CFIFO_ECC_PORT3_REG, 317*52ccf843Smisaki ecc_ctrl.value); 31844961713Sgirish break; 31944961713Sgirish } 32044961713Sgirish break; 321a3c5bd6dSspeer 32244961713Sgirish case NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN: 32344961713Sgirish case NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR: 32444961713Sgirish case NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR: 32544961713Sgirish case NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR: 32644961713Sgirish case NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR: 32744961713Sgirish case NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN: 32844961713Sgirish case NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW: 32944961713Sgirish case NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR: 33044961713Sgirish case NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR: 33144961713Sgirish case NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR: 33244961713Sgirish case NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR: 33344961713Sgirish NXGE_REG_RD64(nxgep->npi_handle, ZCP_INT_STAT_TEST_REG, 334*52ccf843Smisaki &zcps.value); 33544961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN) 33644961713Sgirish zcps.bits.ldw.rrfifo_urun = 1; 33744961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR) 33844961713Sgirish zcps.bits.ldw.rspfifo_uc_err = 1; 33944961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR) 34044961713Sgirish zcps.bits.ldw.stat_tbl_perr = 1; 34144961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR) 34244961713Sgirish zcps.bits.ldw.dyn_tbl_perr = 1; 34344961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR) 34444961713Sgirish zcps.bits.ldw.buf_tbl_perr = 1; 34544961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_CFIFO_ECC) { 34644961713Sgirish switch (portn) { 34744961713Sgirish case 0: 34844961713Sgirish zcps.bits.ldw.cfifo_ecc0 = 1; 34944961713Sgirish break; 35044961713Sgirish case 1: 35144961713Sgirish zcps.bits.ldw.cfifo_ecc1 = 1; 35244961713Sgirish break; 35344961713Sgirish case 2: 35444961713Sgirish zcps.bits.ldw.cfifo_ecc2 = 1; 35544961713Sgirish break; 35644961713Sgirish case 3: 35744961713Sgirish zcps.bits.ldw.cfifo_ecc3 = 1; 35844961713Sgirish break; 35944961713Sgirish } 36044961713Sgirish } 361a3c5bd6dSspeer 362a3c5bd6dSspeer default: 36344961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN) 36444961713Sgirish zcps.bits.ldw.rrfifo_orun = 1; 36544961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW) 36644961713Sgirish zcps.bits.ldw.buf_overflow = 1; 36744961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR) 36844961713Sgirish zcps.bits.ldw.tt_tbl_perr = 1; 36944961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR) 37044961713Sgirish zcps.bits.ldw.rsp_tt_index_err = 1; 37144961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR) 37244961713Sgirish zcps.bits.ldw.slv_tt_index_err = 1; 37344961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR) 37444961713Sgirish zcps.bits.ldw.zcp_tt_index_err = 1; 375adfcba55Sjoycey #if defined(__i386) 376adfcba55Sjoycey cmn_err(CE_NOTE, "!Write 0x%llx to ZCP_INT_STAT_TEST_REG\n", 377*52ccf843Smisaki zcps.value); 378adfcba55Sjoycey #else 37944961713Sgirish cmn_err(CE_NOTE, "!Write 0x%lx to ZCP_INT_STAT_TEST_REG\n", 380*52ccf843Smisaki zcps.value); 381adfcba55Sjoycey #endif 38244961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, ZCP_INT_STAT_TEST_REG, 383*52ccf843Smisaki zcps.value); 38444961713Sgirish break; 38544961713Sgirish } 38644961713Sgirish } 38744961713Sgirish 38844961713Sgirish nxge_status_t 38944961713Sgirish nxge_zcp_fatal_err_recover(p_nxge_t nxgep) 39044961713Sgirish { 391a3c5bd6dSspeer npi_handle_t handle; 392a3c5bd6dSspeer npi_status_t rs = NPI_SUCCESS; 393a3c5bd6dSspeer nxge_status_t status = NXGE_OK; 394a3c5bd6dSspeer uint8_t portn; 395a3c5bd6dSspeer zcp_ram_unit_t w_data; 396a3c5bd6dSspeer zcp_ram_unit_t r_data; 397a3c5bd6dSspeer uint32_t cfifo_depth; 398a3c5bd6dSspeer int i; 39944961713Sgirish 40044961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_zcp_fatal_err_recover")); 40144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 402*52ccf843Smisaki "Recovering from RxPort error...")); 40344961713Sgirish 40444961713Sgirish handle = nxgep->npi_handle; 40544961713Sgirish portn = nxgep->mac.portnum; 40644961713Sgirish 40744961713Sgirish /* Disable RxMAC */ 40844961713Sgirish if (nxge_rx_mac_disable(nxgep) != NXGE_OK) 40944961713Sgirish goto fail; 41044961713Sgirish 41144961713Sgirish /* Make sure source is clear if this is an injected error */ 41244961713Sgirish switch (portn) { 41344961713Sgirish case 0: 41444961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT0_REG, 0); 41544961713Sgirish break; 41644961713Sgirish case 1: 41744961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT1_REG, 0); 41844961713Sgirish break; 41944961713Sgirish case 2: 42044961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT2_REG, 0); 42144961713Sgirish break; 42244961713Sgirish case 3: 42344961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT3_REG, 0); 42444961713Sgirish break; 42544961713Sgirish } 42644961713Sgirish 42744961713Sgirish /* Clear up CFIFO */ 42859ac0c16Sdavemq if (nxgep->niu_type == N2_NIU) { 42959ac0c16Sdavemq cfifo_depth = ZCP_NIU_CFIFO_DEPTH; 4302e59129aSraghus } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 43144961713Sgirish if (portn < 2) 43244961713Sgirish cfifo_depth = ZCP_P0_P1_CFIFO_DEPTH; 43344961713Sgirish else 43444961713Sgirish cfifo_depth = ZCP_P2_P3_CFIFO_DEPTH; 43559ac0c16Sdavemq } else { 43659ac0c16Sdavemq goto fail; 43759ac0c16Sdavemq } 438a3c5bd6dSspeer 43944961713Sgirish w_data.w0 = 0; 44044961713Sgirish w_data.w1 = 0; 44144961713Sgirish w_data.w2 = 0; 44244961713Sgirish w_data.w3 = 0; 44344961713Sgirish w_data.w4 = 0; 444a3c5bd6dSspeer 44544961713Sgirish for (i = 0; i < cfifo_depth; i++) { 446a3c5bd6dSspeer if (npi_zcp_tt_cfifo_entry(handle, OP_SET, 447*52ccf843Smisaki portn, i, &w_data) != NPI_SUCCESS) 44844961713Sgirish goto fail; 449a3c5bd6dSspeer if (npi_zcp_tt_cfifo_entry(handle, OP_GET, 450*52ccf843Smisaki portn, i, &r_data) != NPI_SUCCESS) 45144961713Sgirish goto fail; 45244961713Sgirish } 45344961713Sgirish 45444961713Sgirish /* When recovering from ZCP, RxDMA channel resets are not necessary */ 45544961713Sgirish /* Reset ZCP CFIFO */ 45644961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset ZCP CFIFO...", portn)); 45744961713Sgirish if ((rs = npi_zcp_rest_cfifo_port(handle, portn)) != NPI_SUCCESS) 45844961713Sgirish goto fail; 45944961713Sgirish 46044961713Sgirish /* Reset IPP */ 46144961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset IPP...", portn)); 46244961713Sgirish if ((rs = npi_ipp_reset(handle, portn)) != NPI_SUCCESS) 46344961713Sgirish goto fail; 46444961713Sgirish 46544961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset RxMAC...", portn)); 46644961713Sgirish if (nxge_rx_mac_reset(nxgep) != NXGE_OK) 46744961713Sgirish goto fail; 46844961713Sgirish 46944961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Initialize RxMAC...", portn)); 47044961713Sgirish if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 47144961713Sgirish goto fail; 47244961713Sgirish 47344961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Enable RxMAC...", portn)); 47444961713Sgirish if (nxge_rx_mac_enable(nxgep) != NXGE_OK) 47544961713Sgirish goto fail; 47644961713Sgirish 47744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 478*52ccf843Smisaki "Recovery Sucessful, RxPort Restored")); 47944961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_zcp_fatal_err_recover")); 48044961713Sgirish return (NXGE_OK); 48144961713Sgirish fail: 48244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Recovery failed")); 48344961713Sgirish return (status | rs); 48444961713Sgirish } 485