Commit e89e899f authored by Brett Creeley's avatar Brett Creeley Committed by Jeff Kirsher
Browse files

ice: Add a helper to trigger software interrupt



Add a new function ice_trigger_sw_intr to trigger interrupts.

Signed-off-by: default avatarBrett Creeley <brett.creeley@intel.com>
Signed-off-by: default avatarAnirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 3a9e32bb
Loading
Loading
Loading
Loading
+18 −6
Original line number Diff line number Diff line
@@ -2018,6 +2018,19 @@ int ice_vsi_stop_rx_rings(struct ice_vsi *vsi)
	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
 * @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;

		for (i = 0; i < vsi->tc_cfg.tc_info[tc].qcount_tx; i++) {
			struct ice_q_vector *q_vector;

			if (!rings || !rings[q_idx]) {
				err = -EINVAL;
				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
			 * associated to the queue to schedule NAPI handler
			 */
			if (rings[q_idx]->q_vector) {
				int reg_idx = rings[i]->q_vector->reg_idx;
			q_vector = rings[i]->q_vector;
			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++;
		}
		status = ice_dis_vsi_txq(vsi->port_info, vsi->idx, tc,
+2 −0
Original line number Diff line number Diff line
@@ -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_trigger_sw_intr(struct ice_hw *hw, struct ice_q_vector *q_vector);

void ice_vsi_put_qs(struct ice_vsi *vsi);

#ifdef CONFIG_DCB
+5 −9
Original line number Diff line number Diff line
@@ -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)
{
	struct ice_vsi *vsi = NULL;
	struct ice_hw *hw;
	unsigned int i;
	u32 v, v_idx;
	int packets;
	u32 v;

	ice_for_each_vsi(pf, v)
		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)))
		return;

	hw = &vsi->back->hw;

	for (i = 0; i < vsi->num_txq; i++) {
		struct ice_ring *tx_ring = vsi->tx_rings[i];

		if (tx_ring && tx_ring->desc) {
			int itr = ICE_ITR_NONE;

			/* If packet counter has not changed the queue is
			 * likely stalled, so force an interrupt for this
			 * queue.
@@ -93,12 +94,7 @@ static void ice_check_for_hang_subtask(struct ice_pf *pf)
			packets = tx_ring->stats.pkts & INT_MAX;
			if (tx_ring->tx_stats.prev_pkt == packets) {
				/* Trigger sw interrupt to revive the queue */
				v_idx = tx_ring->q_vector->v_idx;
				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);
				ice_trigger_sw_intr(hw, tx_ring->q_vector);
				continue;
			}