xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_txc.c (revision 86ef0a63)
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