Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

ice: Add support for dynamic interrupt moderation



Currently there is no support for dynamic interrupt moderation. This
patch adds some initial code to support this. The following changes
were made:

1. Currently we are using multiple members to store the interrupt
   granularity (itr_gran_25/50/100/200). This is not necessary because
   we can query the device to determine what the interrupt granularity
   should be set to, done by a new function ice_get_itr_intrl_gran.

2. Added intrl to ice_q_vector structure to support interrupt rate
   limiting.

3. Added the function ice_intrl_usecs_to_reg for converting to a value
   in usecs that the device understands.

4. Added call to write to the GLINT_RATE register. Disable intrl by
   default for now.

5. Changed rx/tx_itr_setting to itr_setting because having both seems
   redundant because a ring is either Tx or Rx.

6. Initialize itr_setting for both Tx/Rx rings in ice_vsi_alloc_rings()

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 ca4929b6
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -230,6 +230,10 @@ struct ice_q_vector {
	u8 num_ring_tx;			/* total number of tx rings in vector */
	u8 num_ring_rx;			/* total number of rx rings in vector */
	char name[ICE_INT_NAME_STR_LEN];
	/* in usecs, need to use ice_intrl_to_usecs_reg() before writing this
	 * value to the device
	 */
	u8 intrl;
} ____cacheline_internodealigned_in_smp;

enum ice_pf_flags {
+36 −5
Original line number Diff line number Diff line
@@ -597,6 +597,39 @@ void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf)
	ice_debug(hw, ICE_DBG_AQ_MSG, "[ FW Log Msg End ]\n");
}

/**
 * ice_get_itr_intrl_gran - determine int/intrl granularity
 * @hw: pointer to the hw struct
 *
 * Determines the itr/intrl granularities based on the maximum aggregate
 * bandwidth according to the device's configuration during power-on.
 */
static enum ice_status ice_get_itr_intrl_gran(struct ice_hw *hw)
{
	u8 max_agg_bw = (rd32(hw, GL_PWR_MODE_CTL) &
			 GL_PWR_MODE_CTL_CAR_MAX_BW_M) >>
			GL_PWR_MODE_CTL_CAR_MAX_BW_S;

	switch (max_agg_bw) {
	case ICE_MAX_AGG_BW_200G:
	case ICE_MAX_AGG_BW_100G:
	case ICE_MAX_AGG_BW_50G:
		hw->itr_gran = ICE_ITR_GRAN_ABOVE_25;
		hw->intrl_gran = ICE_INTRL_GRAN_ABOVE_25;
		break;
	case ICE_MAX_AGG_BW_25G:
		hw->itr_gran = ICE_ITR_GRAN_MAX_25;
		hw->intrl_gran = ICE_INTRL_GRAN_MAX_25;
		break;
	default:
		ice_debug(hw, ICE_DBG_INIT,
			  "Failed to determine itr/intrl granularity\n");
		return ICE_ERR_CFG;
	}

	return 0;
}

/**
 * ice_init_hw - main hardware initialization routine
 * @hw: pointer to the hardware structure
@@ -621,11 +654,9 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
	if (status)
		return status;

	/* set these values to minimum allowed */
	hw->itr_gran_200 = ICE_ITR_GRAN_MIN_200;
	hw->itr_gran_100 = ICE_ITR_GRAN_MIN_100;
	hw->itr_gran_50 = ICE_ITR_GRAN_MIN_50;
	hw->itr_gran_25 = ICE_ITR_GRAN_MIN_25;
	status = ice_get_itr_intrl_gran(hw);
	if (status)
		return status;

	status = ice_init_all_ctrlq(hw);
	if (status)
+5 −0
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@
#define GLINT_DYN_CTL_SW_ITR_INDX_M		ICE_M(0x3, 25)
#define GLINT_DYN_CTL_INTENA_MSK_M		BIT(31)
#define GLINT_ITR(_i, _INT)			(0x00154000 + ((_i) * 8192 + (_INT) * 4))
#define GLINT_RATE(_INT)			(0x0015A000 + ((_INT) * 4))
#define GLINT_RATE_INTRL_ENA_M			BIT(6)
#define PFINT_FW_CTL				0x0016C800
#define PFINT_FW_CTL_MSIX_INDX_M		ICE_M(0x7FF, 0)
#define PFINT_FW_CTL_ITR_INDX_S			11
@@ -173,6 +175,9 @@
#define PF_FUNC_RID				0x0009E880
#define PF_FUNC_RID_FUNC_NUM_S			0
#define PF_FUNC_RID_FUNC_NUM_M			ICE_M(0x7, 0)
#define GL_PWR_MODE_CTL				0x000B820C
#define GL_PWR_MODE_CTL_CAR_MAX_BW_S		30
#define GL_PWR_MODE_CTL_CAR_MAX_BW_M		ICE_M(0x3, 30)
#define GLPRT_BPRCH(_i)				(0x00381384 + ((_i) * 8))
#define GLPRT_BPRCL(_i)				(0x00381380 + ((_i) * 8))
#define GLPRT_BPTCH(_i)				(0x00381244 + ((_i) * 8))
+26 −3
Original line number Diff line number Diff line
@@ -1139,6 +1139,7 @@ static int ice_vsi_alloc_rings(struct ice_vsi *vsi)
		ring->vsi = vsi;
		ring->dev = &pf->pdev->dev;
		ring->count = vsi->num_desc;
		ring->itr_setting = ICE_DFLT_TX_ITR;
		vsi->tx_rings[i] = ring;
	}

@@ -1158,6 +1159,7 @@ static int ice_vsi_alloc_rings(struct ice_vsi *vsi)
		ring->netdev = vsi->netdev;
		ring->dev = &pf->pdev->dev;
		ring->count = vsi->num_desc;
		ring->itr_setting = ICE_DFLT_RX_ITR;
		vsi->rx_rings[i] = ring;
	}

@@ -1595,6 +1597,23 @@ int ice_vsi_cfg_txqs(struct ice_vsi *vsi)
	return err;
}

/**
 * ice_intrl_usec_to_reg - convert interrupt rate limit to register value
 * @intrl: interrupt rate limit in usecs
 * @gran: interrupt rate limit granularity in usecs
 *
 * This function converts a decimal interrupt rate limit in usecs to the format
 * expected by firmware.
 */
static u32 ice_intrl_usec_to_reg(u8 intrl, u8 gran)
{
	u32 val = intrl / gran;

	if (val)
		return val | GLINT_RATE_INTRL_ENA_M;
	return 0;
}

/**
 * ice_vsi_cfg_msix - MSIX mode Interrupt Config in the HW
 * @vsi: the VSI being configured
@@ -1611,23 +1630,27 @@ void ice_vsi_cfg_msix(struct ice_vsi *vsi)
	for (i = 0; i < vsi->num_q_vectors; i++, vector++) {
		struct ice_q_vector *q_vector = vsi->q_vectors[i];

		itr_gran = hw->itr_gran_200;
		itr_gran = hw->itr_gran;

		q_vector->intrl = ICE_DFLT_INTRL;

		if (q_vector->num_ring_rx) {
			q_vector->rx.itr =
				ITR_TO_REG(vsi->rx_rings[rxq]->rx_itr_setting,
				ITR_TO_REG(vsi->rx_rings[rxq]->itr_setting,
					   itr_gran);
			q_vector->rx.latency_range = ICE_LOW_LATENCY;
		}

		if (q_vector->num_ring_tx) {
			q_vector->tx.itr =
				ITR_TO_REG(vsi->tx_rings[txq]->tx_itr_setting,
				ITR_TO_REG(vsi->tx_rings[txq]->itr_setting,
					   itr_gran);
			q_vector->tx.latency_range = ICE_LOW_LATENCY;
		}
		wr32(hw, GLINT_ITR(ICE_RX_ITR, vector), q_vector->rx.itr);
		wr32(hw, GLINT_ITR(ICE_TX_ITR, vector), q_vector->tx.itr);
		wr32(hw, GLINT_RATE(vector),
		     ice_intrl_usec_to_reg(q_vector->intrl, hw->intrl_gran));

		/* Both Transmit Queue Interrupt Cause Control register
		 * and Receive Queue Interrupt Cause control register
+1 −1
Original line number Diff line number Diff line
@@ -1406,7 +1406,7 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf)
	       PFINT_FW_CTL_CAUSE_ENA_M);
	wr32(hw, PFINT_FW_CTL, val);

	itr_gran = hw->itr_gran_200;
	itr_gran = hw->itr_gran;

	wr32(hw, GLINT_ITR(ICE_RX_ITR, pf->hw_oicr_idx),
	     ITR_TO_REG(ICE_ITR_8K, itr_gran));
Loading