mirror of https://gitee.com/openkylin/linux.git
ice: Add a helper to trigger software interrupt
Add a new function ice_trigger_sw_intr to trigger interrupts. Signed-off-by: Brett Creeley <brett.creeley@intel.com> Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
3a9e32bb06
commit
e89e899f3e
|
@ -2018,6 +2018,19 @@ int ice_vsi_stop_rx_rings(struct ice_vsi *vsi)
|
||||||
return ice_vsi_ctrl_rx_rings(vsi, false);
|
return ice_vsi_ctrl_rx_rings(vsi, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_trigger_sw_intr - trigger a software interrupt
|
||||||
|
* @hw: pointer to the HW structure
|
||||||
|
* @q_vector: interrupt vector to trigger the software interrupt for
|
||||||
|
*/
|
||||||
|
void ice_trigger_sw_intr(struct ice_hw *hw, struct ice_q_vector *q_vector)
|
||||||
|
{
|
||||||
|
wr32(hw, GLINT_DYN_CTL(q_vector->reg_idx),
|
||||||
|
(ICE_ITR_NONE << GLINT_DYN_CTL_ITR_INDX_S) |
|
||||||
|
GLINT_DYN_CTL_SWINT_TRIG_M |
|
||||||
|
GLINT_DYN_CTL_INTENA_M);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_vsi_stop_tx_rings - Disable Tx rings
|
* ice_vsi_stop_tx_rings - Disable Tx rings
|
||||||
* @vsi: the VSI being configured
|
* @vsi: the VSI being configured
|
||||||
|
@ -2065,6 +2078,8 @@ ice_vsi_stop_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (i = 0; i < vsi->tc_cfg.tc_info[tc].qcount_tx; i++) {
|
for (i = 0; i < vsi->tc_cfg.tc_info[tc].qcount_tx; i++) {
|
||||||
|
struct ice_q_vector *q_vector;
|
||||||
|
|
||||||
if (!rings || !rings[q_idx]) {
|
if (!rings || !rings[q_idx]) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
@ -2085,13 +2100,10 @@ ice_vsi_stop_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src,
|
||||||
/* trigger a software interrupt for the vector
|
/* trigger a software interrupt for the vector
|
||||||
* associated to the queue to schedule NAPI handler
|
* associated to the queue to schedule NAPI handler
|
||||||
*/
|
*/
|
||||||
if (rings[q_idx]->q_vector) {
|
q_vector = rings[i]->q_vector;
|
||||||
int reg_idx = rings[i]->q_vector->reg_idx;
|
if (q_vector)
|
||||||
|
ice_trigger_sw_intr(hw, q_vector);
|
||||||
|
|
||||||
wr32(hw, GLINT_DYN_CTL(reg_idx),
|
|
||||||
GLINT_DYN_CTL_SWINT_TRIG_M |
|
|
||||||
GLINT_DYN_CTL_INTENA_MSK_M);
|
|
||||||
}
|
|
||||||
q_idx++;
|
q_idx++;
|
||||||
}
|
}
|
||||||
status = ice_dis_vsi_txq(vsi->port_info, vsi->idx, tc,
|
status = ice_dis_vsi_txq(vsi->port_info, vsi->idx, tc,
|
||||||
|
|
|
@ -64,6 +64,8 @@ bool ice_is_reset_in_progress(unsigned long *state);
|
||||||
|
|
||||||
void ice_vsi_free_q_vectors(struct ice_vsi *vsi);
|
void ice_vsi_free_q_vectors(struct ice_vsi *vsi);
|
||||||
|
|
||||||
|
void ice_trigger_sw_intr(struct ice_hw *hw, struct ice_q_vector *q_vector);
|
||||||
|
|
||||||
void ice_vsi_put_qs(struct ice_vsi *vsi);
|
void ice_vsi_put_qs(struct ice_vsi *vsi);
|
||||||
|
|
||||||
#ifdef CONFIG_DCB
|
#ifdef CONFIG_DCB
|
||||||
|
|
|
@ -61,9 +61,10 @@ static u32 ice_get_tx_pending(struct ice_ring *ring)
|
||||||
static void ice_check_for_hang_subtask(struct ice_pf *pf)
|
static void ice_check_for_hang_subtask(struct ice_pf *pf)
|
||||||
{
|
{
|
||||||
struct ice_vsi *vsi = NULL;
|
struct ice_vsi *vsi = NULL;
|
||||||
|
struct ice_hw *hw;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
u32 v, v_idx;
|
|
||||||
int packets;
|
int packets;
|
||||||
|
u32 v;
|
||||||
|
|
||||||
ice_for_each_vsi(pf, v)
|
ice_for_each_vsi(pf, v)
|
||||||
if (pf->vsi[v] && pf->vsi[v]->type == ICE_VSI_PF) {
|
if (pf->vsi[v] && pf->vsi[v]->type == ICE_VSI_PF) {
|
||||||
|
@ -77,12 +78,12 @@ static void ice_check_for_hang_subtask(struct ice_pf *pf)
|
||||||
if (!(vsi->netdev && netif_carrier_ok(vsi->netdev)))
|
if (!(vsi->netdev && netif_carrier_ok(vsi->netdev)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
hw = &vsi->back->hw;
|
||||||
|
|
||||||
for (i = 0; i < vsi->num_txq; i++) {
|
for (i = 0; i < vsi->num_txq; i++) {
|
||||||
struct ice_ring *tx_ring = vsi->tx_rings[i];
|
struct ice_ring *tx_ring = vsi->tx_rings[i];
|
||||||
|
|
||||||
if (tx_ring && tx_ring->desc) {
|
if (tx_ring && tx_ring->desc) {
|
||||||
int itr = ICE_ITR_NONE;
|
|
||||||
|
|
||||||
/* If packet counter has not changed the queue is
|
/* If packet counter has not changed the queue is
|
||||||
* likely stalled, so force an interrupt for this
|
* likely stalled, so force an interrupt for this
|
||||||
* queue.
|
* queue.
|
||||||
|
@ -93,12 +94,7 @@ static void ice_check_for_hang_subtask(struct ice_pf *pf)
|
||||||
packets = tx_ring->stats.pkts & INT_MAX;
|
packets = tx_ring->stats.pkts & INT_MAX;
|
||||||
if (tx_ring->tx_stats.prev_pkt == packets) {
|
if (tx_ring->tx_stats.prev_pkt == packets) {
|
||||||
/* Trigger sw interrupt to revive the queue */
|
/* Trigger sw interrupt to revive the queue */
|
||||||
v_idx = tx_ring->q_vector->v_idx;
|
ice_trigger_sw_intr(hw, tx_ring->q_vector);
|
||||||
wr32(&vsi->back->hw,
|
|
||||||
GLINT_DYN_CTL(vsi->base_vector + v_idx),
|
|
||||||
(itr << GLINT_DYN_CTL_ITR_INDX_S) |
|
|
||||||
GLINT_DYN_CTL_SWINT_TRIG_M |
|
|
||||||
GLINT_DYN_CTL_INTENA_MSK_M);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue