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