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 /*
22678453a8Sspeer * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
2344961713Sgirish * Use is subject to license terms.
2444961713Sgirish */
2544961713Sgirish
2644961713Sgirish #include <sys/nxge/nxge_impl.h>
2744961713Sgirish #include <sys/nxge/nxge_txc.h>
2844961713Sgirish
2944961713Sgirish static nxge_status_t
3044961713Sgirish nxge_txc_handle_port_errors(p_nxge_t, uint32_t);
3144961713Sgirish static void
3244961713Sgirish nxge_txc_inject_port_err(uint8_t, txc_int_stat_dbg_t *,
33*86ef0a63SRichard Lowe uint8_t istats);
3444961713Sgirish extern nxge_status_t nxge_tx_port_fatal_err_recover(p_nxge_t);
3544961713Sgirish
3644961713Sgirish nxge_status_t
nxge_txc_init(p_nxge_t nxgep)3744961713Sgirish nxge_txc_init(p_nxge_t nxgep)
3844961713Sgirish {
3944961713Sgirish uint8_t port;
4044961713Sgirish npi_handle_t handle;
4144961713Sgirish npi_status_t rs = NPI_SUCCESS;
4244961713Sgirish
4344961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep);
4444961713Sgirish port = NXGE_GET_PORT_NUM(nxgep->function_num);
4544961713Sgirish
4644961713Sgirish NXGE_DEBUG_MSG((nxgep, TX_CTL, "==> nxge_txc_init: portn %d", port));
4744961713Sgirish
4844961713Sgirish /*
4944961713Sgirish * Enable the TXC controller.
5044961713Sgirish */
5144961713Sgirish if ((rs = npi_txc_global_enable(handle)) != NPI_SUCCESS) {
5244961713Sgirish goto fail;
5344961713Sgirish }
5444961713Sgirish
5544961713Sgirish /* Enable this port within the TXC. */
5644961713Sgirish if ((rs = npi_txc_port_enable(handle, port)) != NPI_SUCCESS) {
5744961713Sgirish goto fail;
5844961713Sgirish }
5944961713Sgirish
6044961713Sgirish /* Bind DMA channels to this port. */
6144961713Sgirish if ((rs = npi_txc_port_dma_enable(handle, port,
6252ccf843Smisaki TXDMA_PORT_BITMAP(nxgep))) != NPI_SUCCESS) {
6344961713Sgirish goto fail;
6444961713Sgirish }
6544961713Sgirish
6644961713Sgirish /* Unmask all TXC interrupts */
6744961713Sgirish npi_txc_global_imask_set(handle, port, 0);
6844961713Sgirish
6944961713Sgirish NXGE_DEBUG_MSG((nxgep, TX_CTL, "<== nxge_txc_init: portn %d", port));
7044961713Sgirish
7144961713Sgirish return (NXGE_OK);
7244961713Sgirish fail:
7344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
7452ccf843Smisaki "nxge_txc_init: Failed to initialize txc on port %d",
7552ccf843Smisaki port));
7644961713Sgirish
7744961713Sgirish return (NXGE_ERROR | rs);
7844961713Sgirish }
7944961713Sgirish
8044961713Sgirish nxge_status_t
nxge_txc_uninit(p_nxge_t nxgep)8144961713Sgirish nxge_txc_uninit(p_nxge_t nxgep)
8244961713Sgirish {
8344961713Sgirish uint8_t port;
8444961713Sgirish npi_handle_t handle;
8544961713Sgirish npi_status_t rs = NPI_SUCCESS;
8644961713Sgirish
8744961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep);
8844961713Sgirish port = NXGE_GET_PORT_NUM(nxgep->function_num);
8944961713Sgirish
9044961713Sgirish NXGE_DEBUG_MSG((nxgep, TX_CTL, "==> nxge_txc_uninit: portn %d", port));
9144961713Sgirish
9244961713Sgirish /*
9344961713Sgirish * disable the TXC controller.
9444961713Sgirish */
9544961713Sgirish if ((rs = npi_txc_global_disable(handle)) != NPI_SUCCESS) {
9644961713Sgirish goto fail;
9744961713Sgirish }
9844961713Sgirish
9944961713Sgirish /* disable this port within the TXC. */
10044961713Sgirish if ((rs = npi_txc_port_disable(handle, port)) != NPI_SUCCESS) {
10144961713Sgirish goto fail;
10244961713Sgirish }
10344961713Sgirish
10444961713Sgirish /* unbind DMA channels to this port. */
10544961713Sgirish if ((rs = npi_txc_port_dma_enable(handle, port, 0)) != NPI_SUCCESS) {
10644961713Sgirish goto fail;
10744961713Sgirish }
10844961713Sgirish
10944961713Sgirish NXGE_DEBUG_MSG((nxgep, TX_CTL, "<== nxge_txc_uninit: portn %d", port));
11044961713Sgirish
11144961713Sgirish return (NXGE_OK);
11244961713Sgirish fail:
11344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
11452ccf843Smisaki "nxge_txc_init: Failed to initialize txc on port %d",
11552ccf843Smisaki port));
11644961713Sgirish
11744961713Sgirish return (NXGE_ERROR | rs);
11844961713Sgirish }
11944961713Sgirish
120678453a8Sspeer /*
121678453a8Sspeer * nxge_txc_tdc_bind
122678453a8Sspeer *
123678453a8Sspeer * Bind a TDC to a port.
124678453a8Sspeer *
125678453a8Sspeer * Arguments:
126*86ef0a63SRichard Lowe * nxgep
127*86ef0a63SRichard Lowe * channel The channel to bind.
128678453a8Sspeer *
129678453a8Sspeer * Notes:
130678453a8Sspeer *
131678453a8Sspeer * NPI/NXGE function calls:
132678453a8Sspeer * npi_txc_control()
133678453a8Sspeer * npi_txc_global_imask_set()
134678453a8Sspeer * npi_txc_port_dma_enable()
135678453a8Sspeer *
136678453a8Sspeer * Registers accessed:
137678453a8Sspeer * TXC_CONTROL
138678453a8Sspeer * TXC_PORT_DMA
139678453a8Sspeer * TXC_INT_MASK
140678453a8Sspeer *
141678453a8Sspeer * Context:
142678453a8Sspeer * Service domain
143678453a8Sspeer */
144678453a8Sspeer nxge_status_t
nxge_txc_tdc_bind(p_nxge_t nxgep,int channel)145678453a8Sspeer nxge_txc_tdc_bind(
146678453a8Sspeer p_nxge_t nxgep,
147678453a8Sspeer int channel)
148678453a8Sspeer {
149678453a8Sspeer uint8_t port;
150678453a8Sspeer uint64_t bitmap;
151678453a8Sspeer npi_handle_t handle;
152678453a8Sspeer npi_status_t rs = NPI_SUCCESS;
153678453a8Sspeer txc_control_t txc_control;
154678453a8Sspeer
155678453a8Sspeer port = NXGE_GET_PORT_NUM(nxgep->function_num);
156678453a8Sspeer
157678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL,
158678453a8Sspeer "==> nxge_txc_tdc_bind(port %d, channel %d)", port, channel));
159678453a8Sspeer
160678453a8Sspeer handle = NXGE_DEV_NPI_HANDLE(nxgep);
161678453a8Sspeer
162678453a8Sspeer /* Get the current value of TXC_CONTROL. */
163678453a8Sspeer (void) npi_txc_control(handle, OP_GET, &txc_control);
164678453a8Sspeer
165678453a8Sspeer /* Mask all TXC interrupts for <port>. */
166678453a8Sspeer if (txc_control.value & (1 << port)) {
167678453a8Sspeer npi_txc_global_imask_set(handle, port, TXC_INT_MASK_IVAL);
168678453a8Sspeer }
169678453a8Sspeer
170678453a8Sspeer /* Bind <channel> to <port>. */
171678453a8Sspeer /* Read in the old bitmap. */
172678453a8Sspeer TXC_FZC_CNTL_REG_READ64(handle, TXC_PORT_DMA_ENABLE_REG, port,
173678453a8Sspeer &bitmap);
174678453a8Sspeer
175678453a8Sspeer if (bitmap & (1 << channel)) {
176678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
177678453a8Sspeer "nxge_txc_tdc_bind: channel %d already bound on port %d",
17852ccf843Smisaki channel, port));
179678453a8Sspeer } else {
180678453a8Sspeer /* Bind the new channel. */
181678453a8Sspeer bitmap |= (1 << channel);
182678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL,
18352ccf843Smisaki "==> nxge_txc_tdc_bind(): bitmap = %lx", bitmap));
184678453a8Sspeer
185678453a8Sspeer /* Write out the new bitmap. */
186678453a8Sspeer if ((rs = npi_txc_port_dma_enable(handle, port,
18752ccf843Smisaki (uint32_t)bitmap)) != NPI_SUCCESS) {
188678453a8Sspeer goto fail;
189678453a8Sspeer }
190678453a8Sspeer }
191678453a8Sspeer
192678453a8Sspeer /* Enable this port, if necessary. */
193678453a8Sspeer if (!(txc_control.value & (1 << port))) {
194678453a8Sspeer if ((rs = npi_txc_port_enable(handle, port)) != NPI_SUCCESS) {
195678453a8Sspeer goto fail;
196678453a8Sspeer }
197678453a8Sspeer }
198678453a8Sspeer
199678453a8Sspeer /*
200678453a8Sspeer * Enable the TXC controller, if necessary.
201678453a8Sspeer */
202678453a8Sspeer if (txc_control.bits.ldw.txc_enabled == 0) {
203678453a8Sspeer if ((rs = npi_txc_global_enable(handle)) != NPI_SUCCESS) {
204678453a8Sspeer goto fail;
205678453a8Sspeer }
206678453a8Sspeer }
207678453a8Sspeer
208678453a8Sspeer /* Unmask all TXC interrupts on <port> */
209678453a8Sspeer npi_txc_global_imask_set(handle, port, 0);
210678453a8Sspeer
211678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL,
212678453a8Sspeer "<== nxge_txc_tdc_bind(port %d, channel %d)", port, channel));
213678453a8Sspeer
214678453a8Sspeer return (NXGE_OK);
215678453a8Sspeer fail:
216678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
217678453a8Sspeer "nxge_txc_tdc_bind(port %d, channel %d) failed", port, channel));
218678453a8Sspeer
219678453a8Sspeer return (NXGE_ERROR | rs);
220678453a8Sspeer }
221678453a8Sspeer
222678453a8Sspeer /*
223678453a8Sspeer * nxge_txc_tdc_unbind
224678453a8Sspeer *
225678453a8Sspeer * Unbind a TDC from a port.
226678453a8Sspeer *
227678453a8Sspeer * Arguments:
228*86ef0a63SRichard Lowe * nxgep
229*86ef0a63SRichard Lowe * channel The channel to unbind.
230678453a8Sspeer *
231678453a8Sspeer * Notes:
232678453a8Sspeer *
233678453a8Sspeer * NPI/NXGE function calls:
234678453a8Sspeer * npi_txc_control()
235678453a8Sspeer * npi_txc_global_imask_set()
236678453a8Sspeer * npi_txc_port_dma_enable()
237678453a8Sspeer *
238678453a8Sspeer * Registers accessed:
239678453a8Sspeer * TXC_CONTROL
240678453a8Sspeer * TXC_PORT_DMA
241678453a8Sspeer * TXC_INT_MASK
242678453a8Sspeer *
243678453a8Sspeer * Context:
244678453a8Sspeer * Service domain
245678453a8Sspeer */
246678453a8Sspeer nxge_status_t
nxge_txc_tdc_unbind(p_nxge_t nxgep,int channel)247678453a8Sspeer nxge_txc_tdc_unbind(
248678453a8Sspeer p_nxge_t nxgep,
249678453a8Sspeer int channel)
250678453a8Sspeer {
251678453a8Sspeer uint8_t port;
252678453a8Sspeer uint64_t bitmap;
253678453a8Sspeer npi_handle_t handle;
254678453a8Sspeer npi_status_t rs = NPI_SUCCESS;
255678453a8Sspeer
256678453a8Sspeer handle = NXGE_DEV_NPI_HANDLE(nxgep);
257678453a8Sspeer port = NXGE_GET_PORT_NUM(nxgep->function_num);
258678453a8Sspeer
259678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL,
260678453a8Sspeer "==> nxge_txc_tdc_unbind(port %d, channel %d)", port, channel));
261678453a8Sspeer
262678453a8Sspeer /* Mask all TXC interrupts for <port>. */
263678453a8Sspeer npi_txc_global_imask_set(handle, port, TXC_INT_MASK_IVAL);
264678453a8Sspeer
265678453a8Sspeer /* Unbind <channel>. */
266678453a8Sspeer /* Read in the old bitmap. */
267678453a8Sspeer TXC_FZC_CNTL_REG_READ64(handle, TXC_PORT_DMA_ENABLE_REG, port,
268678453a8Sspeer &bitmap);
269678453a8Sspeer
270678453a8Sspeer bitmap &= (~(1 << channel));
271678453a8Sspeer
272678453a8Sspeer /* Write out the new bitmap. */
273678453a8Sspeer if ((rs = npi_txc_port_dma_enable(handle, port,
27452ccf843Smisaki (uint32_t)bitmap)) != NPI_SUCCESS) {
275678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
276678453a8Sspeer "npi_txc_port_dma_enable(%d, %d) failed: %x",
27752ccf843Smisaki port, channel, rs));
278678453a8Sspeer }
279678453a8Sspeer
280678453a8Sspeer /* Unmask all TXC interrupts on <port> */
281678453a8Sspeer if (bitmap)
282678453a8Sspeer npi_txc_global_imask_set(handle, port, 0);
283678453a8Sspeer
284678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL,
285678453a8Sspeer "<== nxge_txc_tdc_unbind(port %d, channel %d)", port, channel));
286678453a8Sspeer
287678453a8Sspeer return (NXGE_OK);
288678453a8Sspeer fail:
289678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
290678453a8Sspeer "nxge_txc_tdc_unbind(port %d, channel %d) failed", port, channel));
291678453a8Sspeer
292678453a8Sspeer return (NXGE_ERROR | rs);
293678453a8Sspeer }
294678453a8Sspeer
29544961713Sgirish void
nxge_txc_regs_dump(p_nxge_t nxgep)29644961713Sgirish nxge_txc_regs_dump(p_nxge_t nxgep)
29744961713Sgirish {
29844961713Sgirish uint32_t cnt1, cnt2;
29944961713Sgirish npi_handle_t handle;
30044961713Sgirish txc_control_t control;
30144961713Sgirish uint32_t bitmap = 0;
30244961713Sgirish
303a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, "\nTXC dump: func # %d:\n",
30452ccf843Smisaki nxgep->function_num));
30544961713Sgirish
30644961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep);
30744961713Sgirish
30844961713Sgirish (void) npi_txc_control(handle, OP_GET, &control);
30944961713Sgirish (void) npi_txc_port_dma_list_get(handle, nxgep->function_num, &bitmap);
31044961713Sgirish
311a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, "\n\tTXC port control 0x%0llx",
31252ccf843Smisaki (long long)control.value));
313a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, "\n\tTXC port bitmap 0x%x", bitmap));
31444961713Sgirish
31544961713Sgirish (void) npi_txc_pkt_xmt_to_mac_get(handle, nxgep->function_num,
31644961713Sgirish &cnt1, &cnt2);
317a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, "\n\tTXC bytes to MAC %d "
31852ccf843Smisaki "packets to MAC %d",
31952ccf843Smisaki cnt1, cnt2));
32044961713Sgirish
32144961713Sgirish (void) npi_txc_pkt_stuffed_get(handle, nxgep->function_num,
32252ccf843Smisaki &cnt1, &cnt2);
323a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, TX_CTL,
32452ccf843Smisaki "\n\tTXC ass packets %d reorder packets %d",
32552ccf843Smisaki cnt1 & 0xffff, cnt2 & 0xffff));
32644961713Sgirish
32744961713Sgirish (void) npi_txc_reorder_get(handle, nxgep->function_num, &cnt1);
328a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, TX_CTL,
32952ccf843Smisaki "\n\tTXC reorder resource %d", cnt1 & 0xff));
33044961713Sgirish }
33144961713Sgirish
33244961713Sgirish nxge_status_t
nxge_txc_handle_sys_errors(p_nxge_t nxgep)33344961713Sgirish nxge_txc_handle_sys_errors(p_nxge_t nxgep)
33444961713Sgirish {
33544961713Sgirish npi_handle_t handle;
33644961713Sgirish txc_int_stat_t istatus;
33744961713Sgirish uint32_t err_status;
33844961713Sgirish uint8_t err_portn;
33944961713Sgirish boolean_t my_err = B_FALSE;
34044961713Sgirish nxge_status_t status = NXGE_OK;
34144961713Sgirish
34244961713Sgirish handle = nxgep->npi_handle;
34344961713Sgirish npi_txc_global_istatus_get(handle, (txc_int_stat_t *)&istatus.value);
34444961713Sgirish switch (nxgep->mac.portnum) {
34544961713Sgirish case 0:
34644961713Sgirish if (istatus.bits.ldw.port0_int_status) {
34744961713Sgirish my_err = B_TRUE;
34844961713Sgirish err_portn = 0;
34944961713Sgirish err_status = istatus.bits.ldw.port0_int_status;
35044961713Sgirish }
35144961713Sgirish break;
35244961713Sgirish case 1:
35344961713Sgirish if (istatus.bits.ldw.port1_int_status) {
35444961713Sgirish my_err = B_TRUE;
35544961713Sgirish err_portn = 1;
35644961713Sgirish err_status = istatus.bits.ldw.port1_int_status;
35744961713Sgirish }
35844961713Sgirish break;
35944961713Sgirish case 2:
36044961713Sgirish if (istatus.bits.ldw.port2_int_status) {
36144961713Sgirish my_err = B_TRUE;
36244961713Sgirish err_portn = 2;
36344961713Sgirish err_status = istatus.bits.ldw.port2_int_status;
36444961713Sgirish }
36544961713Sgirish break;
36644961713Sgirish case 3:
36744961713Sgirish if (istatus.bits.ldw.port3_int_status) {
36844961713Sgirish my_err = B_TRUE;
36944961713Sgirish err_portn = 3;
37044961713Sgirish err_status = istatus.bits.ldw.port3_int_status;
37144961713Sgirish }
37244961713Sgirish break;
37344961713Sgirish default:
37444961713Sgirish return (NXGE_ERROR);
37544961713Sgirish }
37644961713Sgirish if (my_err) {
377e3d11eeeSToomas Soome NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
378e3d11eeeSToomas Soome " nxge_txc_handle_sys_errors: errored port %d",
379e3d11eeeSToomas Soome err_portn));
38044961713Sgirish status = nxge_txc_handle_port_errors(nxgep, err_status);
38144961713Sgirish }
38244961713Sgirish
38344961713Sgirish return (status);
38444961713Sgirish }
38544961713Sgirish
38644961713Sgirish static nxge_status_t
nxge_txc_handle_port_errors(p_nxge_t nxgep,uint32_t err_status)38744961713Sgirish nxge_txc_handle_port_errors(p_nxge_t nxgep, uint32_t err_status)
38844961713Sgirish {
38944961713Sgirish npi_handle_t handle;
39044961713Sgirish npi_status_t rs = NPI_SUCCESS;
39144961713Sgirish p_nxge_txc_stats_t statsp;
39244961713Sgirish txc_int_stat_t istatus;
39344961713Sgirish boolean_t txport_fatal = B_FALSE;
39444961713Sgirish uint8_t portn;
39544961713Sgirish nxge_status_t status = NXGE_OK;
39644961713Sgirish
39744961713Sgirish handle = nxgep->npi_handle;
39844961713Sgirish statsp = (p_nxge_txc_stats_t)&nxgep->statsp->txc_stats;
39944961713Sgirish portn = nxgep->mac.portnum;
40044961713Sgirish istatus.value = 0;
40144961713Sgirish
40244961713Sgirish if ((err_status & TXC_INT_STAT_RO_CORR_ERR) ||
40352ccf843Smisaki (err_status & TXC_INT_STAT_RO_CORR_ERR) ||
40452ccf843Smisaki (err_status & TXC_INT_STAT_RO_UNCORR_ERR) ||
40552ccf843Smisaki (err_status & TXC_INT_STAT_REORDER_ERR)) {
40644961713Sgirish if ((rs = npi_txc_ro_states_get(handle, portn,
40752ccf843Smisaki &statsp->errlog.ro_st)) != NPI_SUCCESS) {
40844961713Sgirish return (NXGE_ERROR | rs);
40944961713Sgirish }
41044961713Sgirish
41144961713Sgirish if (err_status & TXC_INT_STAT_RO_CORR_ERR) {
41244961713Sgirish statsp->ro_correct_err++;
413b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
41452ccf843Smisaki NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR);
41544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
41652ccf843Smisaki "nxge_txc_err_evnts: "
41752ccf843Smisaki "RO FIFO correctable error"));
41844961713Sgirish }
41944961713Sgirish if (err_status & TXC_INT_STAT_RO_UNCORR_ERR) {
42044961713Sgirish statsp->ro_uncorrect_err++;
421b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
42252ccf843Smisaki NXGE_FM_EREPORT_TXC_RO_UNCORRECT_ERR);
42344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
42452ccf843Smisaki "nxge_txc_err_evnts: "
42552ccf843Smisaki "RO FIFO uncorrectable error"));
42644961713Sgirish }
42744961713Sgirish if (err_status & TXC_INT_STAT_REORDER_ERR) {
42844961713Sgirish statsp->reorder_err++;
429b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
43052ccf843Smisaki NXGE_FM_EREPORT_TXC_REORDER_ERR);
43144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
43252ccf843Smisaki "nxge_txc_err_evnts: "
43352ccf843Smisaki "fatal error: Reorder error"));
43444961713Sgirish txport_fatal = B_TRUE;
43544961713Sgirish }
43644961713Sgirish
43744961713Sgirish if ((err_status & TXC_INT_STAT_RO_CORR_ERR) ||
43852ccf843Smisaki (err_status & TXC_INT_STAT_RO_CORR_ERR) ||
43952ccf843Smisaki (err_status & TXC_INT_STAT_RO_UNCORR_ERR)) {
44044961713Sgirish
44144961713Sgirish if ((rs = npi_txc_ro_ecc_state_clr(handle, portn))
44252ccf843Smisaki != NPI_SUCCESS)
44344961713Sgirish return (NXGE_ERROR | rs);
44444961713Sgirish /*
44544961713Sgirish * Making sure that error source is cleared if this is
44644961713Sgirish * an injected error.
44744961713Sgirish */
44844961713Sgirish TXC_FZC_CNTL_REG_WRITE64(handle, TXC_ROECC_CTL_REG,
44952ccf843Smisaki portn, 0);
45044961713Sgirish }
45144961713Sgirish }
45244961713Sgirish
45344961713Sgirish if ((err_status & TXC_INT_STAT_SF_CORR_ERR) ||
45452ccf843Smisaki (err_status & TXC_INT_STAT_SF_UNCORR_ERR)) {
45544961713Sgirish if ((rs = npi_txc_sf_states_get(handle, portn,
45652ccf843Smisaki &statsp->errlog.sf_st)) != NPI_SUCCESS) {
45744961713Sgirish return (NXGE_ERROR | rs);
45844961713Sgirish }
45944961713Sgirish if (err_status & TXC_INT_STAT_SF_CORR_ERR) {
46044961713Sgirish statsp->sf_correct_err++;
461b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
46252ccf843Smisaki NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR);
46344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
46452ccf843Smisaki "nxge_txc_err_evnts: "
46552ccf843Smisaki "SF FIFO correctable error"));
46644961713Sgirish }
46744961713Sgirish if (err_status & TXC_INT_STAT_SF_UNCORR_ERR) {
46844961713Sgirish statsp->sf_uncorrect_err++;
469b37cc459SToomas Soome NXGE_FM_REPORT_ERROR(nxgep, portn, 0,
47052ccf843Smisaki NXGE_FM_EREPORT_TXC_SF_UNCORRECT_ERR);
47144961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
47252ccf843Smisaki "nxge_txc_err_evnts: "
47352ccf843Smisaki "SF FIFO uncorrectable error"));
47444961713Sgirish }
47544961713Sgirish if ((rs = npi_txc_sf_ecc_state_clr(handle, portn))
47652ccf843Smisaki != NPI_SUCCESS)
47744961713Sgirish return (NXGE_ERROR | rs);
47844961713Sgirish /*
47944961713Sgirish * Making sure that error source is cleared if this is
48044961713Sgirish * an injected error.
48144961713Sgirish */
48244961713Sgirish TXC_FZC_CNTL_REG_WRITE64(handle, TXC_SFECC_CTL_REG, portn, 0);
48344961713Sgirish }
48444961713Sgirish
48544961713Sgirish /* Clear corresponding errors */
48644961713Sgirish switch (portn) {
48744961713Sgirish case 0:
48844961713Sgirish istatus.bits.ldw.port0_int_status = err_status;
48944961713Sgirish break;
49044961713Sgirish case 1:
49144961713Sgirish istatus.bits.ldw.port1_int_status = err_status;
49244961713Sgirish break;
49344961713Sgirish case 2:
49444961713Sgirish istatus.bits.ldw.port2_int_status = err_status;
49544961713Sgirish break;
49644961713Sgirish case 3:
49744961713Sgirish istatus.bits.ldw.port3_int_status = err_status;
49844961713Sgirish break;
49944961713Sgirish default:
50044961713Sgirish return (NXGE_ERROR);
50144961713Sgirish }
50244961713Sgirish
50344961713Sgirish npi_txc_global_istatus_clear(handle, istatus.value);
50444961713Sgirish
50544961713Sgirish if (txport_fatal) {
50644961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
50752ccf843Smisaki " nxge_txc_handle_port_errors:"
50852ccf843Smisaki " fatal Error on Port#%d\n",
50952ccf843Smisaki portn));
51044961713Sgirish status = nxge_tx_port_fatal_err_recover(nxgep);
51144961713Sgirish if (status == NXGE_OK) {
51244961713Sgirish FM_SERVICE_RESTORED(nxgep);
51344961713Sgirish }
51444961713Sgirish }
51544961713Sgirish
51644961713Sgirish return (status);
51744961713Sgirish }
51844961713Sgirish
51944961713Sgirish void
nxge_txc_inject_err(p_nxge_t nxgep,uint32_t err_id)52044961713Sgirish nxge_txc_inject_err(p_nxge_t nxgep, uint32_t err_id)
52144961713Sgirish {
52244961713Sgirish txc_int_stat_dbg_t txcs;
52344961713Sgirish txc_roecc_ctl_t ro_ecc_ctl;
52444961713Sgirish txc_sfecc_ctl_t sf_ecc_ctl;
52544961713Sgirish uint8_t portn = nxgep->mac.portnum;
52644961713Sgirish
52744961713Sgirish cmn_err(CE_NOTE, "!TXC error Inject\n");
52844961713Sgirish switch (err_id) {
52944961713Sgirish case NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR:
53044961713Sgirish case NXGE_FM_EREPORT_TXC_RO_UNCORRECT_ERR:
53144961713Sgirish ro_ecc_ctl.value = 0;
53244961713Sgirish ro_ecc_ctl.bits.ldw.all_pkts = 1;
53344961713Sgirish ro_ecc_ctl.bits.ldw.second_line_pkt = 1;
53444961713Sgirish if (err_id == NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR)
53544961713Sgirish ro_ecc_ctl.bits.ldw.single_bit_err = 1;
53644961713Sgirish else
53744961713Sgirish ro_ecc_ctl.bits.ldw.double_bit_err = 1;
53844961713Sgirish cmn_err(CE_NOTE, "!Write 0x%lx to TXC_ROECC_CTL_REG\n",
53952ccf843Smisaki ro_ecc_ctl.value);
54044961713Sgirish TXC_FZC_CNTL_REG_WRITE64(nxgep->npi_handle, TXC_ROECC_CTL_REG,
54152ccf843Smisaki portn, ro_ecc_ctl.value);
54244961713Sgirish break;
54344961713Sgirish case NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR:
54444961713Sgirish case NXGE_FM_EREPORT_TXC_SF_UNCORRECT_ERR:
54544961713Sgirish sf_ecc_ctl.value = 0;
54644961713Sgirish sf_ecc_ctl.bits.ldw.all_pkts = 1;
54744961713Sgirish sf_ecc_ctl.bits.ldw.second_line_pkt = 1;
54844961713Sgirish if (err_id == NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR)
54944961713Sgirish sf_ecc_ctl.bits.ldw.single_bit_err = 1;
55044961713Sgirish else
55144961713Sgirish sf_ecc_ctl.bits.ldw.double_bit_err = 1;
55244961713Sgirish cmn_err(CE_NOTE, "!Write 0x%lx to TXC_SFECC_CTL_REG\n",
55352ccf843Smisaki sf_ecc_ctl.value);
55444961713Sgirish TXC_FZC_CNTL_REG_WRITE64(nxgep->npi_handle, TXC_SFECC_CTL_REG,
55552ccf843Smisaki portn, sf_ecc_ctl.value);
55644961713Sgirish break;
55744961713Sgirish case NXGE_FM_EREPORT_TXC_REORDER_ERR:
55844961713Sgirish NXGE_REG_RD64(nxgep->npi_handle, TXC_INT_STAT_DBG_REG,
55952ccf843Smisaki &txcs.value);
56044961713Sgirish nxge_txc_inject_port_err(portn, &txcs,
56152ccf843Smisaki TXC_INT_STAT_REORDER_ERR);
56244961713Sgirish cmn_err(CE_NOTE, "!Write 0x%lx to TXC_INT_STAT_DBG_REG\n",
56352ccf843Smisaki txcs.value);
56444961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, TXC_INT_STAT_DBG_REG,
56552ccf843Smisaki txcs.value);
56644961713Sgirish break;
56744961713Sgirish default:
56844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
56952ccf843Smisaki "nxge_txc_inject_err: Unknown err_id"));
57044961713Sgirish }
57144961713Sgirish }
57244961713Sgirish
57344961713Sgirish static void
nxge_txc_inject_port_err(uint8_t portn,txc_int_stat_dbg_t * txcs,uint8_t istats)57444961713Sgirish nxge_txc_inject_port_err(uint8_t portn, txc_int_stat_dbg_t *txcs,
575*86ef0a63SRichard Lowe uint8_t istats)
57644961713Sgirish {
57744961713Sgirish switch (portn) {
57844961713Sgirish case 0:
57944961713Sgirish txcs->bits.ldw.port0_int_status |= istats;
58044961713Sgirish break;
58144961713Sgirish case 1:
58244961713Sgirish txcs->bits.ldw.port1_int_status |= istats;
58344961713Sgirish break;
58444961713Sgirish case 2:
58544961713Sgirish txcs->bits.ldw.port2_int_status |= istats;
58644961713Sgirish break;
58744961713Sgirish case 3:
58844961713Sgirish txcs->bits.ldw.port3_int_status |= istats;
58944961713Sgirish break;
59044961713Sgirish default:
59144961713Sgirish ;
59244961713Sgirish }
59344961713Sgirish }
594