aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrett Creeley <brett.creeley@intel.com>2018-09-19 20:23:19 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2018-10-02 10:19:30 -0400
commit9e4ab4c29a62d2ccbf4be42707669be2f42d391c (patch)
tree54327122a0cddba67d650678f355f808e4966844
parentca4929b6df7c729c375c486c0ca53decb0eae9f5 (diff)
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>
-rw-r--r--drivers/net/ethernet/intel/ice/ice.h4
-rw-r--r--drivers/net/ethernet/intel/ice/ice_common.c41
-rw-r--r--drivers/net/ethernet/intel/ice/ice_hw_autogen.h5
-rw-r--r--drivers/net/ethernet/intel/ice/ice_lib.c29
-rw-r--r--drivers/net/ethernet/intel/ice/ice_main.c2
-rw-r--r--drivers/net/ethernet/intel/ice/ice_txrx.h17
-rw-r--r--drivers/net/ethernet/intel/ice/ice_type.h28
7 files changed, 102 insertions, 24 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
index fc6bc1233f10..0b269c470343 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -230,6 +230,10 @@ struct ice_q_vector {
230 u8 num_ring_tx; /* total number of tx rings in vector */ 230 u8 num_ring_tx; /* total number of tx rings in vector */
231 u8 num_ring_rx; /* total number of rx rings in vector */ 231 u8 num_ring_rx; /* total number of rx rings in vector */
232 char name[ICE_INT_NAME_STR_LEN]; 232 char name[ICE_INT_NAME_STR_LEN];
233 /* in usecs, need to use ice_intrl_to_usecs_reg() before writing this
234 * value to the device
235 */
236 u8 intrl;
233} ____cacheline_internodealigned_in_smp; 237} ____cacheline_internodealigned_in_smp;
234 238
235enum ice_pf_flags { 239enum ice_pf_flags {
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
index 9ff291375869..68fbbb92d504 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.c
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
@@ -598,6 +598,39 @@ void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf)
598} 598}
599 599
600/** 600/**
601 * ice_get_itr_intrl_gran - determine int/intrl granularity
602 * @hw: pointer to the hw struct
603 *
604 * Determines the itr/intrl granularities based on the maximum aggregate
605 * bandwidth according to the device's configuration during power-on.
606 */
607static enum ice_status ice_get_itr_intrl_gran(struct ice_hw *hw)
608{
609 u8 max_agg_bw = (rd32(hw, GL_PWR_MODE_CTL) &
610 GL_PWR_MODE_CTL_CAR_MAX_BW_M) >>
611 GL_PWR_MODE_CTL_CAR_MAX_BW_S;
612
613 switch (max_agg_bw) {
614 case ICE_MAX_AGG_BW_200G:
615 case ICE_MAX_AGG_BW_100G:
616 case ICE_MAX_AGG_BW_50G:
617 hw->itr_gran = ICE_ITR_GRAN_ABOVE_25;
618 hw->intrl_gran = ICE_INTRL_GRAN_ABOVE_25;
619 break;
620 case ICE_MAX_AGG_BW_25G:
621 hw->itr_gran = ICE_ITR_GRAN_MAX_25;
622 hw->intrl_gran = ICE_INTRL_GRAN_MAX_25;
623 break;
624 default:
625 ice_debug(hw, ICE_DBG_INIT,
626 "Failed to determine itr/intrl granularity\n");
627 return ICE_ERR_CFG;
628 }
629
630 return 0;
631}
632
633/**
601 * ice_init_hw - main hardware initialization routine 634 * ice_init_hw - main hardware initialization routine
602 * @hw: pointer to the hardware structure 635 * @hw: pointer to the hardware structure
603 */ 636 */
@@ -621,11 +654,9 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
621 if (status) 654 if (status)
622 return status; 655 return status;
623 656
624 /* set these values to minimum allowed */ 657 status = ice_get_itr_intrl_gran(hw);
625 hw->itr_gran_200 = ICE_ITR_GRAN_MIN_200; 658 if (status)
626 hw->itr_gran_100 = ICE_ITR_GRAN_MIN_100; 659 return status;
627 hw->itr_gran_50 = ICE_ITR_GRAN_MIN_50;
628 hw->itr_gran_25 = ICE_ITR_GRAN_MIN_25;
629 660
630 status = ice_init_all_ctrlq(hw); 661 status = ice_init_all_ctrlq(hw);
631 if (status) 662 if (status)
diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
index 88f11498804b..9a78d83eaa3e 100644
--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
+++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
@@ -88,6 +88,8 @@
88#define GLINT_DYN_CTL_SW_ITR_INDX_M ICE_M(0x3, 25) 88#define GLINT_DYN_CTL_SW_ITR_INDX_M ICE_M(0x3, 25)
89#define GLINT_DYN_CTL_INTENA_MSK_M BIT(31) 89#define GLINT_DYN_CTL_INTENA_MSK_M BIT(31)
90#define GLINT_ITR(_i, _INT) (0x00154000 + ((_i) * 8192 + (_INT) * 4)) 90#define GLINT_ITR(_i, _INT) (0x00154000 + ((_i) * 8192 + (_INT) * 4))
91#define GLINT_RATE(_INT) (0x0015A000 + ((_INT) * 4))
92#define GLINT_RATE_INTRL_ENA_M BIT(6)
91#define PFINT_FW_CTL 0x0016C800 93#define PFINT_FW_CTL 0x0016C800
92#define PFINT_FW_CTL_MSIX_INDX_M ICE_M(0x7FF, 0) 94#define PFINT_FW_CTL_MSIX_INDX_M ICE_M(0x7FF, 0)
93#define PFINT_FW_CTL_ITR_INDX_S 11 95#define PFINT_FW_CTL_ITR_INDX_S 11
@@ -173,6 +175,9 @@
173#define PF_FUNC_RID 0x0009E880 175#define PF_FUNC_RID 0x0009E880
174#define PF_FUNC_RID_FUNC_NUM_S 0 176#define PF_FUNC_RID_FUNC_NUM_S 0
175#define PF_FUNC_RID_FUNC_NUM_M ICE_M(0x7, 0) 177#define PF_FUNC_RID_FUNC_NUM_M ICE_M(0x7, 0)
178#define GL_PWR_MODE_CTL 0x000B820C
179#define GL_PWR_MODE_CTL_CAR_MAX_BW_S 30
180#define GL_PWR_MODE_CTL_CAR_MAX_BW_M ICE_M(0x3, 30)
176#define GLPRT_BPRCH(_i) (0x00381384 + ((_i) * 8)) 181#define GLPRT_BPRCH(_i) (0x00381384 + ((_i) * 8))
177#define GLPRT_BPRCL(_i) (0x00381380 + ((_i) * 8)) 182#define GLPRT_BPRCL(_i) (0x00381380 + ((_i) * 8))
178#define GLPRT_BPTCH(_i) (0x00381244 + ((_i) * 8)) 183#define GLPRT_BPTCH(_i) (0x00381244 + ((_i) * 8))
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)
1139 ring->vsi = vsi; 1139 ring->vsi = vsi;
1140 ring->dev = &pf->pdev->dev; 1140 ring->dev = &pf->pdev->dev;
1141 ring->count = vsi->num_desc; 1141 ring->count = vsi->num_desc;
1142 ring->itr_setting = ICE_DFLT_TX_ITR;
1142 vsi->tx_rings[i] = ring; 1143 vsi->tx_rings[i] = ring;
1143 } 1144 }
1144 1145
@@ -1158,6 +1159,7 @@ static int ice_vsi_alloc_rings(struct ice_vsi *vsi)
1158 ring->netdev = vsi->netdev; 1159 ring->netdev = vsi->netdev;
1159 ring->dev = &pf->pdev->dev; 1160 ring->dev = &pf->pdev->dev;
1160 ring->count = vsi->num_desc; 1161 ring->count = vsi->num_desc;
1162 ring->itr_setting = ICE_DFLT_RX_ITR;
1161 vsi->rx_rings[i] = ring; 1163 vsi->rx_rings[i] = ring;
1162 } 1164 }
1163 1165
@@ -1596,6 +1598,23 @@ err_cfg_txqs:
1596} 1598}
1597 1599
1598/** 1600/**
1601 * ice_intrl_usec_to_reg - convert interrupt rate limit to register value
1602 * @intrl: interrupt rate limit in usecs
1603 * @gran: interrupt rate limit granularity in usecs
1604 *
1605 * This function converts a decimal interrupt rate limit in usecs to the format
1606 * expected by firmware.
1607 */
1608static u32 ice_intrl_usec_to_reg(u8 intrl, u8 gran)
1609{
1610 u32 val = intrl / gran;
1611
1612 if (val)
1613 return val | GLINT_RATE_INTRL_ENA_M;
1614 return 0;
1615}
1616
1617/**
1599 * ice_vsi_cfg_msix - MSIX mode Interrupt Config in the HW 1618 * ice_vsi_cfg_msix - MSIX mode Interrupt Config in the HW
1600 * @vsi: the VSI being configured 1619 * @vsi: the VSI being configured
1601 */ 1620 */
@@ -1611,23 +1630,27 @@ void ice_vsi_cfg_msix(struct ice_vsi *vsi)
1611 for (i = 0; i < vsi->num_q_vectors; i++, vector++) { 1630 for (i = 0; i < vsi->num_q_vectors; i++, vector++) {
1612 struct ice_q_vector *q_vector = vsi->q_vectors[i]; 1631 struct ice_q_vector *q_vector = vsi->q_vectors[i];
1613 1632
1614 itr_gran = hw->itr_gran_200; 1633 itr_gran = hw->itr_gran;
1634
1635 q_vector->intrl = ICE_DFLT_INTRL;
1615 1636
1616 if (q_vector->num_ring_rx) { 1637 if (q_vector->num_ring_rx) {
1617 q_vector->rx.itr = 1638 q_vector->rx.itr =
1618 ITR_TO_REG(vsi->rx_rings[rxq]->rx_itr_setting, 1639 ITR_TO_REG(vsi->rx_rings[rxq]->itr_setting,
1619 itr_gran); 1640 itr_gran);
1620 q_vector->rx.latency_range = ICE_LOW_LATENCY; 1641 q_vector->rx.latency_range = ICE_LOW_LATENCY;
1621 } 1642 }
1622 1643
1623 if (q_vector->num_ring_tx) { 1644 if (q_vector->num_ring_tx) {
1624 q_vector->tx.itr = 1645 q_vector->tx.itr =
1625 ITR_TO_REG(vsi->tx_rings[txq]->tx_itr_setting, 1646 ITR_TO_REG(vsi->tx_rings[txq]->itr_setting,
1626 itr_gran); 1647 itr_gran);
1627 q_vector->tx.latency_range = ICE_LOW_LATENCY; 1648 q_vector->tx.latency_range = ICE_LOW_LATENCY;
1628 } 1649 }
1629 wr32(hw, GLINT_ITR(ICE_RX_ITR, vector), q_vector->rx.itr); 1650 wr32(hw, GLINT_ITR(ICE_RX_ITR, vector), q_vector->rx.itr);
1630 wr32(hw, GLINT_ITR(ICE_TX_ITR, vector), q_vector->tx.itr); 1651 wr32(hw, GLINT_ITR(ICE_TX_ITR, vector), q_vector->tx.itr);
1652 wr32(hw, GLINT_RATE(vector),
1653 ice_intrl_usec_to_reg(q_vector->intrl, hw->intrl_gran));
1631 1654
1632 /* Both Transmit Queue Interrupt Cause Control register 1655 /* Both Transmit Queue Interrupt Cause Control register
1633 * and Receive Queue Interrupt Cause control register 1656 * and Receive Queue Interrupt Cause control register
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index f51857ead0f3..9638684f75ac 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -1406,7 +1406,7 @@ skip_req_irq:
1406 PFINT_FW_CTL_CAUSE_ENA_M); 1406 PFINT_FW_CTL_CAUSE_ENA_M);
1407 wr32(hw, PFINT_FW_CTL, val); 1407 wr32(hw, PFINT_FW_CTL, val);
1408 1408
1409 itr_gran = hw->itr_gran_200; 1409 itr_gran = hw->itr_gran;
1410 1410
1411 wr32(hw, GLINT_ITR(ICE_RX_ITR, pf->hw_oicr_idx), 1411 wr32(hw, GLINT_ITR(ICE_RX_ITR, pf->hw_oicr_idx),
1412 ITR_TO_REG(ICE_ITR_8K, itr_gran)); 1412 ITR_TO_REG(ICE_ITR_8K, itr_gran));
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h
index 839fd9ff6043..a9b92974e041 100644
--- a/drivers/net/ethernet/intel/ice/ice_txrx.h
+++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
@@ -104,10 +104,16 @@ enum ice_rx_dtype {
104#define ICE_RX_ITR ICE_IDX_ITR0 104#define ICE_RX_ITR ICE_IDX_ITR0
105#define ICE_TX_ITR ICE_IDX_ITR1 105#define ICE_TX_ITR ICE_IDX_ITR1
106#define ICE_ITR_DYNAMIC 0x8000 /* use top bit as a flag */ 106#define ICE_ITR_DYNAMIC 0x8000 /* use top bit as a flag */
107#define ICE_ITR_8K 0x003E 107#define ICE_ITR_8K 125
108#define ICE_DFLT_TX_ITR ICE_ITR_8K
109#define ICE_DFLT_RX_ITR ICE_ITR_8K
110/* apply ITR granularity translation to program the register. itr_gran is either
111 * 2 or 4 usecs so we need to divide by 2 first then shift by that value
112 */
113#define ITR_TO_REG(val, itr_gran) (((val) & ~ICE_ITR_DYNAMIC) >> \
114 ((itr_gran) / 2))
108 115
109/* apply ITR HW granularity translation to program the HW registers */ 116#define ICE_DFLT_INTRL 0
110#define ITR_TO_REG(val, itr_gran) (((val) & ~ICE_ITR_DYNAMIC) >> (itr_gran))
111 117
112/* Legacy or Advanced Mode Queue */ 118/* Legacy or Advanced Mode Queue */
113#define ICE_TX_ADVANCED 0 119#define ICE_TX_ADVANCED 0
@@ -130,12 +136,11 @@ struct ice_ring {
130 u32 txq_teid; /* Added Tx queue TEID */ 136 u32 txq_teid; /* Added Tx queue TEID */
131 137
132 /* high bit set means dynamic, use accessor routines to read/write. 138 /* high bit set means dynamic, use accessor routines to read/write.
133 * hardware supports 2us/1us resolution for the ITR registers. 139 * hardware supports 4us/2us resolution for the ITR registers.
134 * these values always store the USER setting, and must be converted 140 * these values always store the USER setting, and must be converted
135 * before programming to a register. 141 * before programming to a register.
136 */ 142 */
137 u16 rx_itr_setting; 143 u16 itr_setting;
138 u16 tx_itr_setting;
139 144
140 u16 count; /* Number of descriptors */ 145 u16 count; /* Number of descriptors */
141 u16 reg_idx; /* HW register index of the ring */ 146 u16 reg_idx; /* HW register index of the ring */
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
index 87930f68d3fb..f5c8de0ed0eb 100644
--- a/drivers/net/ethernet/intel/ice/ice_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
@@ -333,16 +333,26 @@ struct ice_hw {
333 u32 fw_build; /* firmware build number */ 333 u32 fw_build; /* firmware build number */
334 334
335 struct ice_fw_log_cfg fw_log; 335 struct ice_fw_log_cfg fw_log;
336 /* minimum allowed value for different speeds */ 336
337#define ICE_ITR_GRAN_MIN_200 1 337/* Device max aggregate bandwidths corresponding to the GL_PWR_MODE_CTL
338#define ICE_ITR_GRAN_MIN_100 1 338 * register. Used for determining the itr/intrl granularity during
339#define ICE_ITR_GRAN_MIN_50 2 339 * initialization.
340#define ICE_ITR_GRAN_MIN_25 4 340 */
341#define ICE_MAX_AGG_BW_200G 0x0
342#define ICE_MAX_AGG_BW_100G 0X1
343#define ICE_MAX_AGG_BW_50G 0x2
344#define ICE_MAX_AGG_BW_25G 0x3
345 /* ITR granularity for different speeds */
346#define ICE_ITR_GRAN_ABOVE_25 2
347#define ICE_ITR_GRAN_MAX_25 4
341 /* ITR granularity in 1 us */ 348 /* ITR granularity in 1 us */
342 u8 itr_gran_200; 349 u8 itr_gran;
343 u8 itr_gran_100; 350 /* INTRL granularity for different speeds */
344 u8 itr_gran_50; 351#define ICE_INTRL_GRAN_ABOVE_25 4
345 u8 itr_gran_25; 352#define ICE_INTRL_GRAN_MAX_25 8
353 /* INTRL granularity in 1 us */
354 u8 intrl_gran;
355
346 u8 ucast_shared; /* true if VSIs can share unicast addr */ 356 u8 ucast_shared; /* true if VSIs can share unicast addr */
347 357
348}; 358};