diff options
author | Brett Creeley <brett.creeley@intel.com> | 2018-09-19 17:23:19 -0700 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2018-10-02 07:19:30 -0700 |
commit | 9e4ab4c29a62d2ccbf4be42707669be2f42d391c (patch) | |
tree | 54327122a0cddba67d650678f355f808e4966844 /drivers/net/ethernet/intel/ice/ice_lib.c | |
parent | ca4929b6df7c729c375c486c0ca53decb0eae9f5 (diff) | |
download | linux-9e4ab4c29a62d2ccbf4be42707669be2f42d391c.tar.bz2 |
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: 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>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_lib.c')
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_lib.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index 98e8b7096e47..acf3478a3f3b 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -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; } @@ -1596,6 +1598,23 @@ err_cfg_txqs: } /** + * 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 |