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 /* 2252ccf843Smisaki * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2344961713Sgirish * Use is subject to license terms. 2444961713Sgirish */ 2544961713Sgirish 2644961713Sgirish #include <nxge_impl.h> 2744961713Sgirish #include <nxge_zcp.h> 2814ea4bb7Ssd #include <nxge_ipp.h> 2914ea4bb7Ssd 3044961713Sgirish nxge_status_t 3144961713Sgirish nxge_zcp_init(p_nxge_t nxgep) 3244961713Sgirish { 33a3c5bd6dSspeer uint8_t portn; 34a3c5bd6dSspeer npi_handle_t handle; 35a3c5bd6dSspeer zcp_iconfig_t istatus; 36a3c5bd6dSspeer npi_status_t rs = NPI_SUCCESS; 37a3c5bd6dSspeer int i; 38a3c5bd6dSspeer zcp_ram_unit_t w_data; 39a3c5bd6dSspeer zcp_ram_unit_t r_data; 40a3c5bd6dSspeer uint32_t cfifo_depth; 4144961713Sgirish 4244961713Sgirish handle = nxgep->npi_handle; 4344961713Sgirish portn = NXGE_GET_PORT_NUM(nxgep->function_num); 4444961713Sgirish 4559ac0c16Sdavemq if (nxgep->niu_type == N2_NIU) { 4659ac0c16Sdavemq cfifo_depth = ZCP_NIU_CFIFO_DEPTH; 472e59129aSraghus } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 4844961713Sgirish if (portn < 2) 4944961713Sgirish cfifo_depth = ZCP_P0_P1_CFIFO_DEPTH; 5044961713Sgirish else 5144961713Sgirish cfifo_depth = ZCP_P2_P3_CFIFO_DEPTH; 5259ac0c16Sdavemq } else { 5359ac0c16Sdavemq goto fail; 5459ac0c16Sdavemq } 5544961713Sgirish 5644961713Sgirish /* Clean up CFIFO */ 5744961713Sgirish w_data.w0 = 0; 5844961713Sgirish w_data.w1 = 0; 5944961713Sgirish w_data.w2 = 0; 6044961713Sgirish w_data.w3 = 0; 6144961713Sgirish w_data.w4 = 0; 62a3c5bd6dSspeer 6344961713Sgirish for (i = 0; i < cfifo_depth; i++) { 64a3c5bd6dSspeer if (npi_zcp_tt_cfifo_entry(handle, OP_SET, 6552ccf843Smisaki portn, i, &w_data) != NPI_SUCCESS) 6644961713Sgirish goto fail; 67a3c5bd6dSspeer if (npi_zcp_tt_cfifo_entry(handle, OP_GET, 6852ccf843Smisaki portn, i, &r_data) != NPI_SUCCESS) 6944961713Sgirish goto fail; 7044961713Sgirish } 7144961713Sgirish 7244961713Sgirish if (npi_zcp_rest_cfifo_port(handle, portn) != NPI_SUCCESS) 73a3c5bd6dSspeer goto fail; 74a3c5bd6dSspeer 7544961713Sgirish /* 76a3c5bd6dSspeer * Making sure that error source is cleared if this is an injected 77a3c5bd6dSspeer * error. 7844961713Sgirish */ 7944961713Sgirish switch (portn) { 8044961713Sgirish case 0: 8144961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT0_REG, 0); 8244961713Sgirish break; 8344961713Sgirish case 1: 8444961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT1_REG, 0); 8544961713Sgirish break; 8644961713Sgirish case 2: 8744961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT2_REG, 0); 8844961713Sgirish break; 8944961713Sgirish case 3: 9044961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT3_REG, 0); 9144961713Sgirish break; 9244961713Sgirish } 9344961713Sgirish 9414ea4bb7Ssd if ((rs = npi_zcp_clear_istatus(handle)) != NPI_SUCCESS) 9514ea4bb7Ssd return (NXGE_ERROR | rs); 9644961713Sgirish if ((rs = npi_zcp_get_istatus(handle, &istatus)) != NPI_SUCCESS) 9744961713Sgirish return (NXGE_ERROR | rs); 9844961713Sgirish if ((rs = npi_zcp_iconfig(handle, INIT, ICFG_ZCP_ALL)) != NPI_SUCCESS) 9944961713Sgirish goto fail; 10044961713Sgirish 10144961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_zcp_init: port%d", portn)); 10244961713Sgirish return (NXGE_OK); 10344961713Sgirish 10444961713Sgirish fail: 10544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 10652ccf843Smisaki "nxge_zcp_init: Fail to initialize ZCP Port #%d\n", portn)); 10744961713Sgirish return (NXGE_ERROR | rs); 10844961713Sgirish } 10944961713Sgirish 11044961713Sgirish nxge_status_t 11144961713Sgirish nxge_zcp_handle_sys_errors(p_nxge_t nxgep) 11244961713Sgirish { 113a3c5bd6dSspeer npi_handle_t handle; 114a3c5bd6dSspeer npi_status_t rs = NPI_SUCCESS; 115a3c5bd6dSspeer p_nxge_zcp_stats_t statsp; 116a3c5bd6dSspeer uint8_t portn; 117a3c5bd6dSspeer zcp_iconfig_t istatus; 118a3c5bd6dSspeer boolean_t rxport_fatal = B_FALSE; 119a3c5bd6dSspeer nxge_status_t status = NXGE_OK; 12044961713Sgirish 12144961713Sgirish handle = nxgep->npi_handle; 12244961713Sgirish statsp = (p_nxge_zcp_stats_t)&nxgep->statsp->zcp_stats; 12344961713Sgirish portn = nxgep->mac.portnum; 12444961713Sgirish 12544961713Sgirish if ((rs = npi_zcp_get_istatus(handle, &istatus)) != NPI_SUCCESS) 12644961713Sgirish return (NXGE_ERROR | rs); 12744961713Sgirish 12844961713Sgirish if (istatus & ICFG_ZCP_RRFIFO_UNDERRUN) { 12944961713Sgirish statsp->rrfifo_underrun++; 130*b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0, 13152ccf843Smisaki NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN); 13244961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 13352ccf843Smisaki "nxge_zcp_err_evnts: rrfifo_underrun")); 13444961713Sgirish } 135a3c5bd6dSspeer 13644961713Sgirish if (istatus & ICFG_ZCP_RRFIFO_OVERRUN) { 13744961713Sgirish statsp->rrfifo_overrun++; 138*b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0, 13952ccf843Smisaki NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN); 14044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 14152ccf843Smisaki "nxge_zcp_err_evnts: buf_rrfifo_overrun")); 14244961713Sgirish } 143a3c5bd6dSspeer 14444961713Sgirish if (istatus & ICFG_ZCP_RSPFIFO_UNCORR_ERR) { 14544961713Sgirish statsp->rspfifo_uncorr_err++; 146*b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0, 14752ccf843Smisaki NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR); 14844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 14952ccf843Smisaki "nxge_zcp_err_evnts: rspfifo_uncorr_err")); 15044961713Sgirish } 151a3c5bd6dSspeer 15244961713Sgirish if (istatus & ICFG_ZCP_BUFFER_OVERFLOW) { 15344961713Sgirish statsp->buffer_overflow++; 154*b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0, 15552ccf843Smisaki NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW); 15644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 15752ccf843Smisaki "nxge_zcp_err_evnts: buffer_overflow")); 15844961713Sgirish rxport_fatal = B_TRUE; 15944961713Sgirish } 160a3c5bd6dSspeer 16144961713Sgirish if (istatus & ICFG_ZCP_STAT_TBL_PERR) { 16244961713Sgirish statsp->stat_tbl_perr++; 163*b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0, 16452ccf843Smisaki NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR); 16544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 16652ccf843Smisaki "nxge_zcp_err_evnts: stat_tbl_perr")); 16744961713Sgirish } 168a3c5bd6dSspeer 16944961713Sgirish if (istatus & ICFG_ZCP_DYN_TBL_PERR) { 17044961713Sgirish statsp->dyn_tbl_perr++; 171*b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0, 17252ccf843Smisaki NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR); 17344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 17452ccf843Smisaki "nxge_zcp_err_evnts: dyn_tbl_perr")); 17544961713Sgirish } 176a3c5bd6dSspeer 17744961713Sgirish if (istatus & ICFG_ZCP_BUF_TBL_PERR) { 17844961713Sgirish statsp->buf_tbl_perr++; 179*b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0, 18052ccf843Smisaki NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR); 18144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 18252ccf843Smisaki "nxge_zcp_err_evnts: buf_tbl_perr")); 18344961713Sgirish } 184a3c5bd6dSspeer 18544961713Sgirish if (istatus & ICFG_ZCP_TT_PROGRAM_ERR) { 18644961713Sgirish statsp->tt_program_err++; 187*b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0, 18852ccf843Smisaki NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR); 18944961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19052ccf843Smisaki "nxge_zcp_err_evnts: tt_program_err")); 19144961713Sgirish } 192a3c5bd6dSspeer 19344961713Sgirish if (istatus & ICFG_ZCP_RSP_TT_INDEX_ERR) { 19444961713Sgirish statsp->rsp_tt_index_err++; 195*b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0, 19652ccf843Smisaki NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR); 19744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 19852ccf843Smisaki "nxge_zcp_err_evnts: rsp_tt_index_err")); 19944961713Sgirish } 200a3c5bd6dSspeer 20144961713Sgirish if (istatus & ICFG_ZCP_SLV_TT_INDEX_ERR) { 20244961713Sgirish statsp->slv_tt_index_err++; 203*b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0, 20452ccf843Smisaki NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR); 20544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 20652ccf843Smisaki "nxge_zcp_err_evnts: slv_tt_index_err")); 20744961713Sgirish } 208a3c5bd6dSspeer 20944961713Sgirish if (istatus & ICFG_ZCP_TT_INDEX_ERR) { 21044961713Sgirish statsp->zcp_tt_index_err++; 211*b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0, 21252ccf843Smisaki NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR); 21344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 21452ccf843Smisaki "nxge_zcp_err_evnts: tt_index_err")); 21544961713Sgirish } 216a3c5bd6dSspeer 21744961713Sgirish if (((portn == 0) && (istatus & ICFG_ZCP_CFIFO_ECC0)) || 21852ccf843Smisaki ((portn == 1) && (istatus & ICFG_ZCP_CFIFO_ECC1)) || 21952ccf843Smisaki ((portn == 2) && (istatus & ICFG_ZCP_CFIFO_ECC2)) || 22052ccf843Smisaki ((portn == 3) && (istatus & ICFG_ZCP_CFIFO_ECC3))) { 22114ea4bb7Ssd boolean_t ue_ecc_valid; 22214ea4bb7Ssd 22314ea4bb7Ssd if ((status = nxge_ipp_eccue_valid_check(nxgep, 22452ccf843Smisaki &ue_ecc_valid)) != NXGE_OK) 22514ea4bb7Ssd return (status); 22614ea4bb7Ssd 22714ea4bb7Ssd if (ue_ecc_valid) { 22814ea4bb7Ssd statsp->cfifo_ecc++; 229*b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0, 23052ccf843Smisaki NXGE_FM_EREPORT_ZCP_CFIFO_ECC); 23114ea4bb7Ssd NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 23252ccf843Smisaki "nxge_zcp_err_evnts: port%d buf_cfifo_ecc", 23352ccf843Smisaki portn)); 23414ea4bb7Ssd rxport_fatal = B_TRUE; 23514ea4bb7Ssd } 23644961713Sgirish } 23744961713Sgirish 23844961713Sgirish /* 239a3c5bd6dSspeer * Making sure that error source is cleared if this is an injected 240a3c5bd6dSspeer * error. 24144961713Sgirish */ 24244961713Sgirish switch (portn) { 24344961713Sgirish case 0: 24444961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT0_REG, 0); 24544961713Sgirish break; 24644961713Sgirish case 1: 24744961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT1_REG, 0); 24844961713Sgirish break; 24944961713Sgirish case 2: 25044961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT2_REG, 0); 25144961713Sgirish break; 25244961713Sgirish case 3: 25344961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT3_REG, 0); 25444961713Sgirish break; 25544961713Sgirish } 25644961713Sgirish 25744961713Sgirish (void) npi_zcp_clear_istatus(handle); 25844961713Sgirish 25944961713Sgirish if (rxport_fatal) { 26044961713Sgirish NXGE_DEBUG_MSG((nxgep, IPP_CTL, 26152ccf843Smisaki " nxge_zcp_handle_sys_errors:" 26252ccf843Smisaki " fatal Error on Port #%d\n", portn)); 26344961713Sgirish status = nxge_zcp_fatal_err_recover(nxgep); 26444961713Sgirish if (status == NXGE_OK) { 26544961713Sgirish FM_SERVICE_RESTORED(nxgep); 26644961713Sgirish } 26744961713Sgirish } 26844961713Sgirish return (status); 26944961713Sgirish } 27044961713Sgirish 27144961713Sgirish void 27244961713Sgirish nxge_zcp_inject_err(p_nxge_t nxgep, uint32_t err_id) 27344961713Sgirish { 274a3c5bd6dSspeer zcp_int_stat_reg_t zcps; 275a3c5bd6dSspeer uint8_t portn = nxgep->mac.portnum; 276a3c5bd6dSspeer zcp_ecc_ctrl_t ecc_ctrl; 27744961713Sgirish 27844961713Sgirish switch (err_id) { 27944961713Sgirish case NXGE_FM_EREPORT_ZCP_CFIFO_ECC: 28044961713Sgirish ecc_ctrl.value = 0; 28144961713Sgirish ecc_ctrl.bits.w0.cor_dbl = 1; 28244961713Sgirish ecc_ctrl.bits.w0.cor_lst = 1; 28344961713Sgirish ecc_ctrl.bits.w0.cor_all = 0; 28444961713Sgirish switch (portn) { 28544961713Sgirish case 0: 28644961713Sgirish cmn_err(CE_NOTE, 28752ccf843Smisaki "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 28852ccf843Smisaki (unsigned long long) ecc_ctrl.value, portn); 28944961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, 29052ccf843Smisaki ZCP_CFIFO_ECC_PORT0_REG, 29152ccf843Smisaki ecc_ctrl.value); 29244961713Sgirish break; 29344961713Sgirish case 1: 29444961713Sgirish cmn_err(CE_NOTE, 29552ccf843Smisaki "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 29652ccf843Smisaki (unsigned long long) ecc_ctrl.value, portn); 29744961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, 29852ccf843Smisaki ZCP_CFIFO_ECC_PORT1_REG, 29952ccf843Smisaki ecc_ctrl.value); 30044961713Sgirish break; 30144961713Sgirish case 2: 30244961713Sgirish cmn_err(CE_NOTE, 30352ccf843Smisaki "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 30452ccf843Smisaki (unsigned long long) ecc_ctrl.value, portn); 30544961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, 30652ccf843Smisaki ZCP_CFIFO_ECC_PORT2_REG, 30752ccf843Smisaki ecc_ctrl.value); 30844961713Sgirish break; 30944961713Sgirish case 3: 31044961713Sgirish cmn_err(CE_NOTE, 31152ccf843Smisaki "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 31252ccf843Smisaki (unsigned long long) ecc_ctrl.value, portn); 31344961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, 31452ccf843Smisaki ZCP_CFIFO_ECC_PORT3_REG, 31552ccf843Smisaki ecc_ctrl.value); 31644961713Sgirish break; 31744961713Sgirish } 31844961713Sgirish break; 319a3c5bd6dSspeer 32044961713Sgirish case NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN: 32144961713Sgirish case NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR: 32244961713Sgirish case NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR: 32344961713Sgirish case NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR: 32444961713Sgirish case NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR: 32544961713Sgirish case NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN: 32644961713Sgirish case NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW: 32744961713Sgirish case NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR: 32844961713Sgirish case NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR: 32944961713Sgirish case NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR: 33044961713Sgirish case NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR: 33144961713Sgirish NXGE_REG_RD64(nxgep->npi_handle, ZCP_INT_STAT_TEST_REG, 33252ccf843Smisaki &zcps.value); 33344961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN) 33444961713Sgirish zcps.bits.ldw.rrfifo_urun = 1; 33544961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR) 33644961713Sgirish zcps.bits.ldw.rspfifo_uc_err = 1; 33744961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR) 33844961713Sgirish zcps.bits.ldw.stat_tbl_perr = 1; 33944961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR) 34044961713Sgirish zcps.bits.ldw.dyn_tbl_perr = 1; 34144961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR) 34244961713Sgirish zcps.bits.ldw.buf_tbl_perr = 1; 34344961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_CFIFO_ECC) { 34444961713Sgirish switch (portn) { 34544961713Sgirish case 0: 34644961713Sgirish zcps.bits.ldw.cfifo_ecc0 = 1; 34744961713Sgirish break; 34844961713Sgirish case 1: 34944961713Sgirish zcps.bits.ldw.cfifo_ecc1 = 1; 35044961713Sgirish break; 35144961713Sgirish case 2: 35244961713Sgirish zcps.bits.ldw.cfifo_ecc2 = 1; 35344961713Sgirish break; 35444961713Sgirish case 3: 35544961713Sgirish zcps.bits.ldw.cfifo_ecc3 = 1; 35644961713Sgirish break; 35744961713Sgirish } 35844961713Sgirish } 35973ff8cc6SToomas Soome /* FALLTHROUGH */ 360a3c5bd6dSspeer 361a3c5bd6dSspeer default: 36244961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN) 36344961713Sgirish zcps.bits.ldw.rrfifo_orun = 1; 36444961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW) 36544961713Sgirish zcps.bits.ldw.buf_overflow = 1; 36644961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR) 36744961713Sgirish zcps.bits.ldw.tt_tbl_perr = 1; 36844961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR) 36944961713Sgirish zcps.bits.ldw.rsp_tt_index_err = 1; 37044961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR) 37144961713Sgirish zcps.bits.ldw.slv_tt_index_err = 1; 37244961713Sgirish if (err_id == NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR) 37344961713Sgirish zcps.bits.ldw.zcp_tt_index_err = 1; 374adfcba55Sjoycey #if defined(__i386) 375adfcba55Sjoycey cmn_err(CE_NOTE, "!Write 0x%llx to ZCP_INT_STAT_TEST_REG\n", 37652ccf843Smisaki zcps.value); 377adfcba55Sjoycey #else 37844961713Sgirish cmn_err(CE_NOTE, "!Write 0x%lx to ZCP_INT_STAT_TEST_REG\n", 37952ccf843Smisaki zcps.value); 380adfcba55Sjoycey #endif 38144961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, ZCP_INT_STAT_TEST_REG, 38252ccf843Smisaki zcps.value); 38344961713Sgirish break; 38444961713Sgirish } 38544961713Sgirish } 38644961713Sgirish 38744961713Sgirish nxge_status_t 38844961713Sgirish nxge_zcp_fatal_err_recover(p_nxge_t nxgep) 38944961713Sgirish { 390a3c5bd6dSspeer npi_handle_t handle; 391a3c5bd6dSspeer npi_status_t rs = NPI_SUCCESS; 392a3c5bd6dSspeer nxge_status_t status = NXGE_OK; 393a3c5bd6dSspeer uint8_t portn; 394a3c5bd6dSspeer zcp_ram_unit_t w_data; 395a3c5bd6dSspeer zcp_ram_unit_t r_data; 396a3c5bd6dSspeer uint32_t cfifo_depth; 397a3c5bd6dSspeer int i; 39844961713Sgirish 39944961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_zcp_fatal_err_recover")); 40044961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 40152ccf843Smisaki "Recovering from RxPort error...")); 40244961713Sgirish 40344961713Sgirish handle = nxgep->npi_handle; 40444961713Sgirish portn = nxgep->mac.portnum; 40544961713Sgirish 40644961713Sgirish /* Disable RxMAC */ 40744961713Sgirish if (nxge_rx_mac_disable(nxgep) != NXGE_OK) 40844961713Sgirish goto fail; 40944961713Sgirish 41044961713Sgirish /* Make sure source is clear if this is an injected error */ 41144961713Sgirish switch (portn) { 41244961713Sgirish case 0: 41344961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT0_REG, 0); 41444961713Sgirish break; 41544961713Sgirish case 1: 41644961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT1_REG, 0); 41744961713Sgirish break; 41844961713Sgirish case 2: 41944961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT2_REG, 0); 42044961713Sgirish break; 42144961713Sgirish case 3: 42244961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT3_REG, 0); 42344961713Sgirish break; 42444961713Sgirish } 42544961713Sgirish 42644961713Sgirish /* Clear up CFIFO */ 42759ac0c16Sdavemq if (nxgep->niu_type == N2_NIU) { 42859ac0c16Sdavemq cfifo_depth = ZCP_NIU_CFIFO_DEPTH; 4292e59129aSraghus } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 43044961713Sgirish if (portn < 2) 43144961713Sgirish cfifo_depth = ZCP_P0_P1_CFIFO_DEPTH; 43244961713Sgirish else 43344961713Sgirish cfifo_depth = ZCP_P2_P3_CFIFO_DEPTH; 43459ac0c16Sdavemq } else { 43559ac0c16Sdavemq goto fail; 43659ac0c16Sdavemq } 437a3c5bd6dSspeer 43844961713Sgirish w_data.w0 = 0; 43944961713Sgirish w_data.w1 = 0; 44044961713Sgirish w_data.w2 = 0; 44144961713Sgirish w_data.w3 = 0; 44244961713Sgirish w_data.w4 = 0; 443a3c5bd6dSspeer 44444961713Sgirish for (i = 0; i < cfifo_depth; i++) { 445a3c5bd6dSspeer if (npi_zcp_tt_cfifo_entry(handle, OP_SET, 44652ccf843Smisaki portn, i, &w_data) != NPI_SUCCESS) 44744961713Sgirish goto fail; 448a3c5bd6dSspeer if (npi_zcp_tt_cfifo_entry(handle, OP_GET, 44952ccf843Smisaki portn, i, &r_data) != NPI_SUCCESS) 45044961713Sgirish goto fail; 45144961713Sgirish } 45244961713Sgirish 45344961713Sgirish /* When recovering from ZCP, RxDMA channel resets are not necessary */ 45444961713Sgirish /* Reset ZCP CFIFO */ 45544961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset ZCP CFIFO...", portn)); 45644961713Sgirish if ((rs = npi_zcp_rest_cfifo_port(handle, portn)) != NPI_SUCCESS) 45744961713Sgirish goto fail; 45844961713Sgirish 45944961713Sgirish /* Reset IPP */ 46044961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset IPP...", portn)); 46144961713Sgirish if ((rs = npi_ipp_reset(handle, portn)) != NPI_SUCCESS) 46244961713Sgirish goto fail; 46344961713Sgirish 46444961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset RxMAC...", portn)); 46544961713Sgirish if (nxge_rx_mac_reset(nxgep) != NXGE_OK) 46644961713Sgirish goto fail; 46744961713Sgirish 46844961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Initialize RxMAC...", portn)); 46944961713Sgirish if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 47044961713Sgirish goto fail; 47144961713Sgirish 47244961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Enable RxMAC...", portn)); 47344961713Sgirish if (nxge_rx_mac_enable(nxgep) != NXGE_OK) 47444961713Sgirish goto fail; 47544961713Sgirish 47644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 47752ccf843Smisaki "Recovery Sucessful, RxPort Restored")); 47844961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_zcp_fatal_err_recover")); 47944961713Sgirish return (NXGE_OK); 48044961713Sgirish fail: 48144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Recovery failed")); 48244961713Sgirish return (status | rs); 48344961713Sgirish } 484