diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_lib.c')
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_lib.c | 75 |
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: | |||
1554 | void ice_vsi_cfg_msix(struct ice_vsi *vsi) | 1570 | void 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 | ||
1941 | unroll_vector_base: | 1957 | unroll_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; | ||
1943 | unroll_alloc_q_vector: | 1964 | unroll_alloc_q_vector: |
1944 | ice_vsi_free_q_vectors(vsi); | 1965 | ice_vsi_free_q_vectors(vsi); |
1945 | unroll_vsi_init: | 1966 | unroll_vsi_init: |
@@ -1960,7 +1981,7 @@ unroll_get_qs: | |||
1960 | static void ice_vsi_release_msix(struct ice_vsi *vsi) | 1981 | static 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) | |||
1992 | void ice_vsi_free_irq(struct ice_vsi *vsi) | 2013 | void 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 | */ |
2184 | void ice_vsi_dis_irq(struct ice_vsi *vsi) | 2209 | void 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); |