aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ice/ice_lib.c
diff options
context:
space:
mode:
authorPreethi Banala <preethi.banala@intel.com>2018-09-19 20:23:16 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2018-10-02 10:16:19 -0400
commiteb0208ec42d319bc09fead0e1afe2bc0c28aeca0 (patch)
tree0af2e51b50e4ab0f45e35fa4fcb090386f071267 /drivers/net/ethernet/intel/ice/ice_lib.c
parent5755143dd18d3b7fa97b419d18d9bb4764b7b46f (diff)
ice: Split irq_tracker into sw_irq_tracker and hw_irq_tracker
For the PF driver, when mapping interrupts to queues, we need to request IRQs from the kernel and we also have to allocate interrupts from the device. Similarly, when the VF driver (iavf.ko) initializes, it requests the kernel IRQs that it needs but it can't directly allocate interrupts in the device. Instead, it sends a mailbox message to the ice driver, which then allocates interrupts in the device on the VF driver's behalf. Currently both these cases end up having to reserve entries in pf->irq_tracker but irq_tracker itself is sized based on how many vectors the PF driver needs. Under the right circumstances, the VF driver can fail to get entries in irq_tracker, which will result in the VF driver failing probe. To fix this, sw_irq_tracker and hw_irq_tracker are introduced. The sw_irq_tracker tracks only the PF's IRQ request and doesn't play any role in VF init. hw_irq_tracker represents the device's interrupt space. When interrupts have to be allocated in the device for either PF or VF, hw_irq_tracker will be looked up to see if the device has run out of interrupts. Signed-off-by: Preethi Banala <preethi.banala@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.c75
1 files changed, 52 insertions, 23 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index a4dfdf35ceab..8f7ee77cb70b 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -1039,9 +1039,9 @@ static int ice_vsi_setup_vector_base(struct ice_vsi *vsi)
1039 struct ice_pf *pf = vsi->back; 1039 struct ice_pf *pf = vsi->back;
1040 int num_q_vectors = 0; 1040 int num_q_vectors = 0;
1041 1041
1042 if (vsi->base_vector) { 1042 if (vsi->sw_base_vector || vsi->hw_base_vector) {
1043 dev_dbg(&pf->pdev->dev, "VSI %d has non-zero base vector %d\n", 1043 dev_dbg(&pf->pdev->dev, "VSI %d has non-zero HW base vector %d or SW base vector %d\n",
1044 vsi->vsi_num, vsi->base_vector); 1044 vsi->vsi_num, vsi->hw_base_vector, vsi->sw_base_vector);
1045 return -EEXIST; 1045 return -EEXIST;
1046 } 1046 }
1047 1047
@@ -1051,6 +1051,21 @@ static int ice_vsi_setup_vector_base(struct ice_vsi *vsi)
1051 switch (vsi->type) { 1051 switch (vsi->type) {
1052 case ICE_VSI_PF: 1052 case ICE_VSI_PF:
1053 num_q_vectors = vsi->num_q_vectors; 1053 num_q_vectors = vsi->num_q_vectors;
1054 /* reserve slots from OS requested IRQs */
1055 vsi->sw_base_vector = ice_get_res(pf, pf->sw_irq_tracker,
1056 num_q_vectors, vsi->idx);
1057 if (vsi->sw_base_vector < 0) {
1058 dev_err(&pf->pdev->dev,
1059 "Failed to get tracking for %d SW vectors for VSI %d, err=%d\n",
1060 num_q_vectors, vsi->vsi_num,
1061 vsi->sw_base_vector);
1062 return -ENOENT;
1063 }
1064 pf->num_avail_sw_msix -= num_q_vectors;
1065
1066 /* reserve slots from HW interrupts */
1067 vsi->hw_base_vector = ice_get_res(pf, pf->hw_irq_tracker,
1068 num_q_vectors, vsi->idx);
1054 break; 1069 break;
1055 default: 1070 default:
1056 dev_warn(&vsi->back->pdev->dev, "Unknown VSI type %d\n", 1071 dev_warn(&vsi->back->pdev->dev, "Unknown VSI type %d\n",
@@ -1058,17 +1073,18 @@ static int ice_vsi_setup_vector_base(struct ice_vsi *vsi)
1058 break; 1073 break;
1059 } 1074 }
1060 1075
1061 if (num_q_vectors) 1076 if (vsi->hw_base_vector < 0) {
1062 vsi->base_vector = ice_get_res(pf, pf->irq_tracker,
1063 num_q_vectors, vsi->idx);
1064
1065 if (vsi->base_vector < 0) {
1066 dev_err(&pf->pdev->dev, 1077 dev_err(&pf->pdev->dev,
1067 "Failed to get tracking for %d vectors for VSI %d, err=%d\n", 1078 "Failed to get tracking for %d HW vectors for VSI %d, err=%d\n",
1068 num_q_vectors, vsi->vsi_num, vsi->base_vector); 1079 num_q_vectors, vsi->vsi_num, vsi->hw_base_vector);
1080 ice_free_res(vsi->back->sw_irq_tracker, vsi->sw_base_vector,
1081 vsi->idx);
1082 pf->num_avail_sw_msix += num_q_vectors;
1069 return -ENOENT; 1083 return -ENOENT;
1070 } 1084 }
1071 1085
1086 pf->num_avail_hw_msix -= num_q_vectors;
1087
1072 return 0; 1088 return 0;
1073} 1089}
1074 1090
@@ -1554,7 +1570,7 @@ err_cfg_txqs:
1554void ice_vsi_cfg_msix(struct ice_vsi *vsi) 1570void ice_vsi_cfg_msix(struct ice_vsi *vsi)
1555{ 1571{
1556 struct ice_pf *pf = vsi->back; 1572 struct ice_pf *pf = vsi->back;
1557 u16 vector = vsi->base_vector; 1573 u16 vector = vsi->hw_base_vector;
1558 struct ice_hw *hw = &pf->hw; 1574 struct ice_hw *hw = &pf->hw;
1559 u32 txq = 0, rxq = 0; 1575 u32 txq = 0, rxq = 0;
1560 int i, q, itr; 1576 int i, q, itr;
@@ -1762,7 +1778,7 @@ int ice_vsi_stop_tx_rings(struct ice_vsi *vsi)
1762 * the queue to schedule NAPI handler 1778 * the queue to schedule NAPI handler
1763 */ 1779 */
1764 v_idx = vsi->tx_rings[i]->q_vector->v_idx; 1780 v_idx = vsi->tx_rings[i]->q_vector->v_idx;
1765 wr32(hw, GLINT_DYN_CTL(vsi->base_vector + v_idx), 1781 wr32(hw, GLINT_DYN_CTL(vsi->hw_base_vector + v_idx),
1766 GLINT_DYN_CTL_SWINT_TRIG_M | GLINT_DYN_CTL_INTENA_MSK_M); 1782 GLINT_DYN_CTL_SWINT_TRIG_M | GLINT_DYN_CTL_INTENA_MSK_M);
1767 } 1783 }
1768 status = ice_dis_vsi_txq(vsi->port_info, vsi->num_txq, q_ids, q_teids, 1784 status = ice_dis_vsi_txq(vsi->port_info, vsi->num_txq, q_ids, q_teids,
@@ -1939,7 +1955,12 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
1939 return vsi; 1955 return vsi;
1940 1956
1941unroll_vector_base: 1957unroll_vector_base:
1942 ice_free_res(vsi->back->irq_tracker, vsi->base_vector, vsi->idx); 1958 /* reclaim SW interrupts back to the common pool */
1959 ice_free_res(vsi->back->sw_irq_tracker, vsi->sw_base_vector, vsi->idx);
1960 pf->num_avail_sw_msix += vsi->num_q_vectors;
1961 /* reclaim HW interrupt back to the common pool */
1962 ice_free_res(vsi->back->hw_irq_tracker, vsi->hw_base_vector, vsi->idx);
1963 pf->num_avail_hw_msix += vsi->num_q_vectors;
1943unroll_alloc_q_vector: 1964unroll_alloc_q_vector:
1944 ice_vsi_free_q_vectors(vsi); 1965 ice_vsi_free_q_vectors(vsi);
1945unroll_vsi_init: 1966unroll_vsi_init:
@@ -1960,7 +1981,7 @@ unroll_get_qs:
1960static void ice_vsi_release_msix(struct ice_vsi *vsi) 1981static void ice_vsi_release_msix(struct ice_vsi *vsi)
1961{ 1982{
1962 struct ice_pf *pf = vsi->back; 1983 struct ice_pf *pf = vsi->back;
1963 u16 vector = vsi->base_vector; 1984 u16 vector = vsi->hw_base_vector;
1964 struct ice_hw *hw = &pf->hw; 1985 struct ice_hw *hw = &pf->hw;
1965 u32 txq = 0; 1986 u32 txq = 0;
1966 u32 rxq = 0; 1987 u32 rxq = 0;
@@ -1992,7 +2013,7 @@ static void ice_vsi_release_msix(struct ice_vsi *vsi)
1992void ice_vsi_free_irq(struct ice_vsi *vsi) 2013void ice_vsi_free_irq(struct ice_vsi *vsi)
1993{ 2014{
1994 struct ice_pf *pf = vsi->back; 2015 struct ice_pf *pf = vsi->back;
1995 int base = vsi->base_vector; 2016 int base = vsi->sw_base_vector;
1996 2017
1997 if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags)) { 2018 if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags)) {
1998 int i; 2019 int i;
@@ -2000,6 +2021,8 @@ void ice_vsi_free_irq(struct ice_vsi *vsi)
2000 if (!vsi->q_vectors || !vsi->irqs_ready) 2021 if (!vsi->q_vectors || !vsi->irqs_ready)
2001 return; 2022 return;
2002 2023
2024 ice_vsi_release_msix(vsi);
2025
2003 vsi->irqs_ready = false; 2026 vsi->irqs_ready = false;
2004 for (i = 0; i < vsi->num_q_vectors; i++) { 2027 for (i = 0; i < vsi->num_q_vectors; i++) {
2005 u16 vector = i + base; 2028 u16 vector = i + base;
@@ -2022,7 +2045,6 @@ void ice_vsi_free_irq(struct ice_vsi *vsi)
2022 devm_free_irq(&pf->pdev->dev, irq_num, 2045 devm_free_irq(&pf->pdev->dev, irq_num,
2023 vsi->q_vectors[i]); 2046 vsi->q_vectors[i]);
2024 } 2047 }
2025 ice_vsi_release_msix(vsi);
2026 } 2048 }
2027} 2049}
2028 2050
@@ -2110,6 +2132,9 @@ static int ice_search_res(struct ice_res_tracker *res, u16 needed, u16 id)
2110 int start = res->search_hint; 2132 int start = res->search_hint;
2111 int end = start; 2133 int end = start;
2112 2134
2135 if ((start + needed) > res->num_entries)
2136 return -ENOMEM;
2137
2113 id |= ICE_RES_VALID_BIT; 2138 id |= ICE_RES_VALID_BIT;
2114 2139
2115 do { 2140 do {
@@ -2183,9 +2208,9 @@ ice_get_res(struct ice_pf *pf, struct ice_res_tracker *res, u16 needed, u16 id)
2183 */ 2208 */
2184void ice_vsi_dis_irq(struct ice_vsi *vsi) 2209void ice_vsi_dis_irq(struct ice_vsi *vsi)
2185{ 2210{
2211 int base = vsi->sw_base_vector;
2186 struct ice_pf *pf = vsi->back; 2212 struct ice_pf *pf = vsi->back;
2187 struct ice_hw *hw = &pf->hw; 2213 struct ice_hw *hw = &pf->hw;
2188 int base = vsi->base_vector;
2189 u32 val; 2214 u32 val;
2190 int i; 2215 int i;
2191 2216
@@ -2218,8 +2243,8 @@ void ice_vsi_dis_irq(struct ice_vsi *vsi)
2218 2243
2219 /* disable each interrupt */ 2244 /* disable each interrupt */
2220 if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags)) { 2245 if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags)) {
2221 for (i = vsi->base_vector; 2246 for (i = vsi->hw_base_vector;
2222 i < (vsi->num_q_vectors + vsi->base_vector); i++) 2247 i < (vsi->num_q_vectors + vsi->hw_base_vector); i++)
2223 wr32(hw, GLINT_DYN_CTL(i), 0); 2248 wr32(hw, GLINT_DYN_CTL(i), 0);
2224 2249
2225 ice_flush(hw); 2250 ice_flush(hw);
@@ -2262,8 +2287,10 @@ int ice_vsi_release(struct ice_vsi *vsi)
2262 ice_vsi_close(vsi); 2287 ice_vsi_close(vsi);
2263 2288
2264 /* reclaim interrupt vectors back to PF */ 2289 /* reclaim interrupt vectors back to PF */
2265 ice_free_res(vsi->back->irq_tracker, vsi->base_vector, vsi->idx); 2290 ice_free_res(vsi->back->sw_irq_tracker, vsi->sw_base_vector, vsi->idx);
2266 pf->num_avail_msix += vsi->num_q_vectors; 2291 pf->num_avail_sw_msix += vsi->num_q_vectors;
2292 ice_free_res(vsi->back->hw_irq_tracker, vsi->hw_base_vector, vsi->idx);
2293 pf->num_avail_hw_msix += vsi->num_q_vectors;
2267 2294
2268 ice_remove_vsi_fltr(&pf->hw, vsi->idx); 2295 ice_remove_vsi_fltr(&pf->hw, vsi->idx);
2269 ice_vsi_delete(vsi); 2296 ice_vsi_delete(vsi);
@@ -2299,8 +2326,10 @@ int ice_vsi_rebuild(struct ice_vsi *vsi)
2299 return -EINVAL; 2326 return -EINVAL;
2300 2327
2301 ice_vsi_free_q_vectors(vsi); 2328 ice_vsi_free_q_vectors(vsi);
2302 ice_free_res(vsi->back->irq_tracker, vsi->base_vector, vsi->idx); 2329 ice_free_res(vsi->back->sw_irq_tracker, vsi->sw_base_vector, vsi->idx);
2303 vsi->base_vector = 0; 2330 ice_free_res(vsi->back->hw_irq_tracker, vsi->hw_base_vector, vsi->idx);
2331 vsi->sw_base_vector = 0;
2332 vsi->hw_base_vector = 0;
2304 ice_vsi_clear_rings(vsi); 2333 ice_vsi_clear_rings(vsi);
2305 ice_vsi_free_arrays(vsi, false); 2334 ice_vsi_free_arrays(vsi, false);
2306 ice_vsi_set_num_qs(vsi); 2335 ice_vsi_set_num_qs(vsi);