16f45ec7bSml29623 /* 26f45ec7bSml29623 * CDDL HEADER START 36f45ec7bSml29623 * 46f45ec7bSml29623 * The contents of this file are subject to the terms of the 56f45ec7bSml29623 * Common Development and Distribution License (the "License"). 66f45ec7bSml29623 * You may not use this file except in compliance with the License. 76f45ec7bSml29623 * 86f45ec7bSml29623 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96f45ec7bSml29623 * or http://www.opensolaris.org/os/licensing. 106f45ec7bSml29623 * See the License for the specific language governing permissions 116f45ec7bSml29623 * and limitations under the License. 126f45ec7bSml29623 * 136f45ec7bSml29623 * When distributing Covered Code, include this CDDL HEADER in each 146f45ec7bSml29623 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156f45ec7bSml29623 * If applicable, add the following below this CDDL HEADER, with the 166f45ec7bSml29623 * fields enclosed by brackets "[]" replaced with your own identifying 176f45ec7bSml29623 * information: Portions Copyright [yyyy] [name of copyright owner] 186f45ec7bSml29623 * 196f45ec7bSml29623 * CDDL HEADER END 206f45ec7bSml29623 */ 216f45ec7bSml29623 /* 22*52ccf843Smisaki * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 236f45ec7bSml29623 * Use is subject to license terms. 246f45ec7bSml29623 */ 256f45ec7bSml29623 266f45ec7bSml29623 #pragma ident "%Z%%M% %I% %E% SMI" 276f45ec7bSml29623 286f45ec7bSml29623 #include <nxge_impl.h> 296f45ec7bSml29623 #include <nxge_zcp.h> 306f45ec7bSml29623 #include <nxge_ipp.h> 316f45ec7bSml29623 326f45ec7bSml29623 nxge_status_t 336f45ec7bSml29623 nxge_zcp_init(p_nxge_t nxgep) 346f45ec7bSml29623 { 356f45ec7bSml29623 uint8_t portn; 366f45ec7bSml29623 npi_handle_t handle; 376f45ec7bSml29623 zcp_iconfig_t istatus; 386f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 396f45ec7bSml29623 int i; 406f45ec7bSml29623 zcp_ram_unit_t w_data; 416f45ec7bSml29623 zcp_ram_unit_t r_data; 426f45ec7bSml29623 uint32_t cfifo_depth; 436f45ec7bSml29623 446f45ec7bSml29623 handle = nxgep->npi_handle; 456f45ec7bSml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num); 466f45ec7bSml29623 4759ac0c16Sdavemq if (nxgep->niu_type == N2_NIU) { 4859ac0c16Sdavemq cfifo_depth = ZCP_NIU_CFIFO_DEPTH; 492e59129aSraghus } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 506f45ec7bSml29623 if (portn < 2) 516f45ec7bSml29623 cfifo_depth = ZCP_P0_P1_CFIFO_DEPTH; 526f45ec7bSml29623 else 536f45ec7bSml29623 cfifo_depth = ZCP_P2_P3_CFIFO_DEPTH; 5459ac0c16Sdavemq } else { 5559ac0c16Sdavemq goto fail; 5659ac0c16Sdavemq } 576f45ec7bSml29623 586f45ec7bSml29623 /* Clean up CFIFO */ 596f45ec7bSml29623 w_data.w0 = 0; 606f45ec7bSml29623 w_data.w1 = 0; 616f45ec7bSml29623 w_data.w2 = 0; 626f45ec7bSml29623 w_data.w3 = 0; 636f45ec7bSml29623 w_data.w4 = 0; 646f45ec7bSml29623 656f45ec7bSml29623 for (i = 0; i < cfifo_depth; i++) { 666f45ec7bSml29623 if (npi_zcp_tt_cfifo_entry(handle, OP_SET, 676f45ec7bSml29623 portn, i, &w_data) != NPI_SUCCESS) 686f45ec7bSml29623 goto fail; 696f45ec7bSml29623 if (npi_zcp_tt_cfifo_entry(handle, OP_GET, 706f45ec7bSml29623 portn, i, &r_data) != NPI_SUCCESS) 716f45ec7bSml29623 goto fail; 726f45ec7bSml29623 } 736f45ec7bSml29623 746f45ec7bSml29623 if (npi_zcp_rest_cfifo_port(handle, portn) != NPI_SUCCESS) 756f45ec7bSml29623 goto fail; 766f45ec7bSml29623 776f45ec7bSml29623 /* 786f45ec7bSml29623 * Making sure that error source is cleared if this is an injected 796f45ec7bSml29623 * error. 806f45ec7bSml29623 */ 816f45ec7bSml29623 switch (portn) { 826f45ec7bSml29623 case 0: 836f45ec7bSml29623 NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT0_REG, 0); 846f45ec7bSml29623 break; 856f45ec7bSml29623 case 1: 866f45ec7bSml29623 NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT1_REG, 0); 876f45ec7bSml29623 break; 886f45ec7bSml29623 case 2: 896f45ec7bSml29623 NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT2_REG, 0); 906f45ec7bSml29623 break; 916f45ec7bSml29623 case 3: 926f45ec7bSml29623 NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT3_REG, 0); 936f45ec7bSml29623 break; 946f45ec7bSml29623 } 956f45ec7bSml29623 966f45ec7bSml29623 if ((rs = npi_zcp_clear_istatus(handle)) != NPI_SUCCESS) 976f45ec7bSml29623 return (NXGE_ERROR | rs); 986f45ec7bSml29623 if ((rs = npi_zcp_get_istatus(handle, &istatus)) != NPI_SUCCESS) 996f45ec7bSml29623 return (NXGE_ERROR | rs); 1006f45ec7bSml29623 if ((rs = npi_zcp_iconfig(handle, INIT, ICFG_ZCP_ALL)) != NPI_SUCCESS) 1016f45ec7bSml29623 goto fail; 1026f45ec7bSml29623 1036f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_zcp_init: port%d", portn)); 1046f45ec7bSml29623 return (NXGE_OK); 1056f45ec7bSml29623 1066f45ec7bSml29623 fail: 1076f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1086f45ec7bSml29623 "nxge_zcp_init: Fail to initialize ZCP Port #%d\n", portn)); 1096f45ec7bSml29623 return (NXGE_ERROR | rs); 1106f45ec7bSml29623 } 1116f45ec7bSml29623 1126f45ec7bSml29623 nxge_status_t 1136f45ec7bSml29623 nxge_zcp_handle_sys_errors(p_nxge_t nxgep) 1146f45ec7bSml29623 { 1156f45ec7bSml29623 npi_handle_t handle; 1166f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 1176f45ec7bSml29623 p_nxge_zcp_stats_t statsp; 1186f45ec7bSml29623 uint8_t portn; 1196f45ec7bSml29623 zcp_iconfig_t istatus; 1206f45ec7bSml29623 boolean_t rxport_fatal = B_FALSE; 1216f45ec7bSml29623 nxge_status_t status = NXGE_OK; 1226f45ec7bSml29623 1236f45ec7bSml29623 handle = nxgep->npi_handle; 1246f45ec7bSml29623 statsp = (p_nxge_zcp_stats_t)&nxgep->statsp->zcp_stats; 1256f45ec7bSml29623 portn = nxgep->mac.portnum; 1266f45ec7bSml29623 1276f45ec7bSml29623 if ((rs = npi_zcp_get_istatus(handle, &istatus)) != NPI_SUCCESS) 1286f45ec7bSml29623 return (NXGE_ERROR | rs); 1296f45ec7bSml29623 1306f45ec7bSml29623 if (istatus & ICFG_ZCP_RRFIFO_UNDERRUN) { 1316f45ec7bSml29623 statsp->rrfifo_underrun++; 1326f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 1336f45ec7bSml29623 NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN); 1346f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1356f45ec7bSml29623 "nxge_zcp_err_evnts: rrfifo_underrun")); 1366f45ec7bSml29623 } 1376f45ec7bSml29623 1386f45ec7bSml29623 if (istatus & ICFG_ZCP_RRFIFO_OVERRUN) { 1396f45ec7bSml29623 statsp->rrfifo_overrun++; 1406f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 1416f45ec7bSml29623 NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN); 1426f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1436f45ec7bSml29623 "nxge_zcp_err_evnts: buf_rrfifo_overrun")); 1446f45ec7bSml29623 } 1456f45ec7bSml29623 1466f45ec7bSml29623 if (istatus & ICFG_ZCP_RSPFIFO_UNCORR_ERR) { 1476f45ec7bSml29623 statsp->rspfifo_uncorr_err++; 1486f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 1496f45ec7bSml29623 NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR); 1506f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1516f45ec7bSml29623 "nxge_zcp_err_evnts: rspfifo_uncorr_err")); 1526f45ec7bSml29623 } 1536f45ec7bSml29623 1546f45ec7bSml29623 if (istatus & ICFG_ZCP_BUFFER_OVERFLOW) { 1556f45ec7bSml29623 statsp->buffer_overflow++; 1566f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 1576f45ec7bSml29623 NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW); 1586f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1596f45ec7bSml29623 "nxge_zcp_err_evnts: buffer_overflow")); 1606f45ec7bSml29623 rxport_fatal = B_TRUE; 1616f45ec7bSml29623 } 1626f45ec7bSml29623 1636f45ec7bSml29623 if (istatus & ICFG_ZCP_STAT_TBL_PERR) { 1646f45ec7bSml29623 statsp->stat_tbl_perr++; 1656f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 1666f45ec7bSml29623 NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR); 1676f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1686f45ec7bSml29623 "nxge_zcp_err_evnts: stat_tbl_perr")); 1696f45ec7bSml29623 } 1706f45ec7bSml29623 1716f45ec7bSml29623 if (istatus & ICFG_ZCP_DYN_TBL_PERR) { 1726f45ec7bSml29623 statsp->dyn_tbl_perr++; 1736f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 1746f45ec7bSml29623 NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR); 1756f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1766f45ec7bSml29623 "nxge_zcp_err_evnts: dyn_tbl_perr")); 1776f45ec7bSml29623 } 1786f45ec7bSml29623 1796f45ec7bSml29623 if (istatus & ICFG_ZCP_BUF_TBL_PERR) { 1806f45ec7bSml29623 statsp->buf_tbl_perr++; 1816f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 1826f45ec7bSml29623 NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR); 1836f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1846f45ec7bSml29623 "nxge_zcp_err_evnts: buf_tbl_perr")); 1856f45ec7bSml29623 } 1866f45ec7bSml29623 1876f45ec7bSml29623 if (istatus & ICFG_ZCP_TT_PROGRAM_ERR) { 1886f45ec7bSml29623 statsp->tt_program_err++; 1896f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 1906f45ec7bSml29623 NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR); 1916f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1926f45ec7bSml29623 "nxge_zcp_err_evnts: tt_program_err")); 1936f45ec7bSml29623 } 1946f45ec7bSml29623 1956f45ec7bSml29623 if (istatus & ICFG_ZCP_RSP_TT_INDEX_ERR) { 1966f45ec7bSml29623 statsp->rsp_tt_index_err++; 1976f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 1986f45ec7bSml29623 NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR); 1996f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2006f45ec7bSml29623 "nxge_zcp_err_evnts: rsp_tt_index_err")); 2016f45ec7bSml29623 } 2026f45ec7bSml29623 2036f45ec7bSml29623 if (istatus & ICFG_ZCP_SLV_TT_INDEX_ERR) { 2046f45ec7bSml29623 statsp->slv_tt_index_err++; 2056f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2066f45ec7bSml29623 NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR); 2076f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2086f45ec7bSml29623 "nxge_zcp_err_evnts: slv_tt_index_err")); 2096f45ec7bSml29623 } 2106f45ec7bSml29623 2116f45ec7bSml29623 if (istatus & ICFG_ZCP_TT_INDEX_ERR) { 2126f45ec7bSml29623 statsp->zcp_tt_index_err++; 2136f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2146f45ec7bSml29623 NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR); 2156f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2166f45ec7bSml29623 "nxge_zcp_err_evnts: tt_index_err")); 2176f45ec7bSml29623 } 2186f45ec7bSml29623 2196f45ec7bSml29623 if (((portn == 0) && (istatus & ICFG_ZCP_CFIFO_ECC0)) || 2206f45ec7bSml29623 ((portn == 1) && (istatus & ICFG_ZCP_CFIFO_ECC1)) || 2216f45ec7bSml29623 ((portn == 2) && (istatus & ICFG_ZCP_CFIFO_ECC2)) || 2226f45ec7bSml29623 ((portn == 3) && (istatus & ICFG_ZCP_CFIFO_ECC3))) { 2236f45ec7bSml29623 boolean_t ue_ecc_valid; 2246f45ec7bSml29623 2256f45ec7bSml29623 if ((status = nxge_ipp_eccue_valid_check(nxgep, 2266f45ec7bSml29623 &ue_ecc_valid)) != NXGE_OK) 2276f45ec7bSml29623 return (status); 2286f45ec7bSml29623 2296f45ec7bSml29623 if (ue_ecc_valid) { 2306f45ec7bSml29623 statsp->cfifo_ecc++; 2316f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 2326f45ec7bSml29623 NXGE_FM_EREPORT_ZCP_CFIFO_ECC); 2336f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2346f45ec7bSml29623 "nxge_zcp_err_evnts: port%d buf_cfifo_ecc", 2356f45ec7bSml29623 portn)); 2366f45ec7bSml29623 rxport_fatal = B_TRUE; 2376f45ec7bSml29623 } 2386f45ec7bSml29623 } 2396f45ec7bSml29623 2406f45ec7bSml29623 /* 2416f45ec7bSml29623 * Making sure that error source is cleared if this is an injected 2426f45ec7bSml29623 * error. 2436f45ec7bSml29623 */ 2446f45ec7bSml29623 switch (portn) { 2456f45ec7bSml29623 case 0: 2466f45ec7bSml29623 NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT0_REG, 0); 2476f45ec7bSml29623 break; 2486f45ec7bSml29623 case 1: 2496f45ec7bSml29623 NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT1_REG, 0); 2506f45ec7bSml29623 break; 2516f45ec7bSml29623 case 2: 2526f45ec7bSml29623 NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT2_REG, 0); 2536f45ec7bSml29623 break; 2546f45ec7bSml29623 case 3: 2556f45ec7bSml29623 NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT3_REG, 0); 2566f45ec7bSml29623 break; 2576f45ec7bSml29623 } 2586f45ec7bSml29623 2596f45ec7bSml29623 (void) npi_zcp_clear_istatus(handle); 2606f45ec7bSml29623 2616f45ec7bSml29623 if (rxport_fatal) { 2626f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL, 2636f45ec7bSml29623 " nxge_zcp_handle_sys_errors:" 2646f45ec7bSml29623 " fatal Error on Port #%d\n", portn)); 2656f45ec7bSml29623 status = nxge_zcp_fatal_err_recover(nxgep); 2666f45ec7bSml29623 if (status == NXGE_OK) { 2676f45ec7bSml29623 FM_SERVICE_RESTORED(nxgep); 2686f45ec7bSml29623 } 2696f45ec7bSml29623 } 2706f45ec7bSml29623 return (status); 2716f45ec7bSml29623 } 2726f45ec7bSml29623 2736f45ec7bSml29623 void 2746f45ec7bSml29623 nxge_zcp_inject_err(p_nxge_t nxgep, uint32_t err_id) 2756f45ec7bSml29623 { 2766f45ec7bSml29623 zcp_int_stat_reg_t zcps; 2776f45ec7bSml29623 uint8_t portn = nxgep->mac.portnum; 2786f45ec7bSml29623 zcp_ecc_ctrl_t ecc_ctrl; 2796f45ec7bSml29623 2806f45ec7bSml29623 switch (err_id) { 2816f45ec7bSml29623 case NXGE_FM_EREPORT_ZCP_CFIFO_ECC: 2826f45ec7bSml29623 ecc_ctrl.value = 0; 2836f45ec7bSml29623 ecc_ctrl.bits.w0.cor_dbl = 1; 2846f45ec7bSml29623 ecc_ctrl.bits.w0.cor_lst = 1; 2856f45ec7bSml29623 ecc_ctrl.bits.w0.cor_all = 0; 2866f45ec7bSml29623 switch (portn) { 2876f45ec7bSml29623 case 0: 2886f45ec7bSml29623 cmn_err(CE_NOTE, 2896f45ec7bSml29623 "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 2906f45ec7bSml29623 (unsigned long long) ecc_ctrl.value, portn); 2916f45ec7bSml29623 NXGE_REG_WR64(nxgep->npi_handle, 2926f45ec7bSml29623 ZCP_CFIFO_ECC_PORT0_REG, 2936f45ec7bSml29623 ecc_ctrl.value); 2946f45ec7bSml29623 break; 2956f45ec7bSml29623 case 1: 2966f45ec7bSml29623 cmn_err(CE_NOTE, 2976f45ec7bSml29623 "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 2986f45ec7bSml29623 (unsigned long long) ecc_ctrl.value, portn); 2996f45ec7bSml29623 NXGE_REG_WR64(nxgep->npi_handle, 3006f45ec7bSml29623 ZCP_CFIFO_ECC_PORT1_REG, 3016f45ec7bSml29623 ecc_ctrl.value); 3026f45ec7bSml29623 break; 3036f45ec7bSml29623 case 2: 3046f45ec7bSml29623 cmn_err(CE_NOTE, 3056f45ec7bSml29623 "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 3066f45ec7bSml29623 (unsigned long long) ecc_ctrl.value, portn); 3076f45ec7bSml29623 NXGE_REG_WR64(nxgep->npi_handle, 3086f45ec7bSml29623 ZCP_CFIFO_ECC_PORT2_REG, 3096f45ec7bSml29623 ecc_ctrl.value); 3106f45ec7bSml29623 break; 3116f45ec7bSml29623 case 3: 3126f45ec7bSml29623 cmn_err(CE_NOTE, 3136f45ec7bSml29623 "!Write 0x%llx to port%d ZCP_CFIFO_ECC_PORT\n", 3146f45ec7bSml29623 (unsigned long long) ecc_ctrl.value, portn); 3156f45ec7bSml29623 NXGE_REG_WR64(nxgep->npi_handle, 3166f45ec7bSml29623 ZCP_CFIFO_ECC_PORT3_REG, 3176f45ec7bSml29623 ecc_ctrl.value); 3186f45ec7bSml29623 break; 3196f45ec7bSml29623 } 3206f45ec7bSml29623 break; 3216f45ec7bSml29623 3226f45ec7bSml29623 case NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN: 3236f45ec7bSml29623 case NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR: 3246f45ec7bSml29623 case NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR: 3256f45ec7bSml29623 case NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR: 3266f45ec7bSml29623 case NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR: 3276f45ec7bSml29623 case NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN: 3286f45ec7bSml29623 case NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW: 3296f45ec7bSml29623 case NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR: 3306f45ec7bSml29623 case NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR: 3316f45ec7bSml29623 case NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR: 3326f45ec7bSml29623 case NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR: 3336f45ec7bSml29623 NXGE_REG_RD64(nxgep->npi_handle, ZCP_INT_STAT_TEST_REG, 3346f45ec7bSml29623 &zcps.value); 3356f45ec7bSml29623 if (err_id == NXGE_FM_EREPORT_ZCP_RRFIFO_UNDERRUN) 3366f45ec7bSml29623 zcps.bits.ldw.rrfifo_urun = 1; 3376f45ec7bSml29623 if (err_id == NXGE_FM_EREPORT_ZCP_RSPFIFO_UNCORR_ERR) 3386f45ec7bSml29623 zcps.bits.ldw.rspfifo_uc_err = 1; 3396f45ec7bSml29623 if (err_id == NXGE_FM_EREPORT_ZCP_STAT_TBL_PERR) 3406f45ec7bSml29623 zcps.bits.ldw.stat_tbl_perr = 1; 3416f45ec7bSml29623 if (err_id == NXGE_FM_EREPORT_ZCP_DYN_TBL_PERR) 3426f45ec7bSml29623 zcps.bits.ldw.dyn_tbl_perr = 1; 3436f45ec7bSml29623 if (err_id == NXGE_FM_EREPORT_ZCP_BUF_TBL_PERR) 3446f45ec7bSml29623 zcps.bits.ldw.buf_tbl_perr = 1; 3456f45ec7bSml29623 if (err_id == NXGE_FM_EREPORT_ZCP_CFIFO_ECC) { 3466f45ec7bSml29623 switch (portn) { 3476f45ec7bSml29623 case 0: 3486f45ec7bSml29623 zcps.bits.ldw.cfifo_ecc0 = 1; 3496f45ec7bSml29623 break; 3506f45ec7bSml29623 case 1: 3516f45ec7bSml29623 zcps.bits.ldw.cfifo_ecc1 = 1; 3526f45ec7bSml29623 break; 3536f45ec7bSml29623 case 2: 3546f45ec7bSml29623 zcps.bits.ldw.cfifo_ecc2 = 1; 3556f45ec7bSml29623 break; 3566f45ec7bSml29623 case 3: 3576f45ec7bSml29623 zcps.bits.ldw.cfifo_ecc3 = 1; 3586f45ec7bSml29623 break; 3596f45ec7bSml29623 } 3606f45ec7bSml29623 } 3616f45ec7bSml29623 3626f45ec7bSml29623 default: 3636f45ec7bSml29623 if (err_id == NXGE_FM_EREPORT_ZCP_RRFIFO_OVERRUN) 3646f45ec7bSml29623 zcps.bits.ldw.rrfifo_orun = 1; 3656f45ec7bSml29623 if (err_id == NXGE_FM_EREPORT_ZCP_BUFFER_OVERFLOW) 3666f45ec7bSml29623 zcps.bits.ldw.buf_overflow = 1; 3676f45ec7bSml29623 if (err_id == NXGE_FM_EREPORT_ZCP_TT_PROGRAM_ERR) 3686f45ec7bSml29623 zcps.bits.ldw.tt_tbl_perr = 1; 3696f45ec7bSml29623 if (err_id == NXGE_FM_EREPORT_ZCP_RSP_TT_INDEX_ERR) 3706f45ec7bSml29623 zcps.bits.ldw.rsp_tt_index_err = 1; 3716f45ec7bSml29623 if (err_id == NXGE_FM_EREPORT_ZCP_SLV_TT_INDEX_ERR) 3726f45ec7bSml29623 zcps.bits.ldw.slv_tt_index_err = 1; 3736f45ec7bSml29623 if (err_id == NXGE_FM_EREPORT_ZCP_TT_INDEX_ERR) 3746f45ec7bSml29623 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", 377adfcba55Sjoycey zcps.value); 378adfcba55Sjoycey #else 3796f45ec7bSml29623 cmn_err(CE_NOTE, "!Write 0x%lx to ZCP_INT_STAT_TEST_REG\n", 3806f45ec7bSml29623 zcps.value); 381adfcba55Sjoycey #endif 3826f45ec7bSml29623 NXGE_REG_WR64(nxgep->npi_handle, ZCP_INT_STAT_TEST_REG, 3836f45ec7bSml29623 zcps.value); 3846f45ec7bSml29623 break; 3856f45ec7bSml29623 } 3866f45ec7bSml29623 } 3876f45ec7bSml29623 3886f45ec7bSml29623 nxge_status_t 3896f45ec7bSml29623 nxge_zcp_fatal_err_recover(p_nxge_t nxgep) 3906f45ec7bSml29623 { 3916f45ec7bSml29623 npi_handle_t handle; 3926f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS; 3936f45ec7bSml29623 nxge_status_t status = NXGE_OK; 3946f45ec7bSml29623 uint8_t portn; 3956f45ec7bSml29623 zcp_ram_unit_t w_data; 3966f45ec7bSml29623 zcp_ram_unit_t r_data; 3976f45ec7bSml29623 uint32_t cfifo_depth; 3986f45ec7bSml29623 int i; 3996f45ec7bSml29623 4006f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_zcp_fatal_err_recover")); 4016f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4026f45ec7bSml29623 "Recovering from RxPort error...")); 4036f45ec7bSml29623 4046f45ec7bSml29623 handle = nxgep->npi_handle; 4056f45ec7bSml29623 portn = nxgep->mac.portnum; 4066f45ec7bSml29623 4076f45ec7bSml29623 /* Disable RxMAC */ 4086f45ec7bSml29623 if (nxge_rx_mac_disable(nxgep) != NXGE_OK) 4096f45ec7bSml29623 goto fail; 4106f45ec7bSml29623 4116f45ec7bSml29623 /* Make sure source is clear if this is an injected error */ 4126f45ec7bSml29623 switch (portn) { 4136f45ec7bSml29623 case 0: 4146f45ec7bSml29623 NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT0_REG, 0); 4156f45ec7bSml29623 break; 4166f45ec7bSml29623 case 1: 4176f45ec7bSml29623 NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT1_REG, 0); 4186f45ec7bSml29623 break; 4196f45ec7bSml29623 case 2: 4206f45ec7bSml29623 NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT2_REG, 0); 4216f45ec7bSml29623 break; 4226f45ec7bSml29623 case 3: 4236f45ec7bSml29623 NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT3_REG, 0); 4246f45ec7bSml29623 break; 4256f45ec7bSml29623 } 4266f45ec7bSml29623 4276f45ec7bSml29623 /* 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)) { 4316f45ec7bSml29623 if (portn < 2) 4326f45ec7bSml29623 cfifo_depth = ZCP_P0_P1_CFIFO_DEPTH; 4336f45ec7bSml29623 else 4346f45ec7bSml29623 cfifo_depth = ZCP_P2_P3_CFIFO_DEPTH; 43559ac0c16Sdavemq } else { 43659ac0c16Sdavemq goto fail; 43759ac0c16Sdavemq } 4386f45ec7bSml29623 4396f45ec7bSml29623 w_data.w0 = 0; 4406f45ec7bSml29623 w_data.w1 = 0; 4416f45ec7bSml29623 w_data.w2 = 0; 4426f45ec7bSml29623 w_data.w3 = 0; 4436f45ec7bSml29623 w_data.w4 = 0; 4446f45ec7bSml29623 4456f45ec7bSml29623 for (i = 0; i < cfifo_depth; i++) { 4466f45ec7bSml29623 if (npi_zcp_tt_cfifo_entry(handle, OP_SET, 4476f45ec7bSml29623 portn, i, &w_data) != NPI_SUCCESS) 4486f45ec7bSml29623 goto fail; 4496f45ec7bSml29623 if (npi_zcp_tt_cfifo_entry(handle, OP_GET, 4506f45ec7bSml29623 portn, i, &r_data) != NPI_SUCCESS) 4516f45ec7bSml29623 goto fail; 4526f45ec7bSml29623 } 4536f45ec7bSml29623 4546f45ec7bSml29623 /* When recovering from ZCP, RxDMA channel resets are not necessary */ 4556f45ec7bSml29623 /* Reset ZCP CFIFO */ 4566f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset ZCP CFIFO...", portn)); 4576f45ec7bSml29623 if ((rs = npi_zcp_rest_cfifo_port(handle, portn)) != NPI_SUCCESS) 4586f45ec7bSml29623 goto fail; 4596f45ec7bSml29623 4606f45ec7bSml29623 /* Reset IPP */ 4616f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset IPP...", portn)); 4626f45ec7bSml29623 if ((rs = npi_ipp_reset(handle, portn)) != NPI_SUCCESS) 4636f45ec7bSml29623 goto fail; 4646f45ec7bSml29623 4656f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset RxMAC...", portn)); 4666f45ec7bSml29623 if (nxge_rx_mac_reset(nxgep) != NXGE_OK) 4676f45ec7bSml29623 goto fail; 4686f45ec7bSml29623 4696f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Initialize RxMAC...", portn)); 4706f45ec7bSml29623 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK) 4716f45ec7bSml29623 goto fail; 4726f45ec7bSml29623 4736f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Enable RxMAC...", portn)); 4746f45ec7bSml29623 if (nxge_rx_mac_enable(nxgep) != NXGE_OK) 4756f45ec7bSml29623 goto fail; 4766f45ec7bSml29623 4776f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 4786f45ec7bSml29623 "Recovery Sucessful, RxPort Restored")); 4796f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_zcp_fatal_err_recover")); 4806f45ec7bSml29623 return (NXGE_OK); 4816f45ec7bSml29623 fail: 4826f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Recovery failed")); 4836f45ec7bSml29623 return (status | rs); 4846f45ec7bSml29623 } 485