xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_txc.c (revision afab0816ecb604f0099a09ad8ee398f0d7b77b1c)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/nxge/nxge_impl.h>
29 #include <sys/nxge/nxge_txc.h>
30 
31 static nxge_status_t
32 nxge_txc_handle_port_errors(p_nxge_t, uint32_t);
33 static void
34 nxge_txc_inject_port_err(uint8_t, txc_int_stat_dbg_t *,
35 			uint8_t istats);
36 extern nxge_status_t nxge_tx_port_fatal_err_recover(p_nxge_t);
37 
38 nxge_status_t
39 nxge_txc_init(p_nxge_t nxgep)
40 {
41 	uint8_t			port;
42 	npi_handle_t		handle;
43 	npi_status_t		rs = NPI_SUCCESS;
44 
45 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
46 	port = NXGE_GET_PORT_NUM(nxgep->function_num);
47 
48 	NXGE_DEBUG_MSG((nxgep, TX_CTL, "==> nxge_txc_init: portn %d", port));
49 
50 	/*
51 	 * Enable the TXC controller.
52 	 */
53 	if ((rs = npi_txc_global_enable(handle)) != NPI_SUCCESS) {
54 		goto fail;
55 	}
56 
57 	/* Enable this port within the TXC. */
58 	if ((rs = npi_txc_port_enable(handle, port)) != NPI_SUCCESS) {
59 		goto fail;
60 	}
61 
62 	/* Bind DMA channels to this port. */
63 	if ((rs = npi_txc_port_dma_enable(handle, port,
64 	    TXDMA_PORT_BITMAP(nxgep))) != NPI_SUCCESS) {
65 		goto fail;
66 	}
67 
68 	/* Unmask all TXC interrupts */
69 	npi_txc_global_imask_set(handle, port, 0);
70 
71 	NXGE_DEBUG_MSG((nxgep, TX_CTL, "<== nxge_txc_init: portn %d", port));
72 
73 	return (NXGE_OK);
74 fail:
75 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
76 	    "nxge_txc_init: Failed to initialize txc on port %d",
77 	    port));
78 
79 	return (NXGE_ERROR | rs);
80 }
81 
82 nxge_status_t
83 nxge_txc_uninit(p_nxge_t nxgep)
84 {
85 	uint8_t			port;
86 	npi_handle_t		handle;
87 	npi_status_t		rs = NPI_SUCCESS;
88 
89 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
90 	port = NXGE_GET_PORT_NUM(nxgep->function_num);
91 
92 	NXGE_DEBUG_MSG((nxgep, TX_CTL, "==> nxge_txc_uninit: portn %d", port));
93 
94 	/*
95 	 * disable the TXC controller.
96 	 */
97 	if ((rs = npi_txc_global_disable(handle)) != NPI_SUCCESS) {
98 		goto fail;
99 	}
100 
101 	/* disable this port within the TXC. */
102 	if ((rs = npi_txc_port_disable(handle, port)) != NPI_SUCCESS) {
103 		goto fail;
104 	}
105 
106 	/* unbind DMA channels to this port. */
107 	if ((rs = npi_txc_port_dma_enable(handle, port, 0)) != NPI_SUCCESS) {
108 		goto fail;
109 	}
110 
111 	NXGE_DEBUG_MSG((nxgep, TX_CTL, "<== nxge_txc_uninit: portn %d", port));
112 
113 	return (NXGE_OK);
114 fail:
115 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
116 	    "nxge_txc_init: Failed to initialize txc on port %d",
117 	    port));
118 
119 	return (NXGE_ERROR | rs);
120 }
121 
122 /*
123  * nxge_txc_tdc_bind
124  *
125  *	Bind a TDC to a port.
126  *
127  * Arguments:
128  * 	nxgep
129  * 	channel		The channel to bind.
130  *
131  * Notes:
132  *
133  * NPI/NXGE function calls:
134  *	npi_txc_control()
135  *	npi_txc_global_imask_set()
136  *	npi_txc_port_dma_enable()
137  *
138  * Registers accessed:
139  *	TXC_CONTROL
140  *	TXC_PORT_DMA
141  *	TXC_INT_MASK
142  *
143  * Context:
144  *	Service domain
145  */
146 nxge_status_t
147 nxge_txc_tdc_bind(
148 	p_nxge_t nxgep,
149 	int channel)
150 {
151 	uint8_t		port;
152 	uint64_t	bitmap;
153 	npi_handle_t	handle;
154 	npi_status_t	rs = NPI_SUCCESS;
155 	txc_control_t	txc_control;
156 
157 	port = NXGE_GET_PORT_NUM(nxgep->function_num);
158 
159 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
160 	    "==> nxge_txc_tdc_bind(port %d, channel %d)", port, channel));
161 
162 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
163 
164 	/* Get the current value of TXC_CONTROL. */
165 	(void) npi_txc_control(handle, OP_GET, &txc_control);
166 
167 	/* Mask all TXC interrupts for <port>. */
168 	if (txc_control.value & (1 << port)) {
169 		npi_txc_global_imask_set(handle, port, TXC_INT_MASK_IVAL);
170 	}
171 
172 	/* Bind <channel> to <port>. */
173 	/* Read in the old bitmap. */
174 	TXC_FZC_CNTL_REG_READ64(handle, TXC_PORT_DMA_ENABLE_REG, port,
175 	    &bitmap);
176 
177 	if (bitmap & (1 << channel)) {
178 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
179 		    "nxge_txc_tdc_bind: channel %d already bound on port %d",
180 		    channel, port));
181 	} else {
182 		/* Bind the new channel. */
183 		bitmap |= (1 << channel);
184 		NXGE_DEBUG_MSG((nxgep, TX_CTL,
185 		    "==> nxge_txc_tdc_bind(): bitmap = %lx", bitmap));
186 
187 		/* Write out the new bitmap. */
188 		if ((rs = npi_txc_port_dma_enable(handle, port,
189 		    (uint32_t)bitmap)) != NPI_SUCCESS) {
190 			goto fail;
191 		}
192 	}
193 
194 	/* Enable this port, if necessary. */
195 	if (!(txc_control.value & (1 << port))) {
196 		if ((rs = npi_txc_port_enable(handle, port)) != NPI_SUCCESS) {
197 			goto fail;
198 		}
199 	}
200 
201 	/*
202 	 * Enable the TXC controller, if necessary.
203 	 */
204 	if (txc_control.bits.ldw.txc_enabled == 0) {
205 		if ((rs = npi_txc_global_enable(handle)) != NPI_SUCCESS) {
206 			goto fail;
207 		}
208 	}
209 
210 	/* Unmask all TXC interrupts on <port> */
211 	npi_txc_global_imask_set(handle, port, 0);
212 
213 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
214 	    "<== nxge_txc_tdc_bind(port %d, channel %d)", port, channel));
215 
216 	return (NXGE_OK);
217 fail:
218 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
219 	    "nxge_txc_tdc_bind(port %d, channel %d) failed", port, channel));
220 
221 	return (NXGE_ERROR | rs);
222 }
223 
224 /*
225  * nxge_txc_tdc_unbind
226  *
227  *	Unbind a TDC from a port.
228  *
229  * Arguments:
230  * 	nxgep
231  * 	channel		The channel to unbind.
232  *
233  * Notes:
234  *
235  * NPI/NXGE function calls:
236  *	npi_txc_control()
237  *	npi_txc_global_imask_set()
238  *	npi_txc_port_dma_enable()
239  *
240  * Registers accessed:
241  *	TXC_CONTROL
242  *	TXC_PORT_DMA
243  *	TXC_INT_MASK
244  *
245  * Context:
246  *	Service domain
247  */
248 nxge_status_t
249 nxge_txc_tdc_unbind(
250 	p_nxge_t nxgep,
251 	int channel)
252 {
253 	uint8_t		port;
254 	uint64_t	bitmap;
255 	npi_handle_t	handle;
256 	npi_status_t	rs = NPI_SUCCESS;
257 
258 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
259 	port = NXGE_GET_PORT_NUM(nxgep->function_num);
260 
261 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
262 	    "==> nxge_txc_tdc_unbind(port %d, channel %d)", port, channel));
263 
264 	/* Mask all TXC interrupts for <port>. */
265 	npi_txc_global_imask_set(handle, port, TXC_INT_MASK_IVAL);
266 
267 	/* Unbind <channel>. */
268 	/* Read in the old bitmap. */
269 	TXC_FZC_CNTL_REG_READ64(handle, TXC_PORT_DMA_ENABLE_REG, port,
270 	    &bitmap);
271 
272 	bitmap &= (~(1 << channel));
273 
274 	/* Write out the new bitmap. */
275 	if ((rs = npi_txc_port_dma_enable(handle, port,
276 	    (uint32_t)bitmap)) != NPI_SUCCESS) {
277 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
278 		    "npi_txc_port_dma_enable(%d, %d) failed: %x",
279 		    port, channel, rs));
280 	}
281 
282 	/* Unmask all TXC interrupts on <port> */
283 	if (bitmap)
284 		npi_txc_global_imask_set(handle, port, 0);
285 
286 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
287 	    "<== nxge_txc_tdc_unbind(port %d, channel %d)", port, channel));
288 
289 	return (NXGE_OK);
290 fail:
291 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
292 	    "nxge_txc_tdc_unbind(port %d, channel %d) failed", port, channel));
293 
294 	return (NXGE_ERROR | rs);
295 }
296 
297 void
298 nxge_txc_regs_dump(p_nxge_t nxgep)
299 {
300 	uint32_t		cnt1, cnt2;
301 	npi_handle_t		handle;
302 	txc_control_t		control;
303 	uint32_t		bitmap = 0;
304 
305 	NXGE_DEBUG_MSG((nxgep, TX_CTL, "\nTXC dump: func # %d:\n",
306 	    nxgep->function_num));
307 
308 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
309 
310 	(void) npi_txc_control(handle, OP_GET, &control);
311 	(void) npi_txc_port_dma_list_get(handle, nxgep->function_num, &bitmap);
312 
313 	NXGE_DEBUG_MSG((nxgep, TX_CTL, "\n\tTXC port control 0x%0llx",
314 	    (long long)control.value));
315 	NXGE_DEBUG_MSG((nxgep, TX_CTL, "\n\tTXC port bitmap 0x%x", bitmap));
316 
317 	(void) npi_txc_pkt_xmt_to_mac_get(handle, nxgep->function_num,
318 	    &cnt1, &cnt2);
319 	NXGE_DEBUG_MSG((nxgep, TX_CTL, "\n\tTXC bytes to MAC %d "
320 	    "packets to MAC %d",
321 	    cnt1, cnt2));
322 
323 	(void) npi_txc_pkt_stuffed_get(handle, nxgep->function_num,
324 	    &cnt1, &cnt2);
325 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
326 	    "\n\tTXC ass packets %d reorder packets %d",
327 	    cnt1 & 0xffff, cnt2 & 0xffff));
328 
329 	(void) npi_txc_reorder_get(handle, nxgep->function_num, &cnt1);
330 	NXGE_DEBUG_MSG((nxgep, TX_CTL,
331 	    "\n\tTXC reorder resource %d", cnt1 & 0xff));
332 }
333 
334 nxge_status_t
335 nxge_txc_handle_sys_errors(p_nxge_t nxgep)
336 {
337 	npi_handle_t		handle;
338 	txc_int_stat_t		istatus;
339 	uint32_t		err_status;
340 	uint8_t			err_portn;
341 	boolean_t		my_err = B_FALSE;
342 	nxge_status_t		status = NXGE_OK;
343 
344 	handle = nxgep->npi_handle;
345 	npi_txc_global_istatus_get(handle, (txc_int_stat_t *)&istatus.value);
346 	switch (nxgep->mac.portnum) {
347 	case 0:
348 		if (istatus.bits.ldw.port0_int_status) {
349 			my_err = B_TRUE;
350 			err_portn = 0;
351 			err_status = istatus.bits.ldw.port0_int_status;
352 		}
353 		break;
354 	case 1:
355 		if (istatus.bits.ldw.port1_int_status) {
356 			my_err = B_TRUE;
357 			err_portn = 1;
358 			err_status = istatus.bits.ldw.port1_int_status;
359 		}
360 		break;
361 	case 2:
362 		if (istatus.bits.ldw.port2_int_status) {
363 			my_err = B_TRUE;
364 			err_portn = 2;
365 			err_status = istatus.bits.ldw.port2_int_status;
366 		}
367 		break;
368 	case 3:
369 		if (istatus.bits.ldw.port3_int_status) {
370 			my_err = B_TRUE;
371 			err_portn = 3;
372 			err_status = istatus.bits.ldw.port3_int_status;
373 		}
374 		break;
375 	default:
376 		return (NXGE_ERROR);
377 	}
378 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
379 	    " nxge_txc_handle_sys_errors: errored port %d",
380 	    err_portn));
381 	if (my_err) {
382 		status = nxge_txc_handle_port_errors(nxgep, err_status);
383 	}
384 
385 	return (status);
386 }
387 
388 static nxge_status_t
389 nxge_txc_handle_port_errors(p_nxge_t nxgep, uint32_t err_status)
390 {
391 	npi_handle_t		handle;
392 	npi_status_t		rs = NPI_SUCCESS;
393 	p_nxge_txc_stats_t	statsp;
394 	txc_int_stat_t		istatus;
395 	boolean_t		txport_fatal = B_FALSE;
396 	uint8_t			portn;
397 	nxge_status_t		status = NXGE_OK;
398 
399 	handle = nxgep->npi_handle;
400 	statsp = (p_nxge_txc_stats_t)&nxgep->statsp->txc_stats;
401 	portn = nxgep->mac.portnum;
402 	istatus.value = 0;
403 
404 	if ((err_status & TXC_INT_STAT_RO_CORR_ERR) ||
405 	    (err_status & TXC_INT_STAT_RO_CORR_ERR) ||
406 	    (err_status & TXC_INT_STAT_RO_UNCORR_ERR) ||
407 	    (err_status & TXC_INT_STAT_REORDER_ERR)) {
408 		if ((rs = npi_txc_ro_states_get(handle, portn,
409 		    &statsp->errlog.ro_st)) != NPI_SUCCESS) {
410 			return (NXGE_ERROR | rs);
411 		}
412 
413 		if (err_status & TXC_INT_STAT_RO_CORR_ERR) {
414 			statsp->ro_correct_err++;
415 			NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
416 			    NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR);
417 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
418 			    "nxge_txc_err_evnts: "
419 			    "RO FIFO correctable error"));
420 		}
421 		if (err_status & TXC_INT_STAT_RO_UNCORR_ERR) {
422 			statsp->ro_uncorrect_err++;
423 			NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
424 			    NXGE_FM_EREPORT_TXC_RO_UNCORRECT_ERR);
425 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
426 			    "nxge_txc_err_evnts: "
427 			    "RO FIFO uncorrectable error"));
428 		}
429 		if (err_status & TXC_INT_STAT_REORDER_ERR) {
430 			statsp->reorder_err++;
431 			NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
432 			    NXGE_FM_EREPORT_TXC_REORDER_ERR);
433 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
434 			    "nxge_txc_err_evnts: "
435 			    "fatal error: Reorder error"));
436 			txport_fatal = B_TRUE;
437 		}
438 
439 		if ((err_status & TXC_INT_STAT_RO_CORR_ERR) ||
440 		    (err_status & TXC_INT_STAT_RO_CORR_ERR) ||
441 		    (err_status & TXC_INT_STAT_RO_UNCORR_ERR)) {
442 
443 			if ((rs = npi_txc_ro_ecc_state_clr(handle, portn))
444 			    != NPI_SUCCESS)
445 				return (NXGE_ERROR | rs);
446 			/*
447 			 * Making sure that error source is cleared if this is
448 			 * an injected error.
449 			 */
450 			TXC_FZC_CNTL_REG_WRITE64(handle, TXC_ROECC_CTL_REG,
451 			    portn, 0);
452 		}
453 	}
454 
455 	if ((err_status & TXC_INT_STAT_SF_CORR_ERR) ||
456 	    (err_status & TXC_INT_STAT_SF_UNCORR_ERR)) {
457 		if ((rs = npi_txc_sf_states_get(handle, portn,
458 		    &statsp->errlog.sf_st)) != NPI_SUCCESS) {
459 			return (NXGE_ERROR | rs);
460 		}
461 		if (err_status & TXC_INT_STAT_SF_CORR_ERR) {
462 			statsp->sf_correct_err++;
463 			NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
464 			    NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR);
465 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
466 			    "nxge_txc_err_evnts: "
467 			    "SF FIFO correctable error"));
468 		}
469 		if (err_status & TXC_INT_STAT_SF_UNCORR_ERR) {
470 			statsp->sf_uncorrect_err++;
471 			NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
472 			    NXGE_FM_EREPORT_TXC_SF_UNCORRECT_ERR);
473 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
474 			    "nxge_txc_err_evnts: "
475 			    "SF FIFO uncorrectable error"));
476 		}
477 		if ((rs = npi_txc_sf_ecc_state_clr(handle, portn))
478 		    != NPI_SUCCESS)
479 			return (NXGE_ERROR | rs);
480 		/*
481 		 * Making sure that error source is cleared if this is
482 		 * an injected error.
483 		 */
484 		TXC_FZC_CNTL_REG_WRITE64(handle, TXC_SFECC_CTL_REG, portn, 0);
485 	}
486 
487 	/* Clear corresponding errors */
488 	switch (portn) {
489 	case 0:
490 		istatus.bits.ldw.port0_int_status = err_status;
491 		break;
492 	case 1:
493 		istatus.bits.ldw.port1_int_status = err_status;
494 		break;
495 	case 2:
496 		istatus.bits.ldw.port2_int_status = err_status;
497 		break;
498 	case 3:
499 		istatus.bits.ldw.port3_int_status = err_status;
500 		break;
501 	default:
502 		return (NXGE_ERROR);
503 	}
504 
505 	npi_txc_global_istatus_clear(handle, istatus.value);
506 
507 	if (txport_fatal) {
508 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
509 		    " nxge_txc_handle_port_errors:"
510 		    " fatal Error on Port#%d\n",
511 		    portn));
512 		status = nxge_tx_port_fatal_err_recover(nxgep);
513 		if (status == NXGE_OK) {
514 			FM_SERVICE_RESTORED(nxgep);
515 		}
516 	}
517 
518 	return (status);
519 }
520 
521 void
522 nxge_txc_inject_err(p_nxge_t nxgep, uint32_t err_id)
523 {
524 	txc_int_stat_dbg_t	txcs;
525 	txc_roecc_ctl_t		ro_ecc_ctl;
526 	txc_sfecc_ctl_t		sf_ecc_ctl;
527 	uint8_t			portn = nxgep->mac.portnum;
528 
529 	cmn_err(CE_NOTE, "!TXC error Inject\n");
530 	switch (err_id) {
531 	case NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR:
532 	case NXGE_FM_EREPORT_TXC_RO_UNCORRECT_ERR:
533 		ro_ecc_ctl.value = 0;
534 		ro_ecc_ctl.bits.ldw.all_pkts = 1;
535 		ro_ecc_ctl.bits.ldw.second_line_pkt = 1;
536 		if (err_id == NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR)
537 			ro_ecc_ctl.bits.ldw.single_bit_err = 1;
538 		else
539 			ro_ecc_ctl.bits.ldw.double_bit_err = 1;
540 #if defined(__i386)
541 		cmn_err(CE_NOTE, "!Write 0x%llx to TXC_ROECC_CTL_REG\n",
542 		    ro_ecc_ctl.value);
543 #else
544 		cmn_err(CE_NOTE, "!Write 0x%lx to TXC_ROECC_CTL_REG\n",
545 		    ro_ecc_ctl.value);
546 #endif
547 		TXC_FZC_CNTL_REG_WRITE64(nxgep->npi_handle, TXC_ROECC_CTL_REG,
548 		    portn, ro_ecc_ctl.value);
549 		break;
550 	case NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR:
551 	case NXGE_FM_EREPORT_TXC_SF_UNCORRECT_ERR:
552 		sf_ecc_ctl.value = 0;
553 		sf_ecc_ctl.bits.ldw.all_pkts = 1;
554 		sf_ecc_ctl.bits.ldw.second_line_pkt = 1;
555 		if (err_id == NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR)
556 			sf_ecc_ctl.bits.ldw.single_bit_err = 1;
557 		else
558 			sf_ecc_ctl.bits.ldw.double_bit_err = 1;
559 #if defined(__i386)
560 		cmn_err(CE_NOTE, "!Write 0x%llx to TXC_SFECC_CTL_REG\n",
561 		    sf_ecc_ctl.value);
562 #else
563 		cmn_err(CE_NOTE, "!Write 0x%lx to TXC_SFECC_CTL_REG\n",
564 		    sf_ecc_ctl.value);
565 #endif
566 		TXC_FZC_CNTL_REG_WRITE64(nxgep->npi_handle, TXC_SFECC_CTL_REG,
567 		    portn, sf_ecc_ctl.value);
568 		break;
569 	case NXGE_FM_EREPORT_TXC_REORDER_ERR:
570 		NXGE_REG_RD64(nxgep->npi_handle, TXC_INT_STAT_DBG_REG,
571 		    &txcs.value);
572 		nxge_txc_inject_port_err(portn, &txcs,
573 		    TXC_INT_STAT_REORDER_ERR);
574 #if defined(__i386)
575 		cmn_err(CE_NOTE, "!Write 0x%llx to TXC_INT_STAT_DBG_REG\n",
576 		    txcs.value);
577 #else
578 		cmn_err(CE_NOTE, "!Write 0x%lx to TXC_INT_STAT_DBG_REG\n",
579 		    txcs.value);
580 #endif
581 		NXGE_REG_WR64(nxgep->npi_handle, TXC_INT_STAT_DBG_REG,
582 		    txcs.value);
583 		break;
584 	default:
585 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
586 		    "nxge_txc_inject_err: Unknown err_id"));
587 	}
588 }
589 
590 static void
591 nxge_txc_inject_port_err(uint8_t portn, txc_int_stat_dbg_t *txcs,
592 				uint8_t istats)
593 {
594 	switch (portn) {
595 	case 0:
596 		txcs->bits.ldw.port0_int_status |= istats;
597 		break;
598 	case 1:
599 		txcs->bits.ldw.port1_int_status |= istats;
600 		break;
601 	case 2:
602 		txcs->bits.ldw.port2_int_status |= istats;
603 		break;
604 	case 3:
605 		txcs->bits.ldw.port3_int_status |= istats;
606 		break;
607 	default:
608 		;
609 	}
610 }
611