hxge_hw.c revision 3dec9fcdd56adf1b4a563137b4915c8f2d83b881
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * CDDL HEADER START
23d366e350386ec109bfa9b2cf91225729a1a26bduboff * The contents of this file are subject to the terms of the
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Common Development and Distribution License (the "License").
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * You may not use this file except in compliance with the License.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * See the License for the specific language governing permissions
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * and limitations under the License.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * When distributing Covered Code, include this CDDL HEADER in each
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * If applicable, add the following below this CDDL HEADER, with the
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * fields enclosed by brackets "[]" replaced with your own identifying
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * information: Portions Copyright [yyyy] [name of copyright owner]
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * CDDL HEADER END
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Use is subject to license terms.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff#pragma ident "%Z%%M% %I% %E% SMI"
f8919bdadda3ebb97bd55cc14a16e0271ed57615dubofflb_property_t lb_normal = {normal, "normal", hxge_lb_normal};
f8919bdadda3ebb97bd55cc14a16e0271ed57615dubofflb_property_t lb_mac10g = {internal, "mac10g", hxge_lb_mac10g};
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffstatic void hxge_rtrace_ioctl(p_hxge_t, queue_t *, mblk_t *, struct iocblk *);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_global_reset"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_global_reset"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_hw_id_init"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Set up initial hardware parameters required such as mac mtu size.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* 1518 + 4 + 16 */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff hxgep->vmac.maxframesize = STD_FRAME_SIZE + TX_PKT_HEADER_SIZE;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (hxgep->param_arr[param_accept_jumbo].value || hxge_jumbo_enable) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_hw_id_init: maxframesize %d",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_hw_id_init"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_hw_init_niu_common"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, MOD_CTL, "hxge_hw_init_niu_common"
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff " already done for dip $%p exiting", hw_p->parent_devp));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "hxge_hw_init_niu_common Started for device id %x",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "hxge_hw_init_niu_common Done for device id %x",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_hw_init_niu_common"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * DDI interface returns second arg as NULL
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if ((arg2 == NULL) || ((void *) ldvp->hxgep != arg2)) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr: ldgvp $%p", ldgvp));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_ERROR_MSG((hxgep, INT_CTL, "<== hxge_intr: not ready"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * This interrupt handler will have to go through
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * all the logical devices to find out which
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * logical device interrupts us and then call
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * its handler to process the events.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr: #ldvs %d #intrs %d",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr(%d): #ldvs %d "
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* Get this group's flag bits. */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff rs = hpi_ldsv_ldfs_get(handle, t_ldgp->ldg, &vector0, &vector1);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Call device's handler if flag bits are on.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if ((LDV_ON(ldv, vector0) | (LDV_ON(ldv, vector1)))) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_intr: calling device %d"
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* rearm group interrupts */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_intr: serviced 0x%x",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff statsp = (p_hxge_peu_sys_stats_t)&hxgep->statsp->peu_sys_stats;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * The PCIE errors are unrecoverrable and cannot be cleared.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * The only thing we can do here is to mask them off to prevent
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * continued interrupts.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: spc_acc_err"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: tdc_pioacc_err"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: rdc_pioacc_err"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: pfc_pioacc_err"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: vmac_pioacc_err"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: cpl_hdrq_parerr"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: cpl_dataq_parerr"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: retryram_xdlh_parerr"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: retrysotram_xdlh_parerr"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: p_hdrq_parerr"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: p_dataq_parerr"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: np_hdrq_parerr"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: np_dataq_parerr"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: eic_msix_parerr"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_peu_handle_sys_errors: hcr_parerr"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/*ARGSUSED*/
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_syserr_intr: arg2 $%p arg1 $%p", hxgep, ldvp));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "<== hxge_syserrintr(no logical group): "
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Get the logical device state if the function uses interrupt.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* This interrupt handler is for system error interrupts. */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_syserr_intr: device error 0x%016llx", estat.value));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_syserr_intr: device error - TDMC"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff } else if (estat.bits.rdc_err0 || estat.bits.rdc_err1) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_syserr_intr: device error - RDMC"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff } else if (estat.bits.vnm_pio_err1 || estat.bits.peu_err1) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* PCI-E */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_syserr_intr: device error - PCI-E"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* kstats are updated here */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "==> hxge_syserr_intr: device error - unknown"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, SYSERR_CTL, "<== hxge_syserr_intr"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr_hw_enable"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_intr_hw_enable"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_intr_hw_disable"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_intr_hw_disable"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffhxge_rx_hw_blank(void *arg, time_t ticks, uint_t count)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, INT_CTL, "==> hxge_rx_hw_blank"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * Replace current ticks and counts for later
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * processing by the receive packet interrupt routines.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, INT_CTL, "<== hxge_rx_hw_blank"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_hw_stop"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_hw_stop"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffhxge_hw_ioctl(p_hxge_t hxgep, queue_t *wq, mblk_t *mp, struct iocblk *iocp)
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, IOC_CTL, "==> hxge_hw_ioctl"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff * 10G is the only loopback mode for Hydra.
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffhxge_loopback_ioctl(p_hxge_t hxgep, queue_t *wq, mblk_t *mp,
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, IOC_CTL, "HXGE_GET_LB_MODE command"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, IOC_CTL, "HXGE_SET_LB_MODE command"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if ((hxgep != NULL) && hxge_set_lb(hxgep, wq, mp->b_cont)) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, IOC_CTL, "LB_GET_INFO_SIZE command"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, IOC_CTL, "HXGE_GET_LB_INFO command"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff cmn_err(CE_NOTE, "hxge_hw_ioctl: invalid command 0x%x",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/*ARGSUSED*/
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "hxge%d: Loopback mode already set (lb_mode %d).\n",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff /* 10G is the only loopback mode for Hydra */
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "hxge%d: Loopback mode not supported(mode %d).\n",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "!hxge%d: Returning to normal operation",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff cmn_err(CE_NOTE, "!hxge%d: Adapter now in %s loopback mode",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if ((hxgep->statsp->port_stats.lb_mode == hxge_lb_mac10g))
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "hxge%d: Loopback mode not supported(mode %d).\n",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, SYSERR_CTL, "==> hxge_check_hw_state"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_ERROR_MSG((hxgep, SYSERR_CTL, "<== hxge_check_hw_state: "
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "NULL ldgvp (interrupt not ready)."));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, SYSERR_CTL, "<== hxge_check_hw_state: "
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "ldgvp $%p t_ldvp $%p use_timer flag %d",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (fm_check_acc_handle(hxgep->dev_regs->hxge_regh) != DDI_FM_OK) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "Bad register acc handle"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff (void) hxge_syserr_intr((caddr_t)t_ldvp, (caddr_t)hxgep);
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff hxgep->hxge_timerid = hxge_start_timer(hxgep, hxge_check_hw_state,
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, SYSERR_CTL, "<== hxge_check_hw_state"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff/*ARGSUSED*/
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboffhxge_rtrace_ioctl(p_hxge_t hxgep, queue_t *wq, mblk_t *mp,
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, STR_CTL, "==> hxge_rtrace_ioctl"));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff if (mp->b_cont == NULL || MBLKL(mp->b_cont) < size) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff "malformed M_IOCTL MBLKL = %d size = %d",
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, STR_CTL, "start_blk = %d\n", start_blk));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, STR_CTL, "num_entries = %d\n", num_entries));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, STR_CTL, "base_entry = %d\n", base_entry));
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff for (i = 0, j = base_entry; i < num_entries; i++, j++) {
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff rtp->buf[i].ctl_addr = hpi_rtracebuf.buf[j].ctl_addr;
f8919bdadda3ebb97bd55cc14a16e0271ed57615duboff HXGE_DEBUG_MSG((hxgep, STR_CTL, "<== hxge_rtrace_ioctl"));