FreeBSD/sys/dev/ixl/ixl_pf_main.c
/*********************************************************************
 *
 *  MSIX Admin Queue Interrupt Service routine
 *
 **********************************************************************/
MSIX Admin Queue Interrupt Service routine
MSIX Admin Queue Interrupt Service routine
void
ixl_msix_adminq(void *arg)
{
	struct ixl_pf	*pf = arg;
	struct i40e_hw	*hw = &pf->hw;
	device_t	dev = pf->dev;
	u32		reg, mask, rstat_reg;
	bool		do_task = FALSE;
	++pf->admin_irq;
	reg = rd32(hw, I40E_PFINT_ICR0);
	mask = rd32(hw, I40E_PFINT_ICR0_ENA);
	if (reg & I40E_PFINT_ICR0_ADMINQ_MASK) {
		mask &= ~I40E_PFINT_ICR0_ADMINQ_MASK;
		do_task = TRUE;
	}
	if (reg & I40E_PFINT_ICR0_MAL_DETECT_MASK) {
		ixl_handle_mdd_event(pf);
		mask &= ~I40E_PFINT_ICR0_MAL_DETECT_MASK;
	}
	if (reg & I40E_PFINT_ICR0_GRST_MASK) {
		device_printf(dev, "Reset Requested!\n");
		rstat_reg = rd32(hw, I40E_GLGEN_RSTAT);
		rstat_reg = (rstat_reg & I40E_GLGEN_RSTAT_RESET_TYPE_MASK)
		    >> I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT;
		device_printf(dev, "Reset type: ");
		switch (rstat_reg) {
		case I40E_RESET_CORER:
			printf("CORER\n");
			break;
		case I40E_RESET_GLOBR:
			printf("GLOBR\n");
			break;
		case I40E_RESET_EMPR:
			printf("EMPR\n");
			atomic_set_int(&pf->state, IXL_PF_STATE_EMPR_RESETTING);
			break;
		default:
			printf("POR\n");
			break;
		}
		do_task = TRUE;
	}
	if (reg & I40E_PFINT_ICR0_ECC_ERR_MASK) {
		device_printf(dev, "ECC Error detected!\n");
	}
	if (reg & I40E_PFINT_ICR0_HMC_ERR_MASK) {
		reg = rd32(hw, I40E_PFHMC_ERRORINFO);
		if (reg & I40E_PFHMC_ERRORINFO_ERROR_DETECTED_MASK) {
			device_printf(dev, "HMC Error detected!\n");
			device_printf(dev, "INFO 0x%08x\n", reg);
			reg = rd32(hw, I40E_PFHMC_ERRORDATA);
			device_printf(dev, "DATA 0x%08x\n", reg);
			wr32(hw, I40E_PFHMC_ERRORINFO, 0);
		}
	}
	if (reg & I40E_PFINT_ICR0_PCI_EXCEPTION_MASK) {
		device_printf(dev, "PCI Exception detected!\n");
	}
#ifdef PCI_IOV
	if (reg & I40E_PFINT_ICR0_VFLR_MASK) {
		mask &= ~I40E_PFINT_ICR0_ENA_VFLR_MASK;
		taskqueue_enqueue(pf->tq, &pf->vflr_task);
	}
#endif
	if (do_task)
		taskqueue_enqueue(pf->tq, &pf->adminq);
	else
		ixl_enable_adminq(hw);
}
void ixl_msix_adminq ( void * arg ) { struct ixl_pf * pf = arg ; struct i40e_hw * hw = & pf -> hw ; device_t dev = pf -> dev ; u32 reg , mask , rstat_reg ; bool do_task = FALSE ; ++ pf -> admin_irq ; reg = rd32 ( hw , I40E_PFINT_ICR0 ) ; mask = rd32 ( hw , I40E_PFINT_ICR0_ENA ) ; if ( reg & I40E_PFINT_ICR0_ADMINQ_MASK ) { mask &= ~ I40E_PFINT_ICR0_ADMINQ_MASK ; do_task = TRUE ; } if ( reg & I40E_PFINT_ICR0_MAL_DETECT_MASK ) { ixl_handle_mdd_event ( pf ) ; mask &= ~ I40E_PFINT_ICR0_MAL_DETECT_MASK ; } if ( reg & I40E_PFINT_ICR0_GRST_MASK ) { device_printf ( dev , " \n " ) ; rstat_reg = rd32 ( hw , I40E_GLGEN_RSTAT ) ; rstat_reg = ( rstat_reg & I40E_GLGEN_RSTAT_RESET_TYPE_MASK ) >> I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT ; device_printf ( dev , " " ) ; switch ( rstat_reg ) { case I40E_RESET_CORER : printf ( " \n " ) ; break ; case I40E_RESET_GLOBR : printf ( " \n " ) ; break ; case I40E_RESET_EMPR : printf ( " \n " ) ; atomic_set_int ( & pf -> state , IXL_PF_STATE_EMPR_RESETTING ) ; break ; default : printf ( " \n " ) ; break ; } do_task = TRUE ; } if ( reg & I40E_PFINT_ICR0_ECC_ERR_MASK ) { device_printf ( dev , " \n " ) ; } if ( reg & I40E_PFINT_ICR0_HMC_ERR_MASK ) { reg = rd32 ( hw , I40E_PFHMC_ERRORINFO ) ; if ( reg & I40E_PFHMC_ERRORINFO_ERROR_DETECTED_MASK ) { device_printf ( dev , " \n " ) ; device_printf ( dev , " \n " , reg ) ; reg = rd32 ( hw , I40E_PFHMC_ERRORDATA ) ; device_printf ( dev , " \n " , reg ) ; wr32 ( hw , I40E_PFHMC_ERRORINFO , 0 ) ; } } if ( reg & I40E_PFINT_ICR0_PCI_EXCEPTION_MASK ) { device_printf ( dev , " \n " ) ; } #ifdef PCI_IOV if ( reg & I40E_PFINT_ICR0_VFLR_MASK ) { mask &= ~ I40E_PFINT_ICR0_ENA_VFLR_MASK ; taskqueue_enqueue ( pf -> tq , & pf -> vflr_task ) ; } #endif if ( do_task ) taskqueue_enqueue ( pf -> tq , & pf -> adminq ) ; else ixl_enable_adminq ( hw ) ; }
MSIX Admin Queue Interrupt Service routine
MSIX Admin Queue Interrupt Service routine
/* Check on the cause */ /* These others might be handled similarly to an EMPR reset */ /* overload admin queue task to check reset progress */