13dec9fcdSqs148142 /* 23dec9fcdSqs148142 * CDDL HEADER START 33dec9fcdSqs148142 * 43dec9fcdSqs148142 * The contents of this file are subject to the terms of the 53dec9fcdSqs148142 * Common Development and Distribution License (the "License"). 63dec9fcdSqs148142 * You may not use this file except in compliance with the License. 73dec9fcdSqs148142 * 83dec9fcdSqs148142 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93dec9fcdSqs148142 * or http://www.opensolaris.org/os/licensing. 103dec9fcdSqs148142 * See the License for the specific language governing permissions 113dec9fcdSqs148142 * and limitations under the License. 123dec9fcdSqs148142 * 133dec9fcdSqs148142 * When distributing Covered Code, include this CDDL HEADER in each 143dec9fcdSqs148142 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153dec9fcdSqs148142 * If applicable, add the following below this CDDL HEADER, with the 163dec9fcdSqs148142 * fields enclosed by brackets "[]" replaced with your own identifying 173dec9fcdSqs148142 * information: Portions Copyright [yyyy] [name of copyright owner] 183dec9fcdSqs148142 * 193dec9fcdSqs148142 * CDDL HEADER END 203dec9fcdSqs148142 */ 213dec9fcdSqs148142 /* 221ed83081SMichael Speer * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 233dec9fcdSqs148142 * Use is subject to license terms. 243dec9fcdSqs148142 */ 253dec9fcdSqs148142 263dec9fcdSqs148142 #include <hxge_impl.h> 273dec9fcdSqs148142 283dec9fcdSqs148142 lb_property_t lb_normal = {normal, "normal", hxge_lb_normal}; 293dec9fcdSqs148142 lb_property_t lb_mac10g = {internal, "mac10g", hxge_lb_mac10g}; 303dec9fcdSqs148142 313dec9fcdSqs148142 uint32_t hxge_lb_dbg = 1; 323dec9fcdSqs148142 33a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States extern uint32_t hxge_jumbo_frame_size; 343dec9fcdSqs148142 353dec9fcdSqs148142 static void hxge_rtrace_ioctl(p_hxge_t, queue_t *, mblk_t *, struct iocblk *); 363dec9fcdSqs148142 373dec9fcdSqs148142 void 383dec9fcdSqs148142 hxge_global_reset(p_hxge_t hxgep) 393dec9fcdSqs148142 { 403dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_global_reset")); 413dec9fcdSqs148142 423dec9fcdSqs148142 (void) hxge_intr_hw_disable(hxgep); 433dec9fcdSqs148142 443dec9fcdSqs148142 if (hxgep->suspended) 453dec9fcdSqs148142 (void) hxge_link_init(hxgep); 463dec9fcdSqs148142 473dec9fcdSqs148142 (void) hxge_vmac_init(hxgep); 483dec9fcdSqs148142 493dec9fcdSqs148142 (void) hxge_intr_hw_enable(hxgep); 503dec9fcdSqs148142 513dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_global_reset")); 523dec9fcdSqs148142 } 533dec9fcdSqs148142 543dec9fcdSqs148142 553dec9fcdSqs148142 void 563dec9fcdSqs148142 hxge_hw_id_init(p_hxge_t hxgep) 573dec9fcdSqs148142 { 583dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_hw_id_init")); 593dec9fcdSqs148142 603dec9fcdSqs148142 /* 61a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * Initialize the frame size to either standard "1500 + 38" or 62a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * jumbo. The user may tune the frame size through the "mtu" parameter 63a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States * using "dladm set-linkprop" 643dec9fcdSqs148142 */ 65a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxgep->vmac.minframesize = MIN_FRAME_SIZE; 66a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxgep->vmac.maxframesize = HXGE_DEFAULT_MTU + MTU_TO_FRAME_SIZE; 67a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States if (hxgep->param_arr[param_accept_jumbo].value) 68a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States hxgep->vmac.maxframesize = (uint16_t)hxge_jumbo_frame_size; 69a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States 703dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_hw_id_init: maxframesize %d", 713dec9fcdSqs148142 hxgep->vmac.maxframesize)); 723dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_hw_id_init")); 733dec9fcdSqs148142 } 743dec9fcdSqs148142 753dec9fcdSqs148142 void 763dec9fcdSqs148142 hxge_hw_init_niu_common(p_hxge_t hxgep) 773dec9fcdSqs148142 { 783dec9fcdSqs148142 p_hxge_hw_list_t hw_p; 793dec9fcdSqs148142 803dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_hw_init_niu_common")); 813dec9fcdSqs148142 823dec9fcdSqs148142 if ((hw_p = hxgep->hxge_hw_p) == NULL) { 833dec9fcdSqs148142 return; 843dec9fcdSqs148142 } 853dec9fcdSqs148142 863dec9fcdSqs148142 MUTEX_ENTER(&hw_p->hxge_cfg_lock); 873dec9fcdSqs148142 if (hw_p->flags & COMMON_INIT_DONE) { 883dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, MOD_CTL, "hxge_hw_init_niu_common" 893dec9fcdSqs148142 " already done for dip $%p exiting", hw_p->parent_devp)); 903dec9fcdSqs148142 MUTEX_EXIT(&hw_p->hxge_cfg_lock); 913dec9fcdSqs148142 return; 923dec9fcdSqs148142 } 933dec9fcdSqs148142 943dec9fcdSqs148142 hw_p->flags = COMMON_INIT_START; 953dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, MOD_CTL, 963dec9fcdSqs148142 "hxge_hw_init_niu_common Started for device id %x", 973dec9fcdSqs148142 hw_p->parent_devp)); 983dec9fcdSqs148142 993dec9fcdSqs148142 (void) hxge_pfc_hw_reset(hxgep); 1003dec9fcdSqs148142 hw_p->flags = COMMON_INIT_DONE; 1013dec9fcdSqs148142 MUTEX_EXIT(&hw_p->hxge_cfg_lock); 1023dec9fcdSqs148142 1033dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, MOD_CTL, 1043dec9fcdSqs148142 "hxge_hw_init_niu_common Done for device id %x", 1053dec9fcdSqs148142 hw_p->parent_devp)); 1063dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_hw_init_niu_common")); 1073dec9fcdSqs148142 } 1083dec9fcdSqs148142 1093dec9fcdSqs148142 uint_t 1103dec9fcdSqs148142 hxge_intr(caddr_t arg1, caddr_t arg2) 1113dec9fcdSqs148142 { 1123dec9fcdSqs148142 p_hxge_ldv_t ldvp = (p_hxge_ldv_t)arg1; 1133dec9fcdSqs148142 p_hxge_t hxgep = (p_hxge_t)arg2; 1143dec9fcdSqs148142 uint8_t ldv; 1153dec9fcdSqs148142 hpi_handle_t handle; 1163dec9fcdSqs148142 p_hxge_ldgv_t ldgvp; 1173dec9fcdSqs148142 p_hxge_ldg_t ldgp, t_ldgp; 1183dec9fcdSqs148142 p_hxge_ldv_t t_ldvp; 1193dec9fcdSqs148142 uint32_t vector0 = 0, vector1 = 0; 120*6ffca240SMichael Speer int j, nldvs; 1213dec9fcdSqs148142 hpi_status_t rs = HPI_SUCCESS; 1223dec9fcdSqs148142 1233dec9fcdSqs148142 /* 1243dec9fcdSqs148142 * DDI interface returns second arg as NULL 1253dec9fcdSqs148142 */ 1263dec9fcdSqs148142 if ((arg2 == NULL) || ((void *) ldvp->hxgep != arg2)) { 1273dec9fcdSqs148142 hxgep = ldvp->hxgep; 1283dec9fcdSqs148142 } 1293dec9fcdSqs148142 1303dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr")); 1313dec9fcdSqs148142 132*6ffca240SMichael Speer if (hxgep->hxge_mac_state != HXGE_MAC_STARTED) { 1333dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, INT_CTL, 134*6ffca240SMichael Speer "<== hxge_intr: not initialized")); 135*6ffca240SMichael Speer return (DDI_INTR_UNCLAIMED); 1363dec9fcdSqs148142 } 1373dec9fcdSqs148142 1383dec9fcdSqs148142 ldgvp = hxgep->ldgvp; 1393dec9fcdSqs148142 1403dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr: ldgvp $%p", ldgvp)); 1413dec9fcdSqs148142 142*6ffca240SMichael Speer if (ldvp == NULL && ldgvp) 1433dec9fcdSqs148142 t_ldvp = ldvp = ldgvp->ldvp; 144*6ffca240SMichael Speer if (ldvp) 1453dec9fcdSqs148142 ldgp = t_ldgp = ldvp->ldgp; 1463dec9fcdSqs148142 1473dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr: " 1483dec9fcdSqs148142 "ldgvp $%p ldvp $%p ldgp $%p", ldgvp, ldvp, ldgp)); 1493dec9fcdSqs148142 1503dec9fcdSqs148142 if (ldgvp == NULL || ldvp == NULL || ldgp == NULL) { 1513dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, INT_CTL, "==> hxge_intr: " 1523dec9fcdSqs148142 "ldgvp $%p ldvp $%p ldgp $%p", ldgvp, ldvp, ldgp)); 1533dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, INT_CTL, "<== hxge_intr: not ready")); 1543dec9fcdSqs148142 return (DDI_INTR_UNCLAIMED); 1553dec9fcdSqs148142 } 1563dec9fcdSqs148142 1573dec9fcdSqs148142 /* 1583dec9fcdSqs148142 * This interrupt handler will have to go through 1593dec9fcdSqs148142 * all the logical devices to find out which 1603dec9fcdSqs148142 * logical device interrupts us and then call 1613dec9fcdSqs148142 * its handler to process the events. 1623dec9fcdSqs148142 */ 1633dec9fcdSqs148142 handle = HXGE_DEV_HPI_HANDLE(hxgep); 1643dec9fcdSqs148142 t_ldgp = ldgp; 1653dec9fcdSqs148142 t_ldvp = ldgp->ldvp; 1663dec9fcdSqs148142 nldvs = ldgp->nldvs; 1673dec9fcdSqs148142 1683dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr: #ldvs %d #intrs %d", 1693dec9fcdSqs148142 nldvs, ldgvp->ldg_intrs)); 170*6ffca240SMichael Speer HXGE_DEBUG_MSG((hxgep, INT_CTL, 171*6ffca240SMichael Speer "==> hxge_intr(%d): #ldvs %d", i, nldvs)); 1723dec9fcdSqs148142 173*6ffca240SMichael Speer /* 174*6ffca240SMichael Speer * Get this group's flag bits. 175*6ffca240SMichael Speer */ 1763dec9fcdSqs148142 t_ldgp->interrupted = B_FALSE; 1773dec9fcdSqs148142 rs = hpi_ldsv_ldfs_get(handle, t_ldgp->ldg, &vector0, &vector1); 178*6ffca240SMichael Speer if (rs != HPI_SUCCESS) 179*6ffca240SMichael Speer return (DDI_INTR_UNCLAIMED); 1803dec9fcdSqs148142 1813dec9fcdSqs148142 if (!vector0 && !vector1) { 1823dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr: " 1833dec9fcdSqs148142 "no interrupts on group %d", t_ldgp->ldg)); 184*6ffca240SMichael Speer return (DDI_INTR_UNCLAIMED); 1853dec9fcdSqs148142 } 1863dec9fcdSqs148142 1873dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr: " 1883dec9fcdSqs148142 "vector0 0x%llx vector1 0x%llx", vector0, vector1)); 1893dec9fcdSqs148142 1903dec9fcdSqs148142 t_ldgp->interrupted = B_TRUE; 1913dec9fcdSqs148142 nldvs = t_ldgp->nldvs; 1923dec9fcdSqs148142 193*6ffca240SMichael Speer /* 194*6ffca240SMichael Speer * Process all devices that share this group. 195*6ffca240SMichael Speer */ 1963dec9fcdSqs148142 for (j = 0; j < nldvs; j++, t_ldvp++) { 1973dec9fcdSqs148142 /* 1983dec9fcdSqs148142 * Call device's handler if flag bits are on. 1993dec9fcdSqs148142 */ 2003dec9fcdSqs148142 ldv = t_ldvp->ldv; 2013dec9fcdSqs148142 if ((LDV_ON(ldv, vector0) | (LDV_ON(ldv, vector1)))) { 2023dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, 2033dec9fcdSqs148142 "==> hxge_intr: calling device %d" 2043dec9fcdSqs148142 " #ldvs %d #intrs %d", j, nldvs, nintrs)); 2053dec9fcdSqs148142 (void) (t_ldvp->ldv_intr_handler)( 2063dec9fcdSqs148142 (caddr_t)t_ldvp, arg2); 2073dec9fcdSqs148142 } 2083dec9fcdSqs148142 } 2093dec9fcdSqs148142 210*6ffca240SMichael Speer /* 211*6ffca240SMichael Speer * Re-arm group interrupts 212*6ffca240SMichael Speer */ 2133dec9fcdSqs148142 if (t_ldgp->interrupted) { 2143dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, 2153dec9fcdSqs148142 "==> hxge_intr: arm group %d", t_ldgp->ldg)); 2163dec9fcdSqs148142 (void) hpi_intr_ldg_mgmt_set(handle, t_ldgp->ldg, 2173dec9fcdSqs148142 t_ldgp->arm, t_ldgp->ldg_timer); 2183dec9fcdSqs148142 } 2193dec9fcdSqs148142 220*6ffca240SMichael Speer HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_intr")); 221*6ffca240SMichael Speer return (DDI_INTR_CLAIMED); 2223dec9fcdSqs148142 } 2233dec9fcdSqs148142 2243dec9fcdSqs148142 hxge_status_t 2253dec9fcdSqs148142 hxge_peu_handle_sys_errors(p_hxge_t hxgep) 2263dec9fcdSqs148142 { 2273dec9fcdSqs148142 hpi_handle_t handle; 2283dec9fcdSqs148142 p_hxge_peu_sys_stats_t statsp; 2293dec9fcdSqs148142 peu_intr_stat_t stat; 2303dec9fcdSqs148142 2313dec9fcdSqs148142 handle = hxgep->hpi_handle; 2323dec9fcdSqs148142 statsp = (p_hxge_peu_sys_stats_t)&hxgep->statsp->peu_sys_stats; 2333dec9fcdSqs148142 234a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_RD32(handle, PEU_INTR_STAT, &stat.value); 2353dec9fcdSqs148142 2363dec9fcdSqs148142 /* 2373dec9fcdSqs148142 * The PCIE errors are unrecoverrable and cannot be cleared. 2383dec9fcdSqs148142 * The only thing we can do here is to mask them off to prevent 2393dec9fcdSqs148142 * continued interrupts. 2403dec9fcdSqs148142 */ 241a512c5d1SQiyan Sun - Sun Microsystems - San Diego United States HXGE_REG_WR32(handle, PEU_INTR_MASK, 0xffffffff); 2423dec9fcdSqs148142 2433dec9fcdSqs148142 if (stat.bits.spc_acc_err) { 2443dec9fcdSqs148142 statsp->spc_acc_err++; 2453dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 2463dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: spc_acc_err")); 2473dec9fcdSqs148142 } 2483dec9fcdSqs148142 2493dec9fcdSqs148142 if (stat.bits.tdc_pioacc_err) { 2503dec9fcdSqs148142 statsp->tdc_pioacc_err++; 2513dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 2523dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: tdc_pioacc_err")); 2533dec9fcdSqs148142 } 2543dec9fcdSqs148142 2553dec9fcdSqs148142 if (stat.bits.rdc_pioacc_err) { 2563dec9fcdSqs148142 statsp->rdc_pioacc_err++; 2573dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 2583dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: rdc_pioacc_err")); 2593dec9fcdSqs148142 } 2603dec9fcdSqs148142 2613dec9fcdSqs148142 if (stat.bits.pfc_pioacc_err) { 2623dec9fcdSqs148142 statsp->pfc_pioacc_err++; 2633dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 2643dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: pfc_pioacc_err")); 2653dec9fcdSqs148142 } 2663dec9fcdSqs148142 2673dec9fcdSqs148142 if (stat.bits.vmac_pioacc_err) { 2683dec9fcdSqs148142 statsp->vmac_pioacc_err++; 2693dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 2703dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: vmac_pioacc_err")); 2713dec9fcdSqs148142 } 2723dec9fcdSqs148142 2733dec9fcdSqs148142 if (stat.bits.cpl_hdrq_parerr) { 2743dec9fcdSqs148142 statsp->cpl_hdrq_parerr++; 2753dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 2763dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: cpl_hdrq_parerr")); 2773dec9fcdSqs148142 } 2783dec9fcdSqs148142 2793dec9fcdSqs148142 if (stat.bits.cpl_dataq_parerr) { 2803dec9fcdSqs148142 statsp->cpl_dataq_parerr++; 2813dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 2823dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: cpl_dataq_parerr")); 2833dec9fcdSqs148142 } 2843dec9fcdSqs148142 2853dec9fcdSqs148142 if (stat.bits.retryram_xdlh_parerr) { 2863dec9fcdSqs148142 statsp->retryram_xdlh_parerr++; 2873dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 2883dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: retryram_xdlh_parerr")); 2893dec9fcdSqs148142 } 2903dec9fcdSqs148142 2913dec9fcdSqs148142 if (stat.bits.retrysotram_xdlh_parerr) { 2923dec9fcdSqs148142 statsp->retrysotram_xdlh_parerr++; 2933dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 2943dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: retrysotram_xdlh_parerr")); 2953dec9fcdSqs148142 } 2963dec9fcdSqs148142 2973dec9fcdSqs148142 if (stat.bits.p_hdrq_parerr) { 2983dec9fcdSqs148142 statsp->p_hdrq_parerr++; 2993dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 3003dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: p_hdrq_parerr")); 3013dec9fcdSqs148142 } 3023dec9fcdSqs148142 3033dec9fcdSqs148142 if (stat.bits.p_dataq_parerr) { 3043dec9fcdSqs148142 statsp->p_dataq_parerr++; 3053dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 3063dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: p_dataq_parerr")); 3073dec9fcdSqs148142 } 3083dec9fcdSqs148142 3093dec9fcdSqs148142 if (stat.bits.np_hdrq_parerr) { 3103dec9fcdSqs148142 statsp->np_hdrq_parerr++; 3113dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 3123dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: np_hdrq_parerr")); 3133dec9fcdSqs148142 } 3143dec9fcdSqs148142 3153dec9fcdSqs148142 if (stat.bits.np_dataq_parerr) { 3163dec9fcdSqs148142 statsp->np_dataq_parerr++; 3173dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 3183dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: np_dataq_parerr")); 3193dec9fcdSqs148142 } 3203dec9fcdSqs148142 3213dec9fcdSqs148142 if (stat.bits.eic_msix_parerr) { 3223dec9fcdSqs148142 statsp->eic_msix_parerr++; 3233dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 3243dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: eic_msix_parerr")); 3253dec9fcdSqs148142 } 3263dec9fcdSqs148142 3273dec9fcdSqs148142 if (stat.bits.hcr_parerr) { 3283dec9fcdSqs148142 statsp->hcr_parerr++; 3293dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 3303dec9fcdSqs148142 "==> hxge_peu_handle_sys_errors: hcr_parerr")); 3313dec9fcdSqs148142 } 3323dec9fcdSqs148142 3331c29f7e3SQiyan Sun - Sun Microsystems - San Diego United States HXGE_FM_REPORT_ERROR(hxgep, NULL, HXGE_FM_EREPORT_PEU_ERR); 3343dec9fcdSqs148142 return (HXGE_OK); 3353dec9fcdSqs148142 } 3363dec9fcdSqs148142 3373dec9fcdSqs148142 /*ARGSUSED*/ 3383dec9fcdSqs148142 uint_t 3393dec9fcdSqs148142 hxge_syserr_intr(caddr_t arg1, caddr_t arg2) 3403dec9fcdSqs148142 { 3413dec9fcdSqs148142 p_hxge_ldv_t ldvp = (p_hxge_ldv_t)arg1; 3423dec9fcdSqs148142 p_hxge_t hxgep = (p_hxge_t)arg2; 3433dec9fcdSqs148142 p_hxge_ldg_t ldgp = NULL; 3443dec9fcdSqs148142 hpi_handle_t handle; 3453dec9fcdSqs148142 dev_err_stat_t estat; 3463dec9fcdSqs148142 3473dec9fcdSqs148142 if ((arg1 == NULL) && (arg2 == NULL)) { 348*6ffca240SMichael Speer return (DDI_INTR_UNCLAIMED); 3493dec9fcdSqs148142 } 3503dec9fcdSqs148142 3513dec9fcdSqs148142 if ((arg2 == NULL) || 3523dec9fcdSqs148142 ((ldvp != NULL) && ((void *)ldvp->hxgep != arg2))) { 3533dec9fcdSqs148142 if (ldvp != NULL) { 3543dec9fcdSqs148142 hxgep = ldvp->hxgep; 3553dec9fcdSqs148142 } 3563dec9fcdSqs148142 } 3573dec9fcdSqs148142 3583dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, SYSERR_CTL, 3593dec9fcdSqs148142 "==> hxge_syserr_intr: arg2 $%p arg1 $%p", hxgep, ldvp)); 3603dec9fcdSqs148142 3613dec9fcdSqs148142 if (ldvp != NULL && ldvp->use_timer == B_FALSE) { 3623dec9fcdSqs148142 ldgp = ldvp->ldgp; 3633dec9fcdSqs148142 if (ldgp == NULL) { 3643dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, SYSERR_CTL, 3653dec9fcdSqs148142 "<== hxge_syserrintr(no logical group): " 3663dec9fcdSqs148142 "arg2 $%p arg1 $%p", hxgep, ldvp)); 3673dec9fcdSqs148142 return (DDI_INTR_UNCLAIMED); 3683dec9fcdSqs148142 } 3693dec9fcdSqs148142 } 3703dec9fcdSqs148142 371*6ffca240SMichael Speer /* 372*6ffca240SMichael Speer * This interrupt handler is for system error interrupts. 373*6ffca240SMichael Speer */ 3743dec9fcdSqs148142 handle = HXGE_DEV_HPI_HANDLE(hxgep); 3753dec9fcdSqs148142 estat.value = 0; 3763dec9fcdSqs148142 (void) hpi_fzc_sys_err_stat_get(handle, &estat); 3773dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, SYSERR_CTL, 3783dec9fcdSqs148142 "==> hxge_syserr_intr: device error 0x%016llx", estat.value)); 3793dec9fcdSqs148142 3803dec9fcdSqs148142 if (estat.bits.tdc_err0 || estat.bits.tdc_err1) { 3813dec9fcdSqs148142 /* TDMC */ 3823a109ad9SQiyan Sun - Sun Microsystems - San Diego United States HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 3833a109ad9SQiyan Sun - Sun Microsystems - San Diego United States "==> hxge_syserr_intr: device error - TDMC")); 3843dec9fcdSqs148142 (void) hxge_txdma_handle_sys_errors(hxgep); 3853dec9fcdSqs148142 } else if (estat.bits.rdc_err0 || estat.bits.rdc_err1) { 3863dec9fcdSqs148142 /* RDMC */ 3873dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 3883dec9fcdSqs148142 "==> hxge_syserr_intr: device error - RDMC")); 3893dec9fcdSqs148142 (void) hxge_rxdma_handle_sys_errors(hxgep); 3903dec9fcdSqs148142 } else if (estat.bits.vnm_pio_err1 || estat.bits.peu_err1) { 3913dec9fcdSqs148142 /* PCI-E */ 3923dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 3933dec9fcdSqs148142 "==> hxge_syserr_intr: device error - PCI-E")); 3943dec9fcdSqs148142 3953dec9fcdSqs148142 /* kstats are updated here */ 3963dec9fcdSqs148142 (void) hxge_peu_handle_sys_errors(hxgep); 3973dec9fcdSqs148142 3983dec9fcdSqs148142 if (estat.bits.peu_err1) 3993dec9fcdSqs148142 HXGE_FM_REPORT_ERROR(hxgep, NULL, 4003dec9fcdSqs148142 HXGE_FM_EREPORT_PEU_ERR); 4013dec9fcdSqs148142 4023dec9fcdSqs148142 if (estat.bits.vnm_pio_err1) 4033dec9fcdSqs148142 HXGE_FM_REPORT_ERROR(hxgep, NULL, 4043dec9fcdSqs148142 HXGE_FM_EREPORT_PEU_VNM_PIO_ERR); 4053dec9fcdSqs148142 } else if (estat.value != 0) { 4063dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 4073dec9fcdSqs148142 "==> hxge_syserr_intr: device error - unknown")); 4083dec9fcdSqs148142 } 4093dec9fcdSqs148142 4103dec9fcdSqs148142 if ((ldgp != NULL) && (ldvp != NULL) && 4113dec9fcdSqs148142 (ldgp->nldvs == 1) && !ldvp->use_timer) { 4123dec9fcdSqs148142 (void) hpi_intr_ldg_mgmt_set(handle, ldgp->ldg, 4133dec9fcdSqs148142 B_TRUE, ldgp->ldg_timer); 4143dec9fcdSqs148142 } 4153dec9fcdSqs148142 4163dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, SYSERR_CTL, "<== hxge_syserr_intr")); 417*6ffca240SMichael Speer return (DDI_INTR_CLAIMED); 4183dec9fcdSqs148142 } 4193dec9fcdSqs148142 4203dec9fcdSqs148142 void 4213dec9fcdSqs148142 hxge_intr_hw_enable(p_hxge_t hxgep) 4223dec9fcdSqs148142 { 4233dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr_hw_enable")); 4243dec9fcdSqs148142 4253dec9fcdSqs148142 (void) hxge_intr_mask_mgmt_set(hxgep, B_TRUE); 4263dec9fcdSqs148142 4273dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_intr_hw_enable")); 4283dec9fcdSqs148142 } 4293dec9fcdSqs148142 4303dec9fcdSqs148142 void 4313dec9fcdSqs148142 hxge_intr_hw_disable(p_hxge_t hxgep) 4323dec9fcdSqs148142 { 4333dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr_hw_disable")); 4343dec9fcdSqs148142 4353dec9fcdSqs148142 (void) hxge_intr_mask_mgmt_set(hxgep, B_FALSE); 4363dec9fcdSqs148142 4373dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_intr_hw_disable")); 4383dec9fcdSqs148142 } 4393dec9fcdSqs148142 440676f0400SMichael Speer /*ARGSUSED*/ 4413dec9fcdSqs148142 void 4423dec9fcdSqs148142 hxge_rx_hw_blank(void *arg, time_t ticks, uint_t count) 4433dec9fcdSqs148142 { 4443dec9fcdSqs148142 p_hxge_t hxgep = (p_hxge_t)arg; 4453dec9fcdSqs148142 4463dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_rx_hw_blank")); 4473dec9fcdSqs148142 4483dec9fcdSqs148142 /* 4493dec9fcdSqs148142 * Replace current ticks and counts for later 4503dec9fcdSqs148142 * processing by the receive packet interrupt routines. 4513dec9fcdSqs148142 */ 4523dec9fcdSqs148142 hxgep->intr_timeout = (uint16_t)ticks; 4533dec9fcdSqs148142 4543dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_rx_hw_blank")); 4553dec9fcdSqs148142 } 4563dec9fcdSqs148142 4573dec9fcdSqs148142 void 4583dec9fcdSqs148142 hxge_hw_stop(p_hxge_t hxgep) 4593dec9fcdSqs148142 { 4603dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_hw_stop")); 4613dec9fcdSqs148142 4623dec9fcdSqs148142 (void) hxge_tx_vmac_disable(hxgep); 4633dec9fcdSqs148142 (void) hxge_rx_vmac_disable(hxgep); 4643dec9fcdSqs148142 (void) hxge_txdma_hw_mode(hxgep, HXGE_DMA_STOP); 4653dec9fcdSqs148142 (void) hxge_rxdma_hw_mode(hxgep, HXGE_DMA_STOP); 4663dec9fcdSqs148142 4673dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_hw_stop")); 4683dec9fcdSqs148142 } 4693dec9fcdSqs148142 4703dec9fcdSqs148142 void 4713dec9fcdSqs148142 hxge_hw_ioctl(p_hxge_t hxgep, queue_t *wq, mblk_t *mp, struct iocblk *iocp) 4723dec9fcdSqs148142 { 4733dec9fcdSqs148142 int cmd; 4743dec9fcdSqs148142 4753dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, "==> hxge_hw_ioctl")); 4763dec9fcdSqs148142 4773dec9fcdSqs148142 if (hxgep == NULL) { 4783dec9fcdSqs148142 miocnak(wq, mp, 0, EINVAL); 4793dec9fcdSqs148142 return; 4803dec9fcdSqs148142 } 4813dec9fcdSqs148142 4823dec9fcdSqs148142 iocp->ioc_error = 0; 4833dec9fcdSqs148142 cmd = iocp->ioc_cmd; 4843dec9fcdSqs148142 4853dec9fcdSqs148142 switch (cmd) { 4863dec9fcdSqs148142 default: 4873dec9fcdSqs148142 miocnak(wq, mp, 0, EINVAL); 4883dec9fcdSqs148142 return; 4893dec9fcdSqs148142 4903dec9fcdSqs148142 case HXGE_PUT_TCAM: 4913dec9fcdSqs148142 hxge_put_tcam(hxgep, mp->b_cont); 4923dec9fcdSqs148142 miocack(wq, mp, 0, 0); 4933dec9fcdSqs148142 break; 4943dec9fcdSqs148142 4953dec9fcdSqs148142 case HXGE_GET_TCAM: 4963dec9fcdSqs148142 hxge_get_tcam(hxgep, mp->b_cont); 4973dec9fcdSqs148142 miocack(wq, mp, 0, 0); 4983dec9fcdSqs148142 break; 4993dec9fcdSqs148142 5003dec9fcdSqs148142 case HXGE_RTRACE: 5013dec9fcdSqs148142 hxge_rtrace_ioctl(hxgep, wq, mp, iocp); 5023dec9fcdSqs148142 break; 5033dec9fcdSqs148142 } 5043dec9fcdSqs148142 } 5053dec9fcdSqs148142 5063dec9fcdSqs148142 /* 5073dec9fcdSqs148142 * 10G is the only loopback mode for Hydra. 5083dec9fcdSqs148142 */ 5093dec9fcdSqs148142 void 5103dec9fcdSqs148142 hxge_loopback_ioctl(p_hxge_t hxgep, queue_t *wq, mblk_t *mp, 5113dec9fcdSqs148142 struct iocblk *iocp) 5123dec9fcdSqs148142 { 5133dec9fcdSqs148142 p_lb_property_t lb_props; 5143dec9fcdSqs148142 size_t size; 5153dec9fcdSqs148142 int i; 5163dec9fcdSqs148142 5173dec9fcdSqs148142 if (mp->b_cont == NULL) { 5183dec9fcdSqs148142 miocnak(wq, mp, 0, EINVAL); 5193dec9fcdSqs148142 } 5203dec9fcdSqs148142 5213dec9fcdSqs148142 switch (iocp->ioc_cmd) { 5223dec9fcdSqs148142 case LB_GET_MODE: 5233dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, "HXGE_GET_LB_MODE command")); 5243dec9fcdSqs148142 if (hxgep != NULL) { 5253dec9fcdSqs148142 *(lb_info_sz_t *)mp->b_cont->b_rptr = 5263dec9fcdSqs148142 hxgep->statsp->port_stats.lb_mode; 5273dec9fcdSqs148142 miocack(wq, mp, sizeof (hxge_lb_t), 0); 5283dec9fcdSqs148142 } else 5293dec9fcdSqs148142 miocnak(wq, mp, 0, EINVAL); 5303dec9fcdSqs148142 break; 5313dec9fcdSqs148142 5323dec9fcdSqs148142 case LB_SET_MODE: 5333dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, "HXGE_SET_LB_MODE command")); 5343dec9fcdSqs148142 if (iocp->ioc_count != sizeof (uint32_t)) { 5353dec9fcdSqs148142 miocack(wq, mp, 0, 0); 5363dec9fcdSqs148142 break; 5373dec9fcdSqs148142 } 5383dec9fcdSqs148142 if ((hxgep != NULL) && hxge_set_lb(hxgep, wq, mp->b_cont)) { 5393dec9fcdSqs148142 miocack(wq, mp, 0, 0); 5403dec9fcdSqs148142 } else { 5413dec9fcdSqs148142 miocnak(wq, mp, 0, EPROTO); 5423dec9fcdSqs148142 } 5433dec9fcdSqs148142 break; 5443dec9fcdSqs148142 5453dec9fcdSqs148142 case LB_GET_INFO_SIZE: 5463dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, "LB_GET_INFO_SIZE command")); 5473dec9fcdSqs148142 if (hxgep != NULL) { 5483dec9fcdSqs148142 size = sizeof (lb_normal) + sizeof (lb_mac10g); 5493dec9fcdSqs148142 5503dec9fcdSqs148142 *(lb_info_sz_t *)mp->b_cont->b_rptr = size; 5513dec9fcdSqs148142 5523dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, 5533dec9fcdSqs148142 "HXGE_GET_LB_INFO command: size %d", size)); 5543dec9fcdSqs148142 miocack(wq, mp, sizeof (lb_info_sz_t), 0); 5553dec9fcdSqs148142 } else 5563dec9fcdSqs148142 miocnak(wq, mp, 0, EINVAL); 5573dec9fcdSqs148142 break; 5583dec9fcdSqs148142 5593dec9fcdSqs148142 case LB_GET_INFO: 5603dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, "HXGE_GET_LB_INFO command")); 5613dec9fcdSqs148142 if (hxgep != NULL) { 5623dec9fcdSqs148142 size = sizeof (lb_normal) + sizeof (lb_mac10g); 5633dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, 5643dec9fcdSqs148142 "HXGE_GET_LB_INFO command: size %d", size)); 5653dec9fcdSqs148142 if (size == iocp->ioc_count) { 5663dec9fcdSqs148142 i = 0; 5673dec9fcdSqs148142 lb_props = (p_lb_property_t)mp->b_cont->b_rptr; 5683dec9fcdSqs148142 lb_props[i++] = lb_normal; 5693dec9fcdSqs148142 lb_props[i++] = lb_mac10g; 5703dec9fcdSqs148142 5713dec9fcdSqs148142 miocack(wq, mp, size, 0); 5723dec9fcdSqs148142 } else 5733dec9fcdSqs148142 miocnak(wq, mp, 0, EINVAL); 5743dec9fcdSqs148142 } else { 5753dec9fcdSqs148142 miocnak(wq, mp, 0, EINVAL); 5763dec9fcdSqs148142 cmn_err(CE_NOTE, "hxge_hw_ioctl: invalid command 0x%x", 5773dec9fcdSqs148142 iocp->ioc_cmd); 5783dec9fcdSqs148142 } 5793dec9fcdSqs148142 5803dec9fcdSqs148142 break; 5813dec9fcdSqs148142 } 5823dec9fcdSqs148142 } 5833dec9fcdSqs148142 5843dec9fcdSqs148142 /*ARGSUSED*/ 5853dec9fcdSqs148142 boolean_t 5863dec9fcdSqs148142 hxge_set_lb(p_hxge_t hxgep, queue_t *wq, p_mblk_t mp) 5873dec9fcdSqs148142 { 5883dec9fcdSqs148142 boolean_t status = B_TRUE; 5893dec9fcdSqs148142 uint32_t lb_mode; 5903dec9fcdSqs148142 lb_property_t *lb_info; 5913dec9fcdSqs148142 5923dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, IOC_CTL, "<== hxge_set_lb")); 5933dec9fcdSqs148142 lb_mode = hxgep->statsp->port_stats.lb_mode; 5943dec9fcdSqs148142 if (lb_mode == *(uint32_t *)mp->b_rptr) { 5953dec9fcdSqs148142 cmn_err(CE_NOTE, 5963dec9fcdSqs148142 "hxge%d: Loopback mode already set (lb_mode %d).\n", 5973dec9fcdSqs148142 hxgep->instance, lb_mode); 5983dec9fcdSqs148142 status = B_FALSE; 5993dec9fcdSqs148142 goto hxge_set_lb_exit; 6003dec9fcdSqs148142 } 6013dec9fcdSqs148142 6023dec9fcdSqs148142 lb_mode = *(uint32_t *)mp->b_rptr; 6033dec9fcdSqs148142 lb_info = NULL; 6043dec9fcdSqs148142 6053dec9fcdSqs148142 /* 10G is the only loopback mode for Hydra */ 6063dec9fcdSqs148142 if (lb_mode == lb_normal.value) 6073dec9fcdSqs148142 lb_info = &lb_normal; 6083dec9fcdSqs148142 else if (lb_mode == lb_mac10g.value) 6093dec9fcdSqs148142 lb_info = &lb_mac10g; 6103dec9fcdSqs148142 else { 6113dec9fcdSqs148142 cmn_err(CE_NOTE, 6123dec9fcdSqs148142 "hxge%d: Loopback mode not supported(mode %d).\n", 6133dec9fcdSqs148142 hxgep->instance, lb_mode); 6143dec9fcdSqs148142 status = B_FALSE; 6153dec9fcdSqs148142 goto hxge_set_lb_exit; 6163dec9fcdSqs148142 } 6173dec9fcdSqs148142 6183dec9fcdSqs148142 if (lb_mode == hxge_lb_normal) { 6193dec9fcdSqs148142 if (hxge_lb_dbg) { 6203dec9fcdSqs148142 cmn_err(CE_NOTE, 6213dec9fcdSqs148142 "!hxge%d: Returning to normal operation", 6223dec9fcdSqs148142 hxgep->instance); 6233dec9fcdSqs148142 } 6243dec9fcdSqs148142 6253dec9fcdSqs148142 hxgep->statsp->port_stats.lb_mode = hxge_lb_normal; 6263dec9fcdSqs148142 hxge_global_reset(hxgep); 6273dec9fcdSqs148142 6283dec9fcdSqs148142 goto hxge_set_lb_exit; 6293dec9fcdSqs148142 } 6303dec9fcdSqs148142 6313dec9fcdSqs148142 hxgep->statsp->port_stats.lb_mode = lb_mode; 6323dec9fcdSqs148142 6333dec9fcdSqs148142 if (hxge_lb_dbg) 6343dec9fcdSqs148142 cmn_err(CE_NOTE, "!hxge%d: Adapter now in %s loopback mode", 6353dec9fcdSqs148142 hxgep->instance, lb_info->key); 6363dec9fcdSqs148142 6373dec9fcdSqs148142 if (lb_info->lb_type == internal) { 6383dec9fcdSqs148142 if ((hxgep->statsp->port_stats.lb_mode == hxge_lb_mac10g)) 6393dec9fcdSqs148142 hxgep->statsp->mac_stats.link_speed = 10000; 6403dec9fcdSqs148142 else { 6413dec9fcdSqs148142 cmn_err(CE_NOTE, 6423dec9fcdSqs148142 "hxge%d: Loopback mode not supported(mode %d).\n", 6433dec9fcdSqs148142 hxgep->instance, lb_mode); 6443dec9fcdSqs148142 status = B_FALSE; 6453dec9fcdSqs148142 goto hxge_set_lb_exit; 6463dec9fcdSqs148142 } 6473dec9fcdSqs148142 hxgep->statsp->mac_stats.link_duplex = 2; 6483dec9fcdSqs148142 hxgep->statsp->mac_stats.link_up = 1; 6493dec9fcdSqs148142 } 6503dec9fcdSqs148142 6513dec9fcdSqs148142 hxge_global_reset(hxgep); 6523dec9fcdSqs148142 6533dec9fcdSqs148142 hxge_set_lb_exit: 6543dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, DDI_CTL, 6553dec9fcdSqs148142 "<== hxge_set_lb status = 0x%08x", status)); 6563dec9fcdSqs148142 6573dec9fcdSqs148142 return (status); 6583dec9fcdSqs148142 } 6593dec9fcdSqs148142 6603dec9fcdSqs148142 void 6613dec9fcdSqs148142 hxge_check_hw_state(p_hxge_t hxgep) 6623dec9fcdSqs148142 { 6633dec9fcdSqs148142 p_hxge_ldgv_t ldgvp; 6643dec9fcdSqs148142 p_hxge_ldv_t t_ldvp; 6653dec9fcdSqs148142 6663dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, SYSERR_CTL, "==> hxge_check_hw_state")); 6673dec9fcdSqs148142 6683dec9fcdSqs148142 MUTEX_ENTER(hxgep->genlock); 6693dec9fcdSqs148142 6703dec9fcdSqs148142 hxgep->hxge_timerid = 0; 6713dec9fcdSqs148142 if (!(hxgep->drv_state & STATE_HW_INITIALIZED)) { 6723dec9fcdSqs148142 goto hxge_check_hw_state_exit; 6733dec9fcdSqs148142 } 6743dec9fcdSqs148142 6753dec9fcdSqs148142 hxge_check_tx_hang(hxgep); 6763dec9fcdSqs148142 6773dec9fcdSqs148142 ldgvp = hxgep->ldgvp; 6783dec9fcdSqs148142 if (ldgvp == NULL || (ldgvp->ldvp_syserr == NULL)) { 6793dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, SYSERR_CTL, "<== hxge_check_hw_state: " 6803dec9fcdSqs148142 "NULL ldgvp (interrupt not ready).")); 6813dec9fcdSqs148142 goto hxge_check_hw_state_exit; 6823dec9fcdSqs148142 } 6833dec9fcdSqs148142 6843dec9fcdSqs148142 t_ldvp = ldgvp->ldvp_syserr; 6853dec9fcdSqs148142 if (!t_ldvp->use_timer) { 6863dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, SYSERR_CTL, "<== hxge_check_hw_state: " 6873dec9fcdSqs148142 "ldgvp $%p t_ldvp $%p use_timer flag %d", 6883dec9fcdSqs148142 ldgvp, t_ldvp, t_ldvp->use_timer)); 6893dec9fcdSqs148142 goto hxge_check_hw_state_exit; 6903dec9fcdSqs148142 } 6913dec9fcdSqs148142 6923dec9fcdSqs148142 if (fm_check_acc_handle(hxgep->dev_regs->hxge_regh) != DDI_FM_OK) { 6933dec9fcdSqs148142 HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL, 6943dec9fcdSqs148142 "Bad register acc handle")); 6953dec9fcdSqs148142 } 6963dec9fcdSqs148142 6973dec9fcdSqs148142 (void) hxge_syserr_intr((caddr_t)t_ldvp, (caddr_t)hxgep); 6983dec9fcdSqs148142 6993dec9fcdSqs148142 hxgep->hxge_timerid = hxge_start_timer(hxgep, hxge_check_hw_state, 7003dec9fcdSqs148142 HXGE_CHECK_TIMER); 7013dec9fcdSqs148142 7023dec9fcdSqs148142 hxge_check_hw_state_exit: 7033dec9fcdSqs148142 MUTEX_EXIT(hxgep->genlock); 7043dec9fcdSqs148142 7053dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, SYSERR_CTL, "<== hxge_check_hw_state")); 7063dec9fcdSqs148142 } 7073dec9fcdSqs148142 7083dec9fcdSqs148142 /*ARGSUSED*/ 7093dec9fcdSqs148142 static void 7103dec9fcdSqs148142 hxge_rtrace_ioctl(p_hxge_t hxgep, queue_t *wq, mblk_t *mp, 7113dec9fcdSqs148142 struct iocblk *iocp) 7123dec9fcdSqs148142 { 7133dec9fcdSqs148142 ssize_t size; 7143dec9fcdSqs148142 rtrace_t *rtp; 7153dec9fcdSqs148142 mblk_t *nmp; 7163dec9fcdSqs148142 uint32_t i, j; 7173dec9fcdSqs148142 uint32_t start_blk; 7183dec9fcdSqs148142 uint32_t base_entry; 7193dec9fcdSqs148142 uint32_t num_entries; 7203dec9fcdSqs148142 7213dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, STR_CTL, "==> hxge_rtrace_ioctl")); 7223dec9fcdSqs148142 7233dec9fcdSqs148142 size = 1024; 7243dec9fcdSqs148142 if (mp->b_cont == NULL || MBLKL(mp->b_cont) < size) { 7253dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, STR_CTL, 7263dec9fcdSqs148142 "malformed M_IOCTL MBLKL = %d size = %d", 7273dec9fcdSqs148142 MBLKL(mp->b_cont), size)); 7283dec9fcdSqs148142 miocnak(wq, mp, 0, EINVAL); 7293dec9fcdSqs148142 return; 7303dec9fcdSqs148142 } 7313dec9fcdSqs148142 7323dec9fcdSqs148142 nmp = mp->b_cont; 7333dec9fcdSqs148142 rtp = (rtrace_t *)nmp->b_rptr; 7343dec9fcdSqs148142 start_blk = rtp->next_idx; 7353dec9fcdSqs148142 num_entries = rtp->last_idx; 7363dec9fcdSqs148142 base_entry = start_blk * MAX_RTRACE_IOC_ENTRIES; 7373dec9fcdSqs148142 7383dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, STR_CTL, "start_blk = %d\n", start_blk)); 7393dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, STR_CTL, "num_entries = %d\n", num_entries)); 7403dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, STR_CTL, "base_entry = %d\n", base_entry)); 7413dec9fcdSqs148142 7423dec9fcdSqs148142 rtp->next_idx = hpi_rtracebuf.next_idx; 7433dec9fcdSqs148142 rtp->last_idx = hpi_rtracebuf.last_idx; 7443dec9fcdSqs148142 rtp->wrapped = hpi_rtracebuf.wrapped; 7453dec9fcdSqs148142 for (i = 0, j = base_entry; i < num_entries; i++, j++) { 7463dec9fcdSqs148142 rtp->buf[i].ctl_addr = hpi_rtracebuf.buf[j].ctl_addr; 7473dec9fcdSqs148142 rtp->buf[i].val_l32 = hpi_rtracebuf.buf[j].val_l32; 7483dec9fcdSqs148142 rtp->buf[i].val_h32 = hpi_rtracebuf.buf[j].val_h32; 7493dec9fcdSqs148142 } 7503dec9fcdSqs148142 7513dec9fcdSqs148142 nmp->b_wptr = nmp->b_rptr + size; 7523dec9fcdSqs148142 HXGE_DEBUG_MSG((hxgep, STR_CTL, "<== hxge_rtrace_ioctl")); 7533dec9fcdSqs148142 miocack(wq, mp, (int)size, 0); 7543dec9fcdSqs148142 } 755