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
nxge_txc_init(p_nxge_t nxgep)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
nxge_txc_uninit(p_nxge_t nxgep)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
nxge_txc_tdc_bind(p_nxge_t nxgep,int channel)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
nxge_txc_tdc_unbind(p_nxge_t nxgep,int channel)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
nxge_txc_regs_dump(p_nxge_t nxgep)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
nxge_txc_handle_sys_errors(p_nxge_t nxgep)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
nxge_txc_handle_port_errors(p_nxge_t nxgep,uint32_t err_status)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
nxge_txc_inject_err(p_nxge_t nxgep,uint32_t err_id)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
nxge_txc_inject_port_err(uint8_t portn,txc_int_stat_dbg_t * txcs,uint8_t istats)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