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 /* 22a3c5bd6dSspeer * Copyright 2007 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; 49*2e59129aSraghus } 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, 67a3c5bd6dSspeer portn, i, &w_data) != NPI_SUCCESS) 6844961713Sgirish goto fail; 69a3c5bd6dSspeer if (npi_zcp_tt_cfifo_entry(handle, OP_GET, 70a3c5bd6dSspeer 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, 108a3c5bd6dSspeer "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, 133a3c5bd6dSspeer NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN); 13444961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 13544961713Sgirish "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, 141a3c5bd6dSspeer NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN); 14244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 14344961713Sgirish "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, 149a3c5bd6dSspeer NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR); 15044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 15144961713Sgirish "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, 157a3c5bd6dSspeer NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW); 15844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 15944961713Sgirish "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, 166a3c5bd6dSspeer NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR); 16744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16844961713Sgirish "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, 174a3c5bd6dSspeer NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR); 17544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 17644961713Sgirish "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, 182a3c5bd6dSspeer NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR); 18344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18444961713Sgirish "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, 190a3c5bd6dSspeer NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR); 19144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19244961713Sgirish "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, 198a3c5bd6dSspeer NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR); 19944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 20044961713Sgirish "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, 206a3c5bd6dSspeer NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR); 20744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 20844961713Sgirish "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, 214a3c5bd6dSspeer NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR); 21544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21644961713Sgirish "nxge_zcp_err_evnts: tt_index_err")); 21744961713Sgirish } 218a3c5bd6dSspeer 21944961713Sgirish if (((portn == 0) && (istatus & ICFG_ZCP_CFIFO_ECC0)) || 220a3c5bd6dSspeer ((portn == 1) && (istatus & ICFG_ZCP_CFIFO_ECC1)) || 221a3c5bd6dSspeer ((portn == 2) && (istatus & ICFG_ZCP_CFIFO_ECC2)) || 222a3c5bd6dSspeer ((portn == 3) && (istatus & ICFG_ZCP_CFIFO_ECC3))) { 22314ea4bb7Ssd boolean_t ue_ecc_valid; 22414ea4bb7Ssd 22514ea4bb7Ssd if ((status = nxge_ipp_eccue_valid_check(nxgep, 226a3c5bd6dSspeer &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, 232a3c5bd6dSspeer NXGE_FM_EREPORT_ZCP_CFIFO_ECC); 23314ea4bb7Ssd NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 234a3c5bd6dSspeer "nxge_zcp_err_evnts: port%d buf_cfifo_ecc", 235a3c5bd6dSspeer 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, 263a3c5bd6dSspeer " nxge_zcp_handle_sys_errors:" 264a3c5bd6dSspeer " 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, 28944961713Sgirish "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 290a3c5bd6dSspeer (unsigned long long) ecc_ctrl.value, portn); 29144961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, 292a3c5bd6dSspeer ZCP_CFIFO_ECC_PORT0_REG, 293a3c5bd6dSspeer ecc_ctrl.value); 29444961713Sgirish break; 29544961713Sgirish case 1: 29644961713Sgirish cmn_err(CE_NOTE, 29744961713Sgirish "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 298a3c5bd6dSspeer (unsigned long long) ecc_ctrl.value, portn); 29944961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, 300a3c5bd6dSspeer ZCP_CFIFO_ECC_PORT1_REG, 301a3c5bd6dSspeer ecc_ctrl.value); 30244961713Sgirish break; 30344961713Sgirish case 2: 30444961713Sgirish cmn_err(CE_NOTE, 30544961713Sgirish "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 306a3c5bd6dSspeer (unsigned long long) ecc_ctrl.value, portn); 30744961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, 308a3c5bd6dSspeer ZCP_CFIFO_ECC_PORT2_REG, 309a3c5bd6dSspeer ecc_ctrl.value); 31044961713Sgirish break; 31144961713Sgirish case 3: 31244961713Sgirish cmn_err(CE_NOTE, 31344961713Sgirish "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 314a3c5bd6dSspeer (unsigned long long) ecc_ctrl.value, portn); 31544961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, 316a3c5bd6dSspeer ZCP_CFIFO_ECC_PORT3_REG, 317a3c5bd6dSspeer 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, 334a3c5bd6dSspeer &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; 37544961713Sgirish cmn_err(CE_NOTE, "!Write 0x%lx to ZCP_INT_STAT_TEST_REG\n", 376a3c5bd6dSspeer zcps.value); 37744961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, ZCP_INT_STAT_TEST_REG, 378a3c5bd6dSspeer zcps.value); 37944961713Sgirish break; 38044961713Sgirish } 38144961713Sgirish } 38244961713Sgirish 38344961713Sgirish nxge_status_t 38444961713Sgirish nxge_zcp_fatal_err_recover(p_nxge_t nxgep) 38544961713Sgirish { 386a3c5bd6dSspeer npi_handle_t handle; 387a3c5bd6dSspeer npi_status_t rs = NPI_SUCCESS; 388a3c5bd6dSspeer nxge_status_t status = NXGE_OK; 389a3c5bd6dSspeer uint8_t portn; 390a3c5bd6dSspeer zcp_ram_unit_t w_data; 391a3c5bd6dSspeer zcp_ram_unit_t r_data; 392a3c5bd6dSspeer uint32_t cfifo_depth; 393a3c5bd6dSspeer int i; 39444961713Sgirish 39544961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_zcp_fatal_err_recover")); 39644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 397a3c5bd6dSspeer "Recovering from RxPort error...")); 39844961713Sgirish 39944961713Sgirish handle = nxgep->npi_handle; 40044961713Sgirish portn = nxgep->mac.portnum; 40144961713Sgirish 40244961713Sgirish /* Disable RxMAC */ 40344961713Sgirish if (nxge_rx_mac_disable(nxgep) != NXGE_OK) 40444961713Sgirish goto fail; 40544961713Sgirish 40644961713Sgirish /* Make sure source is clear if this is an injected error */ 40744961713Sgirish switch (portn) { 40844961713Sgirish case 0: 40944961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT0_REG, 0); 41044961713Sgirish break; 41144961713Sgirish case 1: 41244961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT1_REG, 0); 41344961713Sgirish break; 41444961713Sgirish case 2: 41544961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT2_REG, 0); 41644961713Sgirish break; 41744961713Sgirish case 3: 41844961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT3_REG, 0); 41944961713Sgirish break; 42044961713Sgirish } 42144961713Sgirish 42244961713Sgirish /* Clear up CFIFO */ 42359ac0c16Sdavemq if (nxgep->niu_type == N2_NIU) { 42459ac0c16Sdavemq cfifo_depth = ZCP_NIU_CFIFO_DEPTH; 425*2e59129aSraghus } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 42644961713Sgirish if (portn < 2) 42744961713Sgirish cfifo_depth = ZCP_P0_P1_CFIFO_DEPTH; 42844961713Sgirish else 42944961713Sgirish cfifo_depth = ZCP_P2_P3_CFIFO_DEPTH; 43059ac0c16Sdavemq } else { 43159ac0c16Sdavemq goto fail; 43259ac0c16Sdavemq } 433a3c5bd6dSspeer 43444961713Sgirish w_data.w0 = 0; 43544961713Sgirish w_data.w1 = 0; 43644961713Sgirish w_data.w2 = 0; 43744961713Sgirish w_data.w3 = 0; 43844961713Sgirish w_data.w4 = 0; 439a3c5bd6dSspeer 44044961713Sgirish for (i = 0; i < cfifo_depth; i++) { 441a3c5bd6dSspeer if (npi_zcp_tt_cfifo_entry(handle, OP_SET, 442a3c5bd6dSspeer portn, i, &w_data) != NPI_SUCCESS) 44344961713Sgirish goto fail; 444a3c5bd6dSspeer if (npi_zcp_tt_cfifo_entry(handle, OP_GET, 445a3c5bd6dSspeer portn, i, &r_data) != NPI_SUCCESS) 44644961713Sgirish goto fail; 44744961713Sgirish } 44844961713Sgirish 44944961713Sgirish /* When recovering from ZCP, RxDMA channel resets are not necessary */ 45044961713Sgirish /* Reset ZCP CFIFO */ 45144961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset ZCP CFIFO...", portn)); 45244961713Sgirish if ((rs = npi_zcp_rest_cfifo_port(handle, portn)) != NPI_SUCCESS) 45344961713Sgirish goto fail; 45444961713Sgirish 45544961713Sgirish /* Reset IPP */ 45644961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset IPP...", portn)); 45744961713Sgirish if ((rs = npi_ipp_reset(handle, portn)) != NPI_SUCCESS) 45844961713Sgirish goto fail; 45944961713Sgirish 46044961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset RxMAC...", portn)); 46144961713Sgirish if (nxge_rx_mac_reset(nxgep) != NXGE_OK) 46244961713Sgirish goto fail; 46344961713Sgirish 46444961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Initialize RxMAC...", portn)); 46544961713Sgirish if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 46644961713Sgirish goto fail; 46744961713Sgirish 46844961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Enable RxMAC...", portn)); 46944961713Sgirish if (nxge_rx_mac_enable(nxgep) != NXGE_OK) 47044961713Sgirish goto fail; 47144961713Sgirish 47244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 473a3c5bd6dSspeer "Recovery Sucessful, RxPort Restored")); 47444961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_zcp_fatal_err_recover")); 47544961713Sgirish return (NXGE_OK); 47644961713Sgirish fail: 47744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Recovery failed")); 47844961713Sgirish return (status | rs); 47944961713Sgirish } 480