aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ice/ice_lib.c
diff options
context:
space:
mode:
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);