diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c --- a/sys/dev/ixl/if_ixl.c +++ b/sys/dev/ixl/if_ixl.c @@ -466,7 +466,8 @@ } } - /* Fire off the admin task */ + /* Ensure that all events in Admin Receive Queue are processed */ + ixl_set_state(&pf->state, IXL_STATE_ADMINQ_PENDING); iflib_admin_intr_deferred(pf->vsi.ctx); /* Reschedule the admin timer */ @@ -1423,6 +1424,9 @@ free(event.msg_buf, M_IXL); + if (*pending == 0) + ixl_clear_state(&pf->state, IXL_STATE_ADMINQ_PENDING); + /* Re-enable admin queue interrupt cause */ reg = rd32(hw, I40E_PFINT_ICR0_ENA); reg |= I40E_PFINT_ICR0_ENA_ADMINQ_MASK; @@ -1436,7 +1440,7 @@ { struct ixl_pf *pf = iflib_get_softc(ctx); struct i40e_hw *hw = &pf->hw; - u16 pending; + u16 pending = 0; if (IXL_PF_IS_RESETTING(pf)) ixl_handle_empr_reset(pf); @@ -1452,7 +1456,9 @@ if (ixl_test_state(&pf->state, IXL_STATE_MDD_PENDING)) ixl_handle_mdd_event(pf); - ixl_process_adminq(pf, &pending); + if (ixl_test_state(&pf->state, IXL_STATE_ADMINQ_PENDING)) + ixl_process_adminq(pf, &pending); + ixl_update_link_status(pf); /* diff --git a/sys/dev/ixl/ixl_pf.h b/sys/dev/ixl/ixl_pf.h --- a/sys/dev/ixl/ixl_pf.h +++ b/sys/dev/ixl/ixl_pf.h @@ -89,6 +89,7 @@ IXL_STATE_EEE_ENABLED = 10, IXL_STATE_LINK_ACTIVE_ON_DOWN = 11, IXL_STATE_LINK_POLLING = 12, + IXL_STATE_ADMINQ_PENDING = 13, }; #define IXL_PF_IN_RECOVERY_MODE(pf) \ diff --git a/sys/dev/ixl/ixl_pf_iflib.c b/sys/dev/ixl/ixl_pf_iflib.c --- a/sys/dev/ixl/ixl_pf_iflib.c +++ b/sys/dev/ixl/ixl_pf_iflib.c @@ -152,6 +152,7 @@ /* Check on the cause */ if (reg & I40E_PFINT_ICR0_ADMINQ_MASK) { mask &= ~I40E_PFINT_ICR0_ENA_ADMINQ_MASK; + ixl_set_state(&pf->state, IXL_STATE_ADMINQ_PENDING); do_task = TRUE; }