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 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 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 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 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 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 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 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 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 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