144961713Sgirish /* 244961713Sgirish * CDDL HEADER START 344961713Sgirish * 444961713Sgirish * The contents of this file are subject to the terms of the 544961713Sgirish * Common Development and Distribution License (the "License"). 644961713Sgirish * You may not use this file except in compliance with the License. 744961713Sgirish * 844961713Sgirish * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 944961713Sgirish * or http://www.opensolaris.org/os/licensing. 1044961713Sgirish * See the License for the specific language governing permissions 1144961713Sgirish * and limitations under the License. 1244961713Sgirish * 1344961713Sgirish * When distributing Covered Code, include this CDDL HEADER in each 1444961713Sgirish * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1544961713Sgirish * If applicable, add the following below this CDDL HEADER, with the 1644961713Sgirish * fields enclosed by brackets "[]" replaced with your own identifying 1744961713Sgirish * information: Portions Copyright [yyyy] [name of copyright owner] 1844961713Sgirish * 1944961713Sgirish * CDDL HEADER END 2044961713Sgirish */ 2144961713Sgirish /* 22678453a8Sspeer * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2344961713Sgirish * Use is subject to license terms. 2444961713Sgirish */ 2544961713Sgirish 2644961713Sgirish #pragma ident "%Z%%M% %I% %E% SMI" 2744961713Sgirish 2844961713Sgirish #include <sys/nxge/nxge_impl.h> 2944961713Sgirish #include <sys/nxge/nxge_txc.h> 3044961713Sgirish 3144961713Sgirish static nxge_status_t 3244961713Sgirish nxge_txc_handle_port_errors(p_nxge_t, uint32_t); 3344961713Sgirish static void 3444961713Sgirish nxge_txc_inject_port_err(uint8_t, txc_int_stat_dbg_t *, 3544961713Sgirish uint8_t istats); 3644961713Sgirish extern nxge_status_t nxge_tx_port_fatal_err_recover(p_nxge_t); 3744961713Sgirish 3844961713Sgirish nxge_status_t 3944961713Sgirish nxge_txc_init(p_nxge_t nxgep) 4044961713Sgirish { 4144961713Sgirish uint8_t port; 4244961713Sgirish npi_handle_t handle; 4344961713Sgirish npi_status_t rs = NPI_SUCCESS; 4444961713Sgirish 4544961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 4644961713Sgirish port = NXGE_GET_PORT_NUM(nxgep->function_num); 4744961713Sgirish 4844961713Sgirish NXGE_DEBUG_MSG((nxgep, TX_CTL, "==> nxge_txc_init: portn %d", port)); 4944961713Sgirish 5044961713Sgirish /* 5144961713Sgirish * Enable the TXC controller. 5244961713Sgirish */ 5344961713Sgirish if ((rs = npi_txc_global_enable(handle)) != NPI_SUCCESS) { 5444961713Sgirish goto fail; 5544961713Sgirish } 5644961713Sgirish 5744961713Sgirish /* Enable this port within the TXC. */ 5844961713Sgirish if ((rs = npi_txc_port_enable(handle, port)) != NPI_SUCCESS) { 5944961713Sgirish goto fail; 6044961713Sgirish } 6144961713Sgirish 6244961713Sgirish /* Bind DMA channels to this port. */ 6344961713Sgirish if ((rs = npi_txc_port_dma_enable(handle, port, 64*52ccf843Smisaki TXDMA_PORT_BITMAP(nxgep))) != NPI_SUCCESS) { 6544961713Sgirish goto fail; 6644961713Sgirish } 6744961713Sgirish 6844961713Sgirish /* Unmask all TXC interrupts */ 6944961713Sgirish npi_txc_global_imask_set(handle, port, 0); 7044961713Sgirish 7144961713Sgirish NXGE_DEBUG_MSG((nxgep, TX_CTL, "<== nxge_txc_init: portn %d", port)); 7244961713Sgirish 7344961713Sgirish return (NXGE_OK); 7444961713Sgirish fail: 7544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 76*52ccf843Smisaki "nxge_txc_init: Failed to initialize txc on port %d", 77*52ccf843Smisaki port)); 7844961713Sgirish 7944961713Sgirish return (NXGE_ERROR | rs); 8044961713Sgirish } 8144961713Sgirish 8244961713Sgirish nxge_status_t 8344961713Sgirish nxge_txc_uninit(p_nxge_t nxgep) 8444961713Sgirish { 8544961713Sgirish uint8_t port; 8644961713Sgirish npi_handle_t handle; 8744961713Sgirish npi_status_t rs = NPI_SUCCESS; 8844961713Sgirish 8944961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 9044961713Sgirish port = NXGE_GET_PORT_NUM(nxgep->function_num); 9144961713Sgirish 9244961713Sgirish NXGE_DEBUG_MSG((nxgep, TX_CTL, "==> nxge_txc_uninit: portn %d", port)); 9344961713Sgirish 9444961713Sgirish /* 9544961713Sgirish * disable the TXC controller. 9644961713Sgirish */ 9744961713Sgirish if ((rs = npi_txc_global_disable(handle)) != NPI_SUCCESS) { 9844961713Sgirish goto fail; 9944961713Sgirish } 10044961713Sgirish 10144961713Sgirish /* disable this port within the TXC. */ 10244961713Sgirish if ((rs = npi_txc_port_disable(handle, port)) != NPI_SUCCESS) { 10344961713Sgirish goto fail; 10444961713Sgirish } 10544961713Sgirish 10644961713Sgirish /* unbind DMA channels to this port. */ 10744961713Sgirish if ((rs = npi_txc_port_dma_enable(handle, port, 0)) != NPI_SUCCESS) { 10844961713Sgirish goto fail; 10944961713Sgirish } 11044961713Sgirish 11144961713Sgirish NXGE_DEBUG_MSG((nxgep, TX_CTL, "<== nxge_txc_uninit: portn %d", port)); 11244961713Sgirish 11344961713Sgirish return (NXGE_OK); 11444961713Sgirish fail: 11544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 116*52ccf843Smisaki "nxge_txc_init: Failed to initialize txc on port %d", 117*52ccf843Smisaki port)); 11844961713Sgirish 11944961713Sgirish return (NXGE_ERROR | rs); 12044961713Sgirish } 12144961713Sgirish 122678453a8Sspeer /* 123678453a8Sspeer * nxge_txc_tdc_bind 124678453a8Sspeer * 125678453a8Sspeer * Bind a TDC to a port. 126678453a8Sspeer * 127678453a8Sspeer * Arguments: 128678453a8Sspeer * nxgep 129678453a8Sspeer * channel The channel to bind. 130678453a8Sspeer * 131678453a8Sspeer * Notes: 132678453a8Sspeer * 133678453a8Sspeer * NPI/NXGE function calls: 134678453a8Sspeer * npi_txc_control() 135678453a8Sspeer * npi_txc_global_imask_set() 136678453a8Sspeer * npi_txc_port_dma_enable() 137678453a8Sspeer * 138678453a8Sspeer * Registers accessed: 139678453a8Sspeer * TXC_CONTROL 140678453a8Sspeer * TXC_PORT_DMA 141678453a8Sspeer * TXC_INT_MASK 142678453a8Sspeer * 143678453a8Sspeer * Context: 144678453a8Sspeer * Service domain 145678453a8Sspeer */ 146678453a8Sspeer nxge_status_t 147678453a8Sspeer nxge_txc_tdc_bind( 148678453a8Sspeer p_nxge_t nxgep, 149678453a8Sspeer int channel) 150678453a8Sspeer { 151678453a8Sspeer uint8_t port; 152678453a8Sspeer uint64_t bitmap; 153678453a8Sspeer npi_handle_t handle; 154678453a8Sspeer npi_status_t rs = NPI_SUCCESS; 155678453a8Sspeer txc_control_t txc_control; 156678453a8Sspeer 157678453a8Sspeer port = NXGE_GET_PORT_NUM(nxgep->function_num); 158678453a8Sspeer 159678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, 160678453a8Sspeer "==> nxge_txc_tdc_bind(port %d, channel %d)", port, channel)); 161678453a8Sspeer 162678453a8Sspeer handle = NXGE_DEV_NPI_HANDLE(nxgep); 163678453a8Sspeer 164678453a8Sspeer /* Get the current value of TXC_CONTROL. */ 165678453a8Sspeer (void) npi_txc_control(handle, OP_GET, &txc_control); 166678453a8Sspeer 167678453a8Sspeer /* Mask all TXC interrupts for <port>. */ 168678453a8Sspeer if (txc_control.value & (1 << port)) { 169678453a8Sspeer npi_txc_global_imask_set(handle, port, TXC_INT_MASK_IVAL); 170678453a8Sspeer } 171678453a8Sspeer 172678453a8Sspeer /* Bind <channel> to <port>. */ 173678453a8Sspeer /* Read in the old bitmap. */ 174678453a8Sspeer TXC_FZC_CNTL_REG_READ64(handle, TXC_PORT_DMA_ENABLE_REG, port, 175678453a8Sspeer &bitmap); 176678453a8Sspeer 177678453a8Sspeer if (bitmap & (1 << channel)) { 178678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 179678453a8Sspeer "nxge_txc_tdc_bind: channel %d already bound on port %d", 180*52ccf843Smisaki channel, port)); 181678453a8Sspeer } else { 182678453a8Sspeer /* Bind the new channel. */ 183678453a8Sspeer bitmap |= (1 << channel); 184678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, 185*52ccf843Smisaki "==> nxge_txc_tdc_bind(): bitmap = %lx", bitmap)); 186678453a8Sspeer 187678453a8Sspeer /* Write out the new bitmap. */ 188678453a8Sspeer if ((rs = npi_txc_port_dma_enable(handle, port, 189*52ccf843Smisaki (uint32_t)bitmap)) != NPI_SUCCESS) { 190678453a8Sspeer goto fail; 191678453a8Sspeer } 192678453a8Sspeer } 193678453a8Sspeer 194678453a8Sspeer /* Enable this port, if necessary. */ 195678453a8Sspeer if (!(txc_control.value & (1 << port))) { 196678453a8Sspeer if ((rs = npi_txc_port_enable(handle, port)) != NPI_SUCCESS) { 197678453a8Sspeer goto fail; 198678453a8Sspeer } 199678453a8Sspeer } 200678453a8Sspeer 201678453a8Sspeer /* 202678453a8Sspeer * Enable the TXC controller, if necessary. 203678453a8Sspeer */ 204678453a8Sspeer if (txc_control.bits.ldw.txc_enabled == 0) { 205678453a8Sspeer if ((rs = npi_txc_global_enable(handle)) != NPI_SUCCESS) { 206678453a8Sspeer goto fail; 207678453a8Sspeer } 208678453a8Sspeer } 209678453a8Sspeer 210678453a8Sspeer /* Unmask all TXC interrupts on <port> */ 211678453a8Sspeer npi_txc_global_imask_set(handle, port, 0); 212678453a8Sspeer 213678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, 214678453a8Sspeer "<== nxge_txc_tdc_bind(port %d, channel %d)", port, channel)); 215678453a8Sspeer 216678453a8Sspeer return (NXGE_OK); 217678453a8Sspeer fail: 218678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 219678453a8Sspeer "nxge_txc_tdc_bind(port %d, channel %d) failed", port, channel)); 220678453a8Sspeer 221678453a8Sspeer return (NXGE_ERROR | rs); 222678453a8Sspeer } 223678453a8Sspeer 224678453a8Sspeer /* 225678453a8Sspeer * nxge_txc_tdc_unbind 226678453a8Sspeer * 227678453a8Sspeer * Unbind a TDC from a port. 228678453a8Sspeer * 229678453a8Sspeer * Arguments: 230678453a8Sspeer * nxgep 231678453a8Sspeer * channel The channel to unbind. 232678453a8Sspeer * 233678453a8Sspeer * Notes: 234678453a8Sspeer * 235678453a8Sspeer * NPI/NXGE function calls: 236678453a8Sspeer * npi_txc_control() 237678453a8Sspeer * npi_txc_global_imask_set() 238678453a8Sspeer * npi_txc_port_dma_enable() 239678453a8Sspeer * 240678453a8Sspeer * Registers accessed: 241678453a8Sspeer * TXC_CONTROL 242678453a8Sspeer * TXC_PORT_DMA 243678453a8Sspeer * TXC_INT_MASK 244678453a8Sspeer * 245678453a8Sspeer * Context: 246678453a8Sspeer * Service domain 247678453a8Sspeer */ 248678453a8Sspeer nxge_status_t 249678453a8Sspeer nxge_txc_tdc_unbind( 250678453a8Sspeer p_nxge_t nxgep, 251678453a8Sspeer int channel) 252678453a8Sspeer { 253678453a8Sspeer uint8_t port; 254678453a8Sspeer uint64_t bitmap; 255678453a8Sspeer npi_handle_t handle; 256678453a8Sspeer npi_status_t rs = NPI_SUCCESS; 257678453a8Sspeer 258678453a8Sspeer handle = NXGE_DEV_NPI_HANDLE(nxgep); 259678453a8Sspeer port = NXGE_GET_PORT_NUM(nxgep->function_num); 260678453a8Sspeer 261678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, 262678453a8Sspeer "==> nxge_txc_tdc_unbind(port %d, channel %d)", port, channel)); 263678453a8Sspeer 264678453a8Sspeer /* Mask all TXC interrupts for <port>. */ 265678453a8Sspeer npi_txc_global_imask_set(handle, port, TXC_INT_MASK_IVAL); 266678453a8Sspeer 267678453a8Sspeer /* Unbind <channel>. */ 268678453a8Sspeer /* Read in the old bitmap. */ 269678453a8Sspeer TXC_FZC_CNTL_REG_READ64(handle, TXC_PORT_DMA_ENABLE_REG, port, 270678453a8Sspeer &bitmap); 271678453a8Sspeer 272678453a8Sspeer bitmap &= (~(1 << channel)); 273678453a8Sspeer 274678453a8Sspeer /* Write out the new bitmap. */ 275678453a8Sspeer if ((rs = npi_txc_port_dma_enable(handle, port, 276*52ccf843Smisaki (uint32_t)bitmap)) != NPI_SUCCESS) { 277678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 278678453a8Sspeer "npi_txc_port_dma_enable(%d, %d) failed: %x", 279*52ccf843Smisaki port, channel, rs)); 280678453a8Sspeer } 281678453a8Sspeer 282678453a8Sspeer /* Unmask all TXC interrupts on <port> */ 283678453a8Sspeer if (bitmap) 284678453a8Sspeer npi_txc_global_imask_set(handle, port, 0); 285678453a8Sspeer 286678453a8Sspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, 287678453a8Sspeer "<== nxge_txc_tdc_unbind(port %d, channel %d)", port, channel)); 288678453a8Sspeer 289678453a8Sspeer return (NXGE_OK); 290678453a8Sspeer fail: 291678453a8Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 292678453a8Sspeer "nxge_txc_tdc_unbind(port %d, channel %d) failed", port, channel)); 293678453a8Sspeer 294678453a8Sspeer return (NXGE_ERROR | rs); 295678453a8Sspeer } 296678453a8Sspeer 29744961713Sgirish void 29844961713Sgirish nxge_txc_regs_dump(p_nxge_t nxgep) 29944961713Sgirish { 30044961713Sgirish uint32_t cnt1, cnt2; 30144961713Sgirish npi_handle_t handle; 30244961713Sgirish txc_control_t control; 30344961713Sgirish uint32_t bitmap = 0; 30444961713Sgirish 305a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, "\nTXC dump: func # %d:\n", 306*52ccf843Smisaki nxgep->function_num)); 30744961713Sgirish 30844961713Sgirish handle = NXGE_DEV_NPI_HANDLE(nxgep); 30944961713Sgirish 31044961713Sgirish (void) npi_txc_control(handle, OP_GET, &control); 31144961713Sgirish (void) npi_txc_port_dma_list_get(handle, nxgep->function_num, &bitmap); 31244961713Sgirish 313a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, "\n\tTXC port control 0x%0llx", 314*52ccf843Smisaki (long long)control.value)); 315a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, "\n\tTXC port bitmap 0x%x", bitmap)); 31644961713Sgirish 31744961713Sgirish (void) npi_txc_pkt_xmt_to_mac_get(handle, nxgep->function_num, 31844961713Sgirish &cnt1, &cnt2); 319a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, "\n\tTXC bytes to MAC %d " 320*52ccf843Smisaki "packets to MAC %d", 321*52ccf843Smisaki cnt1, cnt2)); 32244961713Sgirish 32344961713Sgirish (void) npi_txc_pkt_stuffed_get(handle, nxgep->function_num, 324*52ccf843Smisaki &cnt1, &cnt2); 325a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, 326*52ccf843Smisaki "\n\tTXC ass packets %d reorder packets %d", 327*52ccf843Smisaki cnt1 & 0xffff, cnt2 & 0xffff)); 32844961713Sgirish 32944961713Sgirish (void) npi_txc_reorder_get(handle, nxgep->function_num, &cnt1); 330a3c5bd6dSspeer NXGE_DEBUG_MSG((nxgep, TX_CTL, 331*52ccf843Smisaki "\n\tTXC reorder resource %d", cnt1 & 0xff)); 33244961713Sgirish } 33344961713Sgirish 33444961713Sgirish nxge_status_t 33544961713Sgirish nxge_txc_handle_sys_errors(p_nxge_t nxgep) 33644961713Sgirish { 33744961713Sgirish npi_handle_t handle; 33844961713Sgirish txc_int_stat_t istatus; 33944961713Sgirish uint32_t err_status; 34044961713Sgirish uint8_t err_portn; 34144961713Sgirish boolean_t my_err = B_FALSE; 34244961713Sgirish nxge_status_t status = NXGE_OK; 34344961713Sgirish 34444961713Sgirish handle = nxgep->npi_handle; 34544961713Sgirish npi_txc_global_istatus_get(handle, (txc_int_stat_t *)&istatus.value); 34644961713Sgirish switch (nxgep->mac.portnum) { 34744961713Sgirish case 0: 34844961713Sgirish if (istatus.bits.ldw.port0_int_status) { 34944961713Sgirish my_err = B_TRUE; 35044961713Sgirish err_portn = 0; 35144961713Sgirish err_status = istatus.bits.ldw.port0_int_status; 35244961713Sgirish } 35344961713Sgirish break; 35444961713Sgirish case 1: 35544961713Sgirish if (istatus.bits.ldw.port1_int_status) { 35644961713Sgirish my_err = B_TRUE; 35744961713Sgirish err_portn = 1; 35844961713Sgirish err_status = istatus.bits.ldw.port1_int_status; 35944961713Sgirish } 36044961713Sgirish break; 36144961713Sgirish case 2: 36244961713Sgirish if (istatus.bits.ldw.port2_int_status) { 36344961713Sgirish my_err = B_TRUE; 36444961713Sgirish err_portn = 2; 36544961713Sgirish err_status = istatus.bits.ldw.port2_int_status; 36644961713Sgirish } 36744961713Sgirish break; 36844961713Sgirish case 3: 36944961713Sgirish if (istatus.bits.ldw.port3_int_status) { 37044961713Sgirish my_err = B_TRUE; 37144961713Sgirish err_portn = 3; 37244961713Sgirish err_status = istatus.bits.ldw.port3_int_status; 37344961713Sgirish } 37444961713Sgirish break; 37544961713Sgirish default: 37644961713Sgirish return (NXGE_ERROR); 37744961713Sgirish } 37844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 379*52ccf843Smisaki " nxge_txc_handle_sys_errors: errored port %d", 380*52ccf843Smisaki err_portn)); 38144961713Sgirish if (my_err) { 38244961713Sgirish status = nxge_txc_handle_port_errors(nxgep, err_status); 38344961713Sgirish } 38444961713Sgirish 38544961713Sgirish return (status); 38644961713Sgirish } 38744961713Sgirish 38844961713Sgirish static nxge_status_t 38944961713Sgirish nxge_txc_handle_port_errors(p_nxge_t nxgep, uint32_t err_status) 39044961713Sgirish { 39144961713Sgirish npi_handle_t handle; 39244961713Sgirish npi_status_t rs = NPI_SUCCESS; 39344961713Sgirish p_nxge_txc_stats_t statsp; 39444961713Sgirish txc_int_stat_t istatus; 39544961713Sgirish boolean_t txport_fatal = B_FALSE; 39644961713Sgirish uint8_t portn; 39744961713Sgirish nxge_status_t status = NXGE_OK; 39844961713Sgirish 39944961713Sgirish handle = nxgep->npi_handle; 40044961713Sgirish statsp = (p_nxge_txc_stats_t)&nxgep->statsp->txc_stats; 40144961713Sgirish portn = nxgep->mac.portnum; 40244961713Sgirish istatus.value = 0; 40344961713Sgirish 40444961713Sgirish if ((err_status & TXC_INT_STAT_RO_CORR_ERR) || 405*52ccf843Smisaki (err_status & TXC_INT_STAT_RO_CORR_ERR) || 406*52ccf843Smisaki (err_status & TXC_INT_STAT_RO_UNCORR_ERR) || 407*52ccf843Smisaki (err_status & TXC_INT_STAT_REORDER_ERR)) { 40844961713Sgirish if ((rs = npi_txc_ro_states_get(handle, portn, 409*52ccf843Smisaki &statsp->errlog.ro_st)) != NPI_SUCCESS) { 41044961713Sgirish return (NXGE_ERROR | rs); 41144961713Sgirish } 41244961713Sgirish 41344961713Sgirish if (err_status & TXC_INT_STAT_RO_CORR_ERR) { 41444961713Sgirish statsp->ro_correct_err++; 41544961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 416*52ccf843Smisaki NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR); 41744961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 418*52ccf843Smisaki "nxge_txc_err_evnts: " 419*52ccf843Smisaki "RO FIFO correctable error")); 42044961713Sgirish } 42144961713Sgirish if (err_status & TXC_INT_STAT_RO_UNCORR_ERR) { 42244961713Sgirish statsp->ro_uncorrect_err++; 42344961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 424*52ccf843Smisaki NXGE_FM_EREPORT_TXC_RO_UNCORRECT_ERR); 42544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 426*52ccf843Smisaki "nxge_txc_err_evnts: " 427*52ccf843Smisaki "RO FIFO uncorrectable error")); 42844961713Sgirish } 42944961713Sgirish if (err_status & TXC_INT_STAT_REORDER_ERR) { 43044961713Sgirish statsp->reorder_err++; 43144961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 432*52ccf843Smisaki NXGE_FM_EREPORT_TXC_REORDER_ERR); 43344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 434*52ccf843Smisaki "nxge_txc_err_evnts: " 435*52ccf843Smisaki "fatal error: Reorder error")); 43644961713Sgirish txport_fatal = B_TRUE; 43744961713Sgirish } 43844961713Sgirish 43944961713Sgirish if ((err_status & TXC_INT_STAT_RO_CORR_ERR) || 440*52ccf843Smisaki (err_status & TXC_INT_STAT_RO_CORR_ERR) || 441*52ccf843Smisaki (err_status & TXC_INT_STAT_RO_UNCORR_ERR)) { 44244961713Sgirish 44344961713Sgirish if ((rs = npi_txc_ro_ecc_state_clr(handle, portn)) 444*52ccf843Smisaki != NPI_SUCCESS) 44544961713Sgirish return (NXGE_ERROR | rs); 44644961713Sgirish /* 44744961713Sgirish * Making sure that error source is cleared if this is 44844961713Sgirish * an injected error. 44944961713Sgirish */ 45044961713Sgirish TXC_FZC_CNTL_REG_WRITE64(handle, TXC_ROECC_CTL_REG, 451*52ccf843Smisaki portn, 0); 45244961713Sgirish } 45344961713Sgirish } 45444961713Sgirish 45544961713Sgirish if ((err_status & TXC_INT_STAT_SF_CORR_ERR) || 456*52ccf843Smisaki (err_status & TXC_INT_STAT_SF_UNCORR_ERR)) { 45744961713Sgirish if ((rs = npi_txc_sf_states_get(handle, portn, 458*52ccf843Smisaki &statsp->errlog.sf_st)) != NPI_SUCCESS) { 45944961713Sgirish return (NXGE_ERROR | rs); 46044961713Sgirish } 46144961713Sgirish if (err_status & TXC_INT_STAT_SF_CORR_ERR) { 46244961713Sgirish statsp->sf_correct_err++; 46344961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 464*52ccf843Smisaki NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR); 46544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 466*52ccf843Smisaki "nxge_txc_err_evnts: " 467*52ccf843Smisaki "SF FIFO correctable error")); 46844961713Sgirish } 46944961713Sgirish if (err_status & TXC_INT_STAT_SF_UNCORR_ERR) { 47044961713Sgirish statsp->sf_uncorrect_err++; 47144961713Sgirish NXGE_FM_REPORT_ERROR(nxgep, portn, NULL, 472*52ccf843Smisaki NXGE_FM_EREPORT_TXC_SF_UNCORRECT_ERR); 47344961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 474*52ccf843Smisaki "nxge_txc_err_evnts: " 475*52ccf843Smisaki "SF FIFO uncorrectable error")); 47644961713Sgirish } 47744961713Sgirish if ((rs = npi_txc_sf_ecc_state_clr(handle, portn)) 478*52ccf843Smisaki != NPI_SUCCESS) 47944961713Sgirish return (NXGE_ERROR | rs); 48044961713Sgirish /* 48144961713Sgirish * Making sure that error source is cleared if this is 48244961713Sgirish * an injected error. 48344961713Sgirish */ 48444961713Sgirish TXC_FZC_CNTL_REG_WRITE64(handle, TXC_SFECC_CTL_REG, portn, 0); 48544961713Sgirish } 48644961713Sgirish 48744961713Sgirish /* Clear corresponding errors */ 48844961713Sgirish switch (portn) { 48944961713Sgirish case 0: 49044961713Sgirish istatus.bits.ldw.port0_int_status = err_status; 49144961713Sgirish break; 49244961713Sgirish case 1: 49344961713Sgirish istatus.bits.ldw.port1_int_status = err_status; 49444961713Sgirish break; 49544961713Sgirish case 2: 49644961713Sgirish istatus.bits.ldw.port2_int_status = err_status; 49744961713Sgirish break; 49844961713Sgirish case 3: 49944961713Sgirish istatus.bits.ldw.port3_int_status = err_status; 50044961713Sgirish break; 50144961713Sgirish default: 50244961713Sgirish return (NXGE_ERROR); 50344961713Sgirish } 50444961713Sgirish 50544961713Sgirish npi_txc_global_istatus_clear(handle, istatus.value); 50644961713Sgirish 50744961713Sgirish if (txport_fatal) { 50844961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 509*52ccf843Smisaki " nxge_txc_handle_port_errors:" 510*52ccf843Smisaki " fatal Error on Port#%d\n", 511*52ccf843Smisaki portn)); 51244961713Sgirish status = nxge_tx_port_fatal_err_recover(nxgep); 51344961713Sgirish if (status == NXGE_OK) { 51444961713Sgirish FM_SERVICE_RESTORED(nxgep); 51544961713Sgirish } 51644961713Sgirish } 51744961713Sgirish 51844961713Sgirish return (status); 51944961713Sgirish } 52044961713Sgirish 52144961713Sgirish void 52244961713Sgirish nxge_txc_inject_err(p_nxge_t nxgep, uint32_t err_id) 52344961713Sgirish { 52444961713Sgirish txc_int_stat_dbg_t txcs; 52544961713Sgirish txc_roecc_ctl_t ro_ecc_ctl; 52644961713Sgirish txc_sfecc_ctl_t sf_ecc_ctl; 52744961713Sgirish uint8_t portn = nxgep->mac.portnum; 52844961713Sgirish 52944961713Sgirish cmn_err(CE_NOTE, "!TXC error Inject\n"); 53044961713Sgirish switch (err_id) { 53144961713Sgirish case NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR: 53244961713Sgirish case NXGE_FM_EREPORT_TXC_RO_UNCORRECT_ERR: 53344961713Sgirish ro_ecc_ctl.value = 0; 53444961713Sgirish ro_ecc_ctl.bits.ldw.all_pkts = 1; 53544961713Sgirish ro_ecc_ctl.bits.ldw.second_line_pkt = 1; 53644961713Sgirish if (err_id == NXGE_FM_EREPORT_TXC_RO_CORRECT_ERR) 53744961713Sgirish ro_ecc_ctl.bits.ldw.single_bit_err = 1; 53844961713Sgirish else 53944961713Sgirish 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", 542*52ccf843Smisaki ro_ecc_ctl.value); 543adfcba55Sjoycey #else 54444961713Sgirish cmn_err(CE_NOTE, "!Write 0x%lx to TXC_ROECC_CTL_REG\n", 545*52ccf843Smisaki ro_ecc_ctl.value); 546adfcba55Sjoycey #endif 54744961713Sgirish TXC_FZC_CNTL_REG_WRITE64(nxgep->npi_handle, TXC_ROECC_CTL_REG, 548*52ccf843Smisaki portn, ro_ecc_ctl.value); 54944961713Sgirish break; 55044961713Sgirish case NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR: 55144961713Sgirish case NXGE_FM_EREPORT_TXC_SF_UNCORRECT_ERR: 55244961713Sgirish sf_ecc_ctl.value = 0; 55344961713Sgirish sf_ecc_ctl.bits.ldw.all_pkts = 1; 55444961713Sgirish sf_ecc_ctl.bits.ldw.second_line_pkt = 1; 55544961713Sgirish if (err_id == NXGE_FM_EREPORT_TXC_SF_CORRECT_ERR) 55644961713Sgirish sf_ecc_ctl.bits.ldw.single_bit_err = 1; 55744961713Sgirish else 55844961713Sgirish 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", 561*52ccf843Smisaki sf_ecc_ctl.value); 562adfcba55Sjoycey #else 56344961713Sgirish cmn_err(CE_NOTE, "!Write 0x%lx to TXC_SFECC_CTL_REG\n", 564*52ccf843Smisaki sf_ecc_ctl.value); 565adfcba55Sjoycey #endif 56644961713Sgirish TXC_FZC_CNTL_REG_WRITE64(nxgep->npi_handle, TXC_SFECC_CTL_REG, 567*52ccf843Smisaki portn, sf_ecc_ctl.value); 56844961713Sgirish break; 56944961713Sgirish case NXGE_FM_EREPORT_TXC_REORDER_ERR: 57044961713Sgirish NXGE_REG_RD64(nxgep->npi_handle, TXC_INT_STAT_DBG_REG, 571*52ccf843Smisaki &txcs.value); 57244961713Sgirish nxge_txc_inject_port_err(portn, &txcs, 573*52ccf843Smisaki TXC_INT_STAT_REORDER_ERR); 574adfcba55Sjoycey #if defined(__i386) 575adfcba55Sjoycey cmn_err(CE_NOTE, "!Write 0x%llx to TXC_INT_STAT_DBG_REG\n", 576*52ccf843Smisaki txcs.value); 577adfcba55Sjoycey #else 57844961713Sgirish cmn_err(CE_NOTE, "!Write 0x%lx to TXC_INT_STAT_DBG_REG\n", 579*52ccf843Smisaki txcs.value); 580adfcba55Sjoycey #endif 58144961713Sgirish NXGE_REG_WR64(nxgep->npi_handle, TXC_INT_STAT_DBG_REG, 582*52ccf843Smisaki txcs.value); 58344961713Sgirish break; 58444961713Sgirish default: 58544961713Sgirish NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 586*52ccf843Smisaki "nxge_txc_inject_err: Unknown err_id")); 58744961713Sgirish } 58844961713Sgirish } 58944961713Sgirish 59044961713Sgirish static void 59144961713Sgirish nxge_txc_inject_port_err(uint8_t portn, txc_int_stat_dbg_t *txcs, 59244961713Sgirish uint8_t istats) 59344961713Sgirish { 59444961713Sgirish switch (portn) { 59544961713Sgirish case 0: 59644961713Sgirish txcs->bits.ldw.port0_int_status |= istats; 59744961713Sgirish break; 59844961713Sgirish case 1: 59944961713Sgirish txcs->bits.ldw.port1_int_status |= istats; 60044961713Sgirish break; 60144961713Sgirish case 2: 60244961713Sgirish txcs->bits.ldw.port2_int_status |= istats; 60344961713Sgirish break; 60444961713Sgirish case 3: 60544961713Sgirish txcs->bits.ldw.port3_int_status |= istats; 60644961713Sgirish break; 60744961713Sgirish default: 60844961713Sgirish ; 60944961713Sgirish } 61044961713Sgirish } 611