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
nxge_zcp_init(p_nxge_t nxgep)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
nxge_zcp_handle_sys_errors(p_nxge_t nxgep)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
nxge_zcp_inject_err(p_nxge_t nxgep,uint32_t err_id)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;
37444961713Sgirish cmn_err(CE_NOTE, "!Write 0x%lx to ZCP_INT_STAT_TEST_REG\n",
37552ccf843Smisaki zcps.value);
37644961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, ZCP_INT_STAT_TEST_REG,
37752ccf843Smisaki zcps.value);
37844961713Sgirish break;
37944961713Sgirish }
38044961713Sgirish }
38144961713Sgirish
38244961713Sgirish nxge_status_t
nxge_zcp_fatal_err_recover(p_nxge_t nxgep)38344961713Sgirish nxge_zcp_fatal_err_recover(p_nxge_t nxgep)
38444961713Sgirish {
385a3c5bd6dSspeer npi_handle_t handle;
386a3c5bd6dSspeer npi_status_t rs = NPI_SUCCESS;
387a3c5bd6dSspeer nxge_status_t status = NXGE_OK;
388a3c5bd6dSspeer uint8_t portn;
389a3c5bd6dSspeer zcp_ram_unit_t w_data;
390a3c5bd6dSspeer zcp_ram_unit_t r_data;
391a3c5bd6dSspeer uint32_t cfifo_depth;
392a3c5bd6dSspeer int i;
39344961713Sgirish
39444961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_zcp_fatal_err_recover"));
39544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
39652ccf843Smisaki "Recovering from RxPort error..."));
39744961713Sgirish
39844961713Sgirish handle = nxgep->npi_handle;
39944961713Sgirish portn = nxgep->mac.portnum;
40044961713Sgirish
40144961713Sgirish /* Disable RxMAC */
40244961713Sgirish if (nxge_rx_mac_disable(nxgep) != NXGE_OK)
40344961713Sgirish goto fail;
40444961713Sgirish
40544961713Sgirish /* Make sure source is clear if this is an injected error */
40644961713Sgirish switch (portn) {
40744961713Sgirish case 0:
40844961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT0_REG, 0);
40944961713Sgirish break;
41044961713Sgirish case 1:
41144961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT1_REG, 0);
41244961713Sgirish break;
41344961713Sgirish case 2:
41444961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT2_REG, 0);
41544961713Sgirish break;
41644961713Sgirish case 3:
41744961713Sgirish NXGE_REG_WR64(handle, ZCP_CFIFO_ECC_PORT3_REG, 0);
41844961713Sgirish break;
41944961713Sgirish }
42044961713Sgirish
42144961713Sgirish /* Clear up CFIFO */
42259ac0c16Sdavemq if (nxgep->niu_type == N2_NIU) {
42359ac0c16Sdavemq cfifo_depth = ZCP_NIU_CFIFO_DEPTH;
4242e59129aSraghus } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
42544961713Sgirish if (portn < 2)
42644961713Sgirish cfifo_depth = ZCP_P0_P1_CFIFO_DEPTH;
42744961713Sgirish else
42844961713Sgirish cfifo_depth = ZCP_P2_P3_CFIFO_DEPTH;
42959ac0c16Sdavemq } else {
43059ac0c16Sdavemq goto fail;
43159ac0c16Sdavemq }
432a3c5bd6dSspeer
43344961713Sgirish w_data.w0 = 0;
43444961713Sgirish w_data.w1 = 0;
43544961713Sgirish w_data.w2 = 0;
43644961713Sgirish w_data.w3 = 0;
43744961713Sgirish w_data.w4 = 0;
438a3c5bd6dSspeer
43944961713Sgirish for (i = 0; i < cfifo_depth; i++) {
440a3c5bd6dSspeer if (npi_zcp_tt_cfifo_entry(handle, OP_SET,
44152ccf843Smisaki portn, i, &w_data) != NPI_SUCCESS)
44244961713Sgirish goto fail;
443a3c5bd6dSspeer if (npi_zcp_tt_cfifo_entry(handle, OP_GET,
44452ccf843Smisaki portn, i, &r_data) != NPI_SUCCESS)
44544961713Sgirish goto fail;
44644961713Sgirish }
44744961713Sgirish
44844961713Sgirish /* When recovering from ZCP, RxDMA channel resets are not necessary */
44944961713Sgirish /* Reset ZCP CFIFO */
45044961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset ZCP CFIFO...", portn));
45144961713Sgirish if ((rs = npi_zcp_rest_cfifo_port(handle, portn)) != NPI_SUCCESS)
45244961713Sgirish goto fail;
45344961713Sgirish
45444961713Sgirish /* Reset IPP */
45544961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset IPP...", portn));
45644961713Sgirish if ((rs = npi_ipp_reset(handle, portn)) != NPI_SUCCESS)
45744961713Sgirish goto fail;
45844961713Sgirish
45944961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Reset RxMAC...", portn));
46044961713Sgirish if (nxge_rx_mac_reset(nxgep) != NXGE_OK)
46144961713Sgirish goto fail;
46244961713Sgirish
46344961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Initialize RxMAC...", portn));
46444961713Sgirish if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
46544961713Sgirish goto fail;
46644961713Sgirish
46744961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "port%d Enable RxMAC...", portn));
46844961713Sgirish if (nxge_rx_mac_enable(nxgep) != NXGE_OK)
46944961713Sgirish goto fail;
47044961713Sgirish
47144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
47252ccf843Smisaki "Recovery Sucessful, RxPort Restored"));
47344961713Sgirish NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_zcp_fatal_err_recover"));
47444961713Sgirish return (NXGE_OK);
47544961713Sgirish fail:
47644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Recovery failed"));
47744961713Sgirish return (status | rs);
47844961713Sgirish }
479