16f45ec7bSml29623 /*
26f45ec7bSml29623 * CDDL HEADER START
36f45ec7bSml29623 *
46f45ec7bSml29623 * The contents of this file are subject to the terms of the
56f45ec7bSml29623 * Common Development and Distribution License (the "License").
66f45ec7bSml29623 * You may not use this file except in compliance with the License.
76f45ec7bSml29623 *
86f45ec7bSml29623 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96f45ec7bSml29623 * or http://www.opensolaris.org/os/licensing.
106f45ec7bSml29623 * See the License for the specific language governing permissions
116f45ec7bSml29623 * and limitations under the License.
126f45ec7bSml29623 *
136f45ec7bSml29623 * When distributing Covered Code, include this CDDL HEADER in each
146f45ec7bSml29623 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156f45ec7bSml29623 * If applicable, add the following below this CDDL HEADER, with the
166f45ec7bSml29623 * fields enclosed by brackets "[]" replaced with your own identifying
176f45ec7bSml29623 * information: Portions Copyright [yyyy] [name of copyright owner]
186f45ec7bSml29623 *
196f45ec7bSml29623 * CDDL HEADER END
206f45ec7bSml29623 */
216f45ec7bSml29623 /*
22*678453a8Sspeer * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
236f45ec7bSml29623 * Use is subject to license terms.
246f45ec7bSml29623 */
256f45ec7bSml29623
266f45ec7bSml29623 #pragma ident "%Z%%M% %I% %E% SMI"
276f45ec7bSml29623
286f45ec7bSml29623 #include <sys/nxge/nxge_impl.h>
296f45ec7bSml29623 #include <sys/nxge/nxge_txc.h>
306f45ec7bSml29623
316f45ec7bSml29623 static nxge_status_t
326f45ec7bSml29623 nxge_txc_handle_port_errors(p_nxge_t, uint32_t);
336f45ec7bSml29623 static void
346f45ec7bSml29623 nxge_txc_inject_port_err(uint8_t, txc_int_stat_dbg_t *,
356f45ec7bSml29623 uint8_t istats);
366f45ec7bSml29623 extern nxge_status_t nxge_tx_port_fatal_err_recover(p_nxge_t);
376f45ec7bSml29623
386f45ec7bSml29623 nxge_status_t
nxge_txc_init(p_nxge_t nxgep)396f45ec7bSml29623 nxge_txc_init(p_nxge_t nxgep)
406f45ec7bSml29623 {
416f45ec7bSml29623 uint8_t port;
426f45ec7bSml29623 npi_handle_t handle;
436f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS;
446f45ec7bSml29623
456f45ec7bSml29623 handle = NXGE_DEV_NPI_HANDLE(nxgep);
466f45ec7bSml29623 port = NXGE_GET_PORT_NUM(nxgep->function_num);
476f45ec7bSml29623
486f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, TX_CTL, "==> nxge_txc_init: portn %d", port));
496f45ec7bSml29623
506f45ec7bSml29623 /*
516f45ec7bSml29623 * Enable the TXC controller.
526f45ec7bSml29623 */
536f45ec7bSml29623 if ((rs = npi_txc_global_enable(handle)) != NPI_SUCCESS) {
546f45ec7bSml29623 goto fail;
556f45ec7bSml29623 }
566f45ec7bSml29623
576f45ec7bSml29623 /* Enable this port within the TXC. */
586f45ec7bSml29623 if ((rs = npi_txc_port_enable(handle, port)) != NPI_SUCCESS) {
596f45ec7bSml29623 goto fail;
606f45ec7bSml29623 }
616f45ec7bSml29623
626f45ec7bSml29623 /* Bind DMA channels to this port. */
636f45ec7bSml29623 if ((rs = npi_txc_port_dma_enable(handle, port,
646f45ec7bSml29623 TXDMA_PORT_BITMAP(nxgep))) != NPI_SUCCESS) {
656f45ec7bSml29623 goto fail;
666f45ec7bSml29623 }
676f45ec7bSml29623
686f45ec7bSml29623 /* Unmask all TXC interrupts */
696f45ec7bSml29623 npi_txc_global_imask_set(handle, port, 0);
706f45ec7bSml29623
716f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, TX_CTL, "<== nxge_txc_init: portn %d", port));
726f45ec7bSml29623
736f45ec7bSml29623 return (NXGE_OK);
746f45ec7bSml29623 fail:
756f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
766f45ec7bSml29623 "nxge_txc_init: Failed to initialize txc on port %d",
776f45ec7bSml29623 port));
786f45ec7bSml29623
796f45ec7bSml29623 return (NXGE_ERROR | rs);
806f45ec7bSml29623 }
816f45ec7bSml29623
826f45ec7bSml29623 nxge_status_t
nxge_txc_uninit(p_nxge_t nxgep)836f45ec7bSml29623 nxge_txc_uninit(p_nxge_t nxgep)
846f45ec7bSml29623 {
856f45ec7bSml29623 uint8_t port;
866f45ec7bSml29623 npi_handle_t handle;
876f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS;
886f45ec7bSml29623
896f45ec7bSml29623 handle = NXGE_DEV_NPI_HANDLE(nxgep);
906f45ec7bSml29623 port = NXGE_GET_PORT_NUM(nxgep->function_num);
916f45ec7bSml29623
926f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, TX_CTL, "==> nxge_txc_uninit: portn %d", port));
936f45ec7bSml29623
946f45ec7bSml29623 /*
956f45ec7bSml29623 * disable the TXC controller.
966f45ec7bSml29623 */
976f45ec7bSml29623 if ((rs = npi_txc_global_disable(handle)) != NPI_SUCCESS) {
986f45ec7bSml29623 goto fail;
996f45ec7bSml29623 }
1006f45ec7bSml29623
1016f45ec7bSml29623 /* disable this port within the TXC. */
1026f45ec7bSml29623 if ((rs = npi_txc_port_disable(handle, port)) != NPI_SUCCESS) {
1036f45ec7bSml29623 goto fail;
1046f45ec7bSml29623 }
1056f45ec7bSml29623
1066f45ec7bSml29623 /* unbind DMA channels to this port. */
1076f45ec7bSml29623 if ((rs = npi_txc_port_dma_enable(handle, port, 0)) != NPI_SUCCESS) {
1086f45ec7bSml29623 goto fail;
1096f45ec7bSml29623 }
1106f45ec7bSml29623
1116f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, TX_CTL, "<== nxge_txc_uninit: portn %d", port));
1126f45ec7bSml29623
1136f45ec7bSml29623 return (NXGE_OK);
1146f45ec7bSml29623 fail:
1156f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1166f45ec7bSml29623 "nxge_txc_init: Failed to initialize txc on port %d",
1176f45ec7bSml29623 port));
1186f45ec7bSml29623
1196f45ec7bSml29623 return (NXGE_ERROR | rs);
1206f45ec7bSml29623 }
1216f45ec7bSml29623
122*678453a8Sspeer /*
123*678453a8Sspeer * nxge_txc_tdc_bind
124*678453a8Sspeer *
125*678453a8Sspeer * Bind a TDC to a port.
126*678453a8Sspeer *
127*678453a8Sspeer * Arguments:
128*678453a8Sspeer * nxgep
129*678453a8Sspeer * channel The channel to bind.
130*678453a8Sspeer *
131*678453a8Sspeer * Notes:
132*678453a8Sspeer *
133*678453a8Sspeer * NPI/NXGE function calls:
134*678453a8Sspeer * npi_txc_control()
135*678453a8Sspeer * npi_txc_global_imask_set()
136*678453a8Sspeer * npi_txc_port_dma_enable()
137*678453a8Sspeer *
138*678453a8Sspeer * Registers accessed:
139*678453a8Sspeer * TXC_CONTROL
140*678453a8Sspeer * TXC_PORT_DMA
141*678453a8Sspeer * TXC_INT_MASK
142*678453a8Sspeer *
143*678453a8Sspeer * Context:
144*678453a8Sspeer * Service domain
145*678453a8Sspeer */
146*678453a8Sspeer nxge_status_t
nxge_txc_tdc_bind(p_nxge_t nxgep,int channel)147*678453a8Sspeer nxge_txc_tdc_bind(
148*678453a8Sspeer p_nxge_t nxgep,
149*678453a8Sspeer int channel)
150*678453a8Sspeer {
151*678453a8Sspeer uint8_t port;
152*678453a8Sspeer uint64_t bitmap;
153*678453a8Sspeer npi_handle_t handle;
154*678453a8Sspeer npi_status_t rs = NPI_SUCCESS;
155*678453a8Sspeer txc_control_t txc_control;
156*678453a8Sspeer
157*678453a8Sspeer port = NXGE_GET_PORT_NUM(nxgep->function_num);
158*678453a8Sspeer
159*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL,
160*678453a8Sspeer "==> nxge_txc_tdc_bind(port %d, channel %d)", port, channel));
161*678453a8Sspeer
162*678453a8Sspeer handle = NXGE_DEV_NPI_HANDLE(nxgep);
163*678453a8Sspeer
164*678453a8Sspeer /* Get the current value of TXC_CONTROL. */
165*678453a8Sspeer (void) npi_txc_control(handle, OP_GET, &txc_control);
166*678453a8Sspeer
167*678453a8Sspeer /* Mask all TXC interrupts for <port>. */
168*678453a8Sspeer if (txc_control.value & (1 << port)) {
169*678453a8Sspeer npi_txc_global_imask_set(handle, port, TXC_INT_MASK_IVAL);
170*678453a8Sspeer }
171*678453a8Sspeer
172*678453a8Sspeer /* Bind <channel> to <port>. */
173*678453a8Sspeer /* Read in the old bitmap. */
174*678453a8Sspeer TXC_FZC_CNTL_REG_READ64(handle, TXC_PORT_DMA_ENABLE_REG, port,
175*678453a8Sspeer &bitmap);
176*678453a8Sspeer
177*678453a8Sspeer if (bitmap & (1 << channel)) {
178*678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
179*678453a8Sspeer "nxge_txc_tdc_bind: channel %d already bound on port %d",
180*678453a8Sspeer channel, port));
181*678453a8Sspeer } else {
182*678453a8Sspeer /* Bind the new channel. */
183*678453a8Sspeer bitmap |= (1 << channel);
184*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL,
185*678453a8Sspeer "==> nxge_txc_tdc_bind(): bitmap = %lx", bitmap));
186*678453a8Sspeer
187*678453a8Sspeer /* Write out the new bitmap. */
188*678453a8Sspeer if ((rs = npi_txc_port_dma_enable(handle, port,
189*678453a8Sspeer (uint32_t)bitmap)) != NPI_SUCCESS) {
190*678453a8Sspeer goto fail;
191*678453a8Sspeer }
192*678453a8Sspeer }
193*678453a8Sspeer
194*678453a8Sspeer /* Enable this port, if necessary. */
195*678453a8Sspeer if (!(txc_control.value & (1 << port))) {
196*678453a8Sspeer if ((rs = npi_txc_port_enable(handle, port)) != NPI_SUCCESS) {
197*678453a8Sspeer goto fail;
198*678453a8Sspeer }
199*678453a8Sspeer }
200*678453a8Sspeer
201*678453a8Sspeer /*
202*678453a8Sspeer * Enable the TXC controller, if necessary.
203*678453a8Sspeer */
204*678453a8Sspeer if (txc_control.bits.ldw.txc_enabled == 0) {
205*678453a8Sspeer if ((rs = npi_txc_global_enable(handle)) != NPI_SUCCESS) {
206*678453a8Sspeer goto fail;
207*678453a8Sspeer }
208*678453a8Sspeer }
209*678453a8Sspeer
210*678453a8Sspeer /* Unmask all TXC interrupts on <port> */
211*678453a8Sspeer npi_txc_global_imask_set(handle, port, 0);
212*678453a8Sspeer
213*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL,
214*678453a8Sspeer "<== nxge_txc_tdc_bind(port %d, channel %d)", port, channel));
215*678453a8Sspeer
216*678453a8Sspeer return (NXGE_OK);
217*678453a8Sspeer fail:
218*678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
219*678453a8Sspeer "nxge_txc_tdc_bind(port %d, channel %d) failed", port, channel));
220*678453a8Sspeer
221*678453a8Sspeer return (NXGE_ERROR | rs);
222*678453a8Sspeer }
223*678453a8Sspeer
224*678453a8Sspeer /*
225*678453a8Sspeer * nxge_txc_tdc_unbind
226*678453a8Sspeer *
227*678453a8Sspeer * Unbind a TDC from a port.
228*678453a8Sspeer *
229*678453a8Sspeer * Arguments:
230*678453a8Sspeer * nxgep
231*678453a8Sspeer * channel The channel to unbind.
232*678453a8Sspeer *
233*678453a8Sspeer * Notes:
234*678453a8Sspeer *
235*678453a8Sspeer * NPI/NXGE function calls:
236*678453a8Sspeer * npi_txc_control()
237*678453a8Sspeer * npi_txc_global_imask_set()
238*678453a8Sspeer * npi_txc_port_dma_enable()
239*678453a8Sspeer *
240*678453a8Sspeer * Registers accessed:
241*678453a8Sspeer * TXC_CONTROL
242*678453a8Sspeer * TXC_PORT_DMA
243*678453a8Sspeer * TXC_INT_MASK
244*678453a8Sspeer *
245*678453a8Sspeer * Context:
246*678453a8Sspeer * Service domain
247*678453a8Sspeer */
248*678453a8Sspeer nxge_status_t
nxge_txc_tdc_unbind(p_nxge_t nxgep,int channel)249*678453a8Sspeer nxge_txc_tdc_unbind(
250*678453a8Sspeer p_nxge_t nxgep,
251*678453a8Sspeer int channel)
252*678453a8Sspeer {
253*678453a8Sspeer uint8_t port;
254*678453a8Sspeer uint64_t bitmap;
255*678453a8Sspeer npi_handle_t handle;
256*678453a8Sspeer npi_status_t rs = NPI_SUCCESS;
257*678453a8Sspeer
258*678453a8Sspeer handle = NXGE_DEV_NPI_HANDLE(nxgep);
259*678453a8Sspeer port = NXGE_GET_PORT_NUM(nxgep->function_num);
260*678453a8Sspeer
261*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL,
262*678453a8Sspeer "==> nxge_txc_tdc_unbind(port %d, channel %d)", port, channel));
263*678453a8Sspeer
264*678453a8Sspeer /* Mask all TXC interrupts for <port>. */
265*678453a8Sspeer npi_txc_global_imask_set(handle, port, TXC_INT_MASK_IVAL);
266*678453a8Sspeer
267*678453a8Sspeer /* Unbind <channel>. */
268*678453a8Sspeer /* Read in the old bitmap. */
269*678453a8Sspeer TXC_FZC_CNTL_REG_READ64(handle, TXC_PORT_DMA_ENABLE_REG, port,
270*678453a8Sspeer &bitmap);
271*678453a8Sspeer
272*678453a8Sspeer bitmap &= (~(1 << channel));
273*678453a8Sspeer
274*678453a8Sspeer /* Write out the new bitmap. */
275*678453a8Sspeer if ((rs = npi_txc_port_dma_enable(handle, port,
276*678453a8Sspeer (uint32_t)bitmap)) != NPI_SUCCESS) {
277*678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
278*678453a8Sspeer "npi_txc_port_dma_enable(%d, %d) failed: %x",
279*678453a8Sspeer port, channel, rs));
280*678453a8Sspeer }
281*678453a8Sspeer
282*678453a8Sspeer /* Unmask all TXC interrupts on <port> */
283*678453a8Sspeer if (bitmap)
284*678453a8Sspeer npi_txc_global_imask_set(handle, port, 0);
285*678453a8Sspeer
286*678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL,
287*678453a8Sspeer "<== nxge_txc_tdc_unbind(port %d, channel %d)", port, channel));
288*678453a8Sspeer
289*678453a8Sspeer return (NXGE_OK);
290*678453a8Sspeer fail:
291*678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
292*678453a8Sspeer "nxge_txc_tdc_unbind(port %d, channel %d) failed", port, channel));
293*678453a8Sspeer
294*678453a8Sspeer return (NXGE_ERROR | rs);
295*678453a8Sspeer }
296*678453a8Sspeer
2976f45ec7bSml29623 void
nxge_txc_regs_dump(p_nxge_t nxgep)2986f45ec7bSml29623 nxge_txc_regs_dump(p_nxge_t nxgep)
2996f45ec7bSml29623 {
3006f45ec7bSml29623 uint32_t cnt1, cnt2;
3016f45ec7bSml29623 npi_handle_t handle;
3026f45ec7bSml29623 txc_control_t control;
3036f45ec7bSml29623 uint32_t bitmap = 0;
3046f45ec7bSml29623
3056f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, TX_CTL, "\nTXC dump: func # %d:\n",
3066f45ec7bSml29623 nxgep->function_num));
3076f45ec7bSml29623
3086f45ec7bSml29623 handle = NXGE_DEV_NPI_HANDLE(nxgep);
3096f45ec7bSml29623
3106f45ec7bSml29623 (void) npi_txc_control(handle, OP_GET, &control);
3116f45ec7bSml29623 (void) npi_txc_port_dma_list_get(handle, nxgep->function_num, &bitmap);
3126f45ec7bSml29623
3136f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, TX_CTL, "\n\tTXC port control 0x%0llx",
3146f45ec7bSml29623 (long long)control.value));
3156f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, TX_CTL, "\n\tTXC port bitmap 0x%x", bitmap));
3166f45ec7bSml29623
3176f45ec7bSml29623 (void) npi_txc_pkt_xmt_to_mac_get(handle, nxgep->function_num,
3186f45ec7bSml29623 &cnt1, &cnt2);
3196f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, TX_CTL, "\n\tTXC bytes to MAC %d "
3206f45ec7bSml29623 "packets to MAC %d",
3216f45ec7bSml29623 cnt1, cnt2));
3226f45ec7bSml29623
3236f45ec7bSml29623 (void) npi_txc_pkt_stuffed_get(handle, nxgep->function_num,
3246f45ec7bSml29623 &cnt1, &cnt2);
3256f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, TX_CTL,
3266f45ec7bSml29623 "\n\tTXC ass packets %d reorder packets %d",
3276f45ec7bSml29623 cnt1 & 0xffff, cnt2 & 0xffff));
3286f45ec7bSml29623
3296f45ec7bSml29623 (void) npi_txc_reorder_get(handle, nxgep->function_num, &cnt1);
3306f45ec7bSml29623 NXGE_DEBUG_MSG((nxgep, TX_CTL,
3316f45ec7bSml29623 "\n\tTXC reorder resource %d", cnt1 & 0xff));
3326f45ec7bSml29623 }
3336f45ec7bSml29623
3346f45ec7bSml29623 nxge_status_t
nxge_txc_handle_sys_errors(p_nxge_t nxgep)3356f45ec7bSml29623 nxge_txc_handle_sys_errors(p_nxge_t nxgep)
3366f45ec7bSml29623 {
3376f45ec7bSml29623 npi_handle_t handle;
3386f45ec7bSml29623 txc_int_stat_t istatus;
3396f45ec7bSml29623 uint32_t err_status;
3406f45ec7bSml29623 uint8_t err_portn;
3416f45ec7bSml29623 boolean_t my_err = B_FALSE;
3426f45ec7bSml29623 nxge_status_t status = NXGE_OK;
3436f45ec7bSml29623
3446f45ec7bSml29623 handle = nxgep->npi_handle;
3456f45ec7bSml29623 npi_txc_global_istatus_get(handle, (txc_int_stat_t *)&istatus.value);
3466f45ec7bSml29623 switch (nxgep->mac.portnum) {
3476f45ec7bSml29623 case 0:
3486f45ec7bSml29623 if (istatus.bits.ldw.port0_int_status) {
3496f45ec7bSml29623 my_err = B_TRUE;
3506f45ec7bSml29623 err_portn = 0;
3516f45ec7bSml29623 err_status = istatus.bits.ldw.port0_int_status;
3526f45ec7bSml29623 }
3536f45ec7bSml29623 break;
3546f45ec7bSml29623 case 1:
3556f45ec7bSml29623 if (istatus.bits.ldw.port1_int_status) {
3566f45ec7bSml29623 my_err = B_TRUE;
3576f45ec7bSml29623 err_portn = 1;
3586f45ec7bSml29623 err_status = istatus.bits.ldw.port1_int_status;
3596f45ec7bSml29623 }
3606f45ec7bSml29623 break;
3616f45ec7bSml29623 case 2:
3626f45ec7bSml29623 if (istatus.bits.ldw.port2_int_status) {
3636f45ec7bSml29623 my_err = B_TRUE;
3646f45ec7bSml29623 err_portn = 2;
3656f45ec7bSml29623 err_status = istatus.bits.ldw.port2_int_status;
3666f45ec7bSml29623 }
3676f45ec7bSml29623 break;
3686f45ec7bSml29623 case 3:
3696f45ec7bSml29623 if (istatus.bits.ldw.port3_int_status) {
3706f45ec7bSml29623 my_err = B_TRUE;
3716f45ec7bSml29623 err_portn = 3;
3726f45ec7bSml29623 err_status = istatus.bits.ldw.port3_int_status;
3736f45ec7bSml29623 }
3746f45ec7bSml29623 break;
3756f45ec7bSml29623 default:
3766f45ec7bSml29623 return (NXGE_ERROR);
3776f45ec7bSml29623 }
3786f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3796f45ec7bSml29623 " nxge_txc_handle_sys_errors: errored port %d",
3806f45ec7bSml29623 err_portn));
3816f45ec7bSml29623 if (my_err) {
3826f45ec7bSml29623 status = nxge_txc_handle_port_errors(nxgep, err_status);
3836f45ec7bSml29623 }
3846f45ec7bSml29623
3856f45ec7bSml29623 return (status);
3866f45ec7bSml29623 }
3876f45ec7bSml29623
3886f45ec7bSml29623 static nxge_status_t
nxge_txc_handle_port_errors(p_nxge_t nxgep,uint32_t err_status)3896f45ec7bSml29623 nxge_txc_handle_port_errors(p_nxge_t nxgep, uint32_t err_status)
3906f45ec7bSml29623 {
3916f45ec7bSml29623 npi_handle_t handle;
3926f45ec7bSml29623 npi_status_t rs = NPI_SUCCESS;
3936f45ec7bSml29623 p_nxge_txc_stats_t statsp;
3946f45ec7bSml29623 txc_int_stat_t istatus;
3956f45ec7bSml29623 boolean_t txport_fatal = B_FALSE;
3966f45ec7bSml29623 uint8_t portn;
3976f45ec7bSml29623 nxge_status_t status = NXGE_OK;
3986f45ec7bSml29623
3996f45ec7bSml29623 handle = nxgep->npi_handle;
4006f45ec7bSml29623 statsp = (p_nxge_txc_stats_t)&nxgep->statsp->txc_stats;
4016f45ec7bSml29623 portn = nxgep->mac.portnum;
4026f45ec7bSml29623 istatus.value = 0;
4036f45ec7bSml29623
4046f45ec7bSml29623 if ((err_status & TXC_INT_STAT_RO_CORR_ERR) ||
4056f45ec7bSml29623 (err_status & TXC_INT_STAT_RO_CORR_ERR) ||
4066f45ec7bSml29623 (err_status & TXC_INT_STAT_RO_UNCORR_ERR) ||
4076f45ec7bSml29623 (err_status & TXC_INT_STAT_REORDER_ERR)) {
4086f45ec7bSml29623 if ((rs = npi_txc_ro_states_get(handle, portn,
4096f45ec7bSml29623 &statsp->errlog.ro_st)) != NPI_SUCCESS) {
4106f45ec7bSml29623 return (NXGE_ERROR | rs);
4116f45ec7bSml29623 }
4126f45ec7bSml29623
4136f45ec7bSml29623 if (err_status & TXC_INT_STAT_RO_CORR_ERR) {
4146f45ec7bSml29623 statsp->ro_correct_err++;
4156f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4166f45ec7bSml29623 NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR);
4176f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4186f45ec7bSml29623 "nxge_txc_err_evnts: "
4196f45ec7bSml29623 "RO FIFO correctable error"));
4206f45ec7bSml29623 }
4216f45ec7bSml29623 if (err_status & TXC_INT_STAT_RO_UNCORR_ERR) {
4226f45ec7bSml29623 statsp->ro_uncorrect_err++;
4236f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4246f45ec7bSml29623 NXGE_FM_EREPORT_TXC_RO_UNCORRECT_ERR);
4256f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4266f45ec7bSml29623 "nxge_txc_err_evnts: "
4276f45ec7bSml29623 "RO FIFO uncorrectable error"));
4286f45ec7bSml29623 }
4296f45ec7bSml29623 if (err_status & TXC_INT_STAT_REORDER_ERR) {
4306f45ec7bSml29623 statsp->reorder_err++;
4316f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4326f45ec7bSml29623 NXGE_FM_EREPORT_TXC_REORDER_ERR);
4336f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4346f45ec7bSml29623 "nxge_txc_err_evnts: "
4356f45ec7bSml29623 "fatal error: Reorder error"));
4366f45ec7bSml29623 txport_fatal = B_TRUE;
4376f45ec7bSml29623 }
4386f45ec7bSml29623
4396f45ec7bSml29623 if ((err_status & TXC_INT_STAT_RO_CORR_ERR) ||
4406f45ec7bSml29623 (err_status & TXC_INT_STAT_RO_CORR_ERR) ||
4416f45ec7bSml29623 (err_status & TXC_INT_STAT_RO_UNCORR_ERR)) {
4426f45ec7bSml29623
4436f45ec7bSml29623 if ((rs = npi_txc_ro_ecc_state_clr(handle, portn))
4446f45ec7bSml29623 != NPI_SUCCESS)
4456f45ec7bSml29623 return (NXGE_ERROR | rs);
4466f45ec7bSml29623 /*
4476f45ec7bSml29623 * Making sure that error source is cleared if this is
4486f45ec7bSml29623 * an injected error.
4496f45ec7bSml29623 */
4506f45ec7bSml29623 TXC_FZC_CNTL_REG_WRITE64(handle, TXC_ROECC_CTL_REG,
4516f45ec7bSml29623 portn, 0);
4526f45ec7bSml29623 }
4536f45ec7bSml29623 }
4546f45ec7bSml29623
4556f45ec7bSml29623 if ((err_status & TXC_INT_STAT_SF_CORR_ERR) ||
4566f45ec7bSml29623 (err_status & TXC_INT_STAT_SF_UNCORR_ERR)) {
4576f45ec7bSml29623 if ((rs = npi_txc_sf_states_get(handle, portn,
4586f45ec7bSml29623 &statsp->errlog.sf_st)) != NPI_SUCCESS) {
4596f45ec7bSml29623 return (NXGE_ERROR | rs);
4606f45ec7bSml29623 }
4616f45ec7bSml29623 if (err_status & TXC_INT_STAT_SF_CORR_ERR) {
4626f45ec7bSml29623 statsp->sf_correct_err++;
4636f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4646f45ec7bSml29623 NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR);
4656f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4666f45ec7bSml29623 "nxge_txc_err_evnts: "
4676f45ec7bSml29623 "SF FIFO correctable error"));
4686f45ec7bSml29623 }
4696f45ec7bSml29623 if (err_status & TXC_INT_STAT_SF_UNCORR_ERR) {
4706f45ec7bSml29623 statsp->sf_uncorrect_err++;
4716f45ec7bSml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4726f45ec7bSml29623 NXGE_FM_EREPORT_TXC_SF_UNCORRECT_ERR);
4736f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4746f45ec7bSml29623 "nxge_txc_err_evnts: "
4756f45ec7bSml29623 "SF FIFO uncorrectable error"));
4766f45ec7bSml29623 }
4776f45ec7bSml29623 if ((rs = npi_txc_sf_ecc_state_clr(handle, portn))
4786f45ec7bSml29623 != NPI_SUCCESS)
4796f45ec7bSml29623 return (NXGE_ERROR | rs);
4806f45ec7bSml29623 /*
4816f45ec7bSml29623 * Making sure that error source is cleared if this is
4826f45ec7bSml29623 * an injected error.
4836f45ec7bSml29623 */
4846f45ec7bSml29623 TXC_FZC_CNTL_REG_WRITE64(handle, TXC_SFECC_CTL_REG, portn, 0);
4856f45ec7bSml29623 }
4866f45ec7bSml29623
4876f45ec7bSml29623 /* Clear corresponding errors */
4886f45ec7bSml29623 switch (portn) {
4896f45ec7bSml29623 case 0:
4906f45ec7bSml29623 istatus.bits.ldw.port0_int_status = err_status;
4916f45ec7bSml29623 break;
4926f45ec7bSml29623 case 1:
4936f45ec7bSml29623 istatus.bits.ldw.port1_int_status = err_status;
4946f45ec7bSml29623 break;
4956f45ec7bSml29623 case 2:
4966f45ec7bSml29623 istatus.bits.ldw.port2_int_status = err_status;
4976f45ec7bSml29623 break;
4986f45ec7bSml29623 case 3:
4996f45ec7bSml29623 istatus.bits.ldw.port3_int_status = err_status;
5006f45ec7bSml29623 break;
5016f45ec7bSml29623 default:
5026f45ec7bSml29623 return (NXGE_ERROR);
5036f45ec7bSml29623 }
5046f45ec7bSml29623
5056f45ec7bSml29623 npi_txc_global_istatus_clear(handle, istatus.value);
5066f45ec7bSml29623
5076f45ec7bSml29623 if (txport_fatal) {
5086f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5096f45ec7bSml29623 " nxge_txc_handle_port_errors:"
5106f45ec7bSml29623 " fatal Error on Port#%d\n",
5116f45ec7bSml29623 portn));
5126f45ec7bSml29623 status = nxge_tx_port_fatal_err_recover(nxgep);
5136f45ec7bSml29623 if (status == NXGE_OK) {
5146f45ec7bSml29623 FM_SERVICE_RESTORED(nxgep);
5156f45ec7bSml29623 }
5166f45ec7bSml29623 }
5176f45ec7bSml29623
5186f45ec7bSml29623 return (status);
5196f45ec7bSml29623 }
5206f45ec7bSml29623
5216f45ec7bSml29623 void
nxge_txc_inject_err(p_nxge_t nxgep,uint32_t err_id)5226f45ec7bSml29623 nxge_txc_inject_err(p_nxge_t nxgep, uint32_t err_id)
5236f45ec7bSml29623 {
5246f45ec7bSml29623 txc_int_stat_dbg_t txcs;
5256f45ec7bSml29623 txc_roecc_ctl_t ro_ecc_ctl;
5266f45ec7bSml29623 txc_sfecc_ctl_t sf_ecc_ctl;
5276f45ec7bSml29623 uint8_t portn = nxgep->mac.portnum;
5286f45ec7bSml29623
5296f45ec7bSml29623 cmn_err(CE_NOTE, "!TXC error Inject\n");
5306f45ec7bSml29623 switch (err_id) {
5316f45ec7bSml29623 case NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR:
5326f45ec7bSml29623 case NXGE_FM_EREPORT_TXC_RO_UNCORRECT_ERR:
5336f45ec7bSml29623 ro_ecc_ctl.value = 0;
5346f45ec7bSml29623 ro_ecc_ctl.bits.ldw.all_pkts = 1;
5356f45ec7bSml29623 ro_ecc_ctl.bits.ldw.second_line_pkt = 1;
5366f45ec7bSml29623 if (err_id == NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR)
5376f45ec7bSml29623 ro_ecc_ctl.bits.ldw.single_bit_err = 1;
5386f45ec7bSml29623 else
5396f45ec7bSml29623 ro_ecc_ctl.bits.ldw.double_bit_err = 1;
540adfcba55Sjoycey #if defined(__i386)
541adfcba55Sjoycey cmn_err(CE_NOTE, "!Write 0x%llx to TXC_ROECC_CTL_REG\n",
542adfcba55Sjoycey ro_ecc_ctl.value);
543adfcba55Sjoycey #else
5446f45ec7bSml29623 cmn_err(CE_NOTE, "!Write 0x%lx to TXC_ROECC_CTL_REG\n",
5456f45ec7bSml29623 ro_ecc_ctl.value);
546adfcba55Sjoycey #endif
5476f45ec7bSml29623 TXC_FZC_CNTL_REG_WRITE64(nxgep->npi_handle, TXC_ROECC_CTL_REG,
5486f45ec7bSml29623 portn, ro_ecc_ctl.value);
5496f45ec7bSml29623 break;
5506f45ec7bSml29623 case NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR:
5516f45ec7bSml29623 case NXGE_FM_EREPORT_TXC_SF_UNCORRECT_ERR:
5526f45ec7bSml29623 sf_ecc_ctl.value = 0;
5536f45ec7bSml29623 sf_ecc_ctl.bits.ldw.all_pkts = 1;
5546f45ec7bSml29623 sf_ecc_ctl.bits.ldw.second_line_pkt = 1;
5556f45ec7bSml29623 if (err_id == NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR)
5566f45ec7bSml29623 sf_ecc_ctl.bits.ldw.single_bit_err = 1;
5576f45ec7bSml29623 else
5586f45ec7bSml29623 sf_ecc_ctl.bits.ldw.double_bit_err = 1;
559adfcba55Sjoycey #if defined(__i386)
560adfcba55Sjoycey cmn_err(CE_NOTE, "!Write 0x%llx to TXC_SFECC_CTL_REG\n",
561adfcba55Sjoycey sf_ecc_ctl.value);
562adfcba55Sjoycey #else
5636f45ec7bSml29623 cmn_err(CE_NOTE, "!Write 0x%lx to TXC_SFECC_CTL_REG\n",
5646f45ec7bSml29623 sf_ecc_ctl.value);
565adfcba55Sjoycey #endif
5666f45ec7bSml29623 TXC_FZC_CNTL_REG_WRITE64(nxgep->npi_handle, TXC_SFECC_CTL_REG,
5676f45ec7bSml29623 portn, sf_ecc_ctl.value);
5686f45ec7bSml29623 break;
5696f45ec7bSml29623 case NXGE_FM_EREPORT_TXC_REORDER_ERR:
5706f45ec7bSml29623 NXGE_REG_RD64(nxgep->npi_handle, TXC_INT_STAT_DBG_REG,
5716f45ec7bSml29623 &txcs.value);
5726f45ec7bSml29623 nxge_txc_inject_port_err(portn, &txcs,
5736f45ec7bSml29623 TXC_INT_STAT_REORDER_ERR);
574adfcba55Sjoycey #if defined(__i386)
575adfcba55Sjoycey cmn_err(CE_NOTE, "!Write 0x%llx to TXC_INT_STAT_DBG_REG\n",
576adfcba55Sjoycey txcs.value);
577adfcba55Sjoycey #else
5786f45ec7bSml29623 cmn_err(CE_NOTE, "!Write 0x%lx to TXC_INT_STAT_DBG_REG\n",
5796f45ec7bSml29623 txcs.value);
580adfcba55Sjoycey #endif
5816f45ec7bSml29623 NXGE_REG_WR64(nxgep->npi_handle, TXC_INT_STAT_DBG_REG,
5826f45ec7bSml29623 txcs.value);
5836f45ec7bSml29623 break;
5846f45ec7bSml29623 default:
5856f45ec7bSml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5866f45ec7bSml29623 "nxge_txc_inject_err: Unknown err_id"));
5876f45ec7bSml29623 }
5886f45ec7bSml29623 }
5896f45ec7bSml29623
5906f45ec7bSml29623 static void
nxge_txc_inject_port_err(uint8_t portn,txc_int_stat_dbg_t * txcs,uint8_t istats)5916f45ec7bSml29623 nxge_txc_inject_port_err(uint8_t portn, txc_int_stat_dbg_t *txcs,
5926f45ec7bSml29623 uint8_t istats)
5936f45ec7bSml29623 {
5946f45ec7bSml29623 switch (portn) {
5956f45ec7bSml29623 case 0:
5966f45ec7bSml29623 txcs->bits.ldw.port0_int_status |= istats;
5976f45ec7bSml29623 break;
5986f45ec7bSml29623 case 1:
5996f45ec7bSml29623 txcs->bits.ldw.port1_int_status |= istats;
6006f45ec7bSml29623 break;
6016f45ec7bSml29623 case 2:
6026f45ec7bSml29623 txcs->bits.ldw.port2_int_status |= istats;
6036f45ec7bSml29623 break;
6046f45ec7bSml29623 case 3:
6056f45ec7bSml29623 txcs->bits.ldw.port3_int_status |= istats;
6066f45ec7bSml29623 break;
6076f45ec7bSml29623 default:
6086f45ec7bSml29623 ;
6096f45ec7bSml29623 }
6106f45ec7bSml29623 }
611