diff options
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice.h | 21 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_lib.c | 75 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_main.c | 116 |
3 files changed, 148 insertions, 64 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index 9cce4cb91401..fc6bc1233f10 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h | |||
@@ -172,7 +172,8 @@ struct ice_vsi { | |||
172 | u32 rx_buf_failed; | 172 | u32 rx_buf_failed; |
173 | u32 rx_page_failed; | 173 | u32 rx_page_failed; |
174 | int num_q_vectors; | 174 | int num_q_vectors; |
175 | int base_vector; | 175 | int sw_base_vector; /* Irq base for OS reserved vectors */ |
176 | int hw_base_vector; /* HW (absolute) index of a vector */ | ||
176 | enum ice_vsi_type type; | 177 | enum ice_vsi_type type; |
177 | u16 vsi_num; /* HW (absolute) index of this VSI */ | 178 | u16 vsi_num; /* HW (absolute) index of this VSI */ |
178 | u16 idx; /* software index in pf->vsi[] */ | 179 | u16 idx; /* software index in pf->vsi[] */ |
@@ -240,8 +241,14 @@ enum ice_pf_flags { | |||
240 | 241 | ||
241 | struct ice_pf { | 242 | struct ice_pf { |
242 | struct pci_dev *pdev; | 243 | struct pci_dev *pdev; |
244 | |||
245 | /* OS reserved IRQ details */ | ||
243 | struct msix_entry *msix_entries; | 246 | struct msix_entry *msix_entries; |
244 | struct ice_res_tracker *irq_tracker; | 247 | struct ice_res_tracker *sw_irq_tracker; |
248 | |||
249 | /* HW reserved Interrupts for this PF */ | ||
250 | struct ice_res_tracker *hw_irq_tracker; | ||
251 | |||
245 | struct ice_vsi **vsi; /* VSIs created by the driver */ | 252 | struct ice_vsi **vsi; /* VSIs created by the driver */ |
246 | struct ice_sw *first_sw; /* first switch created by firmware */ | 253 | struct ice_sw *first_sw; /* first switch created by firmware */ |
247 | DECLARE_BITMAP(state, __ICE_STATE_NBITS); | 254 | DECLARE_BITMAP(state, __ICE_STATE_NBITS); |
@@ -256,9 +263,11 @@ struct ice_pf { | |||
256 | struct mutex sw_mutex; /* lock for protecting VSI alloc flow */ | 263 | struct mutex sw_mutex; /* lock for protecting VSI alloc flow */ |
257 | u32 msg_enable; | 264 | u32 msg_enable; |
258 | u32 hw_csum_rx_error; | 265 | u32 hw_csum_rx_error; |
259 | u32 oicr_idx; /* Other interrupt cause vector index */ | 266 | u32 sw_oicr_idx; /* Other interrupt cause SW vector index */ |
267 | u32 num_avail_sw_msix; /* remaining MSIX SW vectors left unclaimed */ | ||
268 | u32 hw_oicr_idx; /* Other interrupt cause vector HW index */ | ||
269 | u32 num_avail_hw_msix; /* remaining HW MSIX vectors left unclaimed */ | ||
260 | u32 num_lan_msix; /* Total MSIX vectors for base driver */ | 270 | u32 num_lan_msix; /* Total MSIX vectors for base driver */ |
261 | u32 num_avail_msix; /* remaining MSIX vectors left unclaimed */ | ||
262 | u16 num_lan_tx; /* num lan tx queues setup */ | 271 | u16 num_lan_tx; /* num lan tx queues setup */ |
263 | u16 num_lan_rx; /* num lan rx queues setup */ | 272 | u16 num_lan_rx; /* num lan rx queues setup */ |
264 | u16 q_left_tx; /* remaining num tx queues left unclaimed */ | 273 | u16 q_left_tx; /* remaining num tx queues left unclaimed */ |
@@ -293,8 +302,8 @@ struct ice_netdev_priv { | |||
293 | static inline void ice_irq_dynamic_ena(struct ice_hw *hw, struct ice_vsi *vsi, | 302 | static inline void ice_irq_dynamic_ena(struct ice_hw *hw, struct ice_vsi *vsi, |
294 | struct ice_q_vector *q_vector) | 303 | struct ice_q_vector *q_vector) |
295 | { | 304 | { |
296 | u32 vector = (vsi && q_vector) ? vsi->base_vector + q_vector->v_idx : | 305 | u32 vector = (vsi && q_vector) ? vsi->hw_base_vector + q_vector->v_idx : |
297 | ((struct ice_pf *)hw->back)->oicr_idx; | 306 | ((struct ice_pf *)hw->back)->hw_oicr_idx; |
298 | int itr = ICE_ITR_NONE; | 307 | int itr = ICE_ITR_NONE; |
299 | u32 val; | 308 | u32 val; |
300 | 309 | ||
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); |
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index bb42ee643b77..d9f30d15ad65 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c | |||
@@ -95,7 +95,7 @@ static void ice_check_for_hang_subtask(struct ice_pf *pf) | |||
95 | /* Trigger sw interrupt to revive the queue */ | 95 | /* Trigger sw interrupt to revive the queue */ |
96 | v_idx = tx_ring->q_vector->v_idx; | 96 | v_idx = tx_ring->q_vector->v_idx; |
97 | wr32(&vsi->back->hw, | 97 | wr32(&vsi->back->hw, |
98 | GLINT_DYN_CTL(vsi->base_vector + v_idx), | 98 | GLINT_DYN_CTL(vsi->hw_base_vector + v_idx), |
99 | (itr << GLINT_DYN_CTL_ITR_INDX_S) | | 99 | (itr << GLINT_DYN_CTL_ITR_INDX_S) | |
100 | GLINT_DYN_CTL_SWINT_TRIG_M | | 100 | GLINT_DYN_CTL_SWINT_TRIG_M | |
101 | GLINT_DYN_CTL_INTENA_MSK_M); | 101 | GLINT_DYN_CTL_INTENA_MSK_M); |
@@ -1122,7 +1122,7 @@ static int ice_vsi_req_irq_msix(struct ice_vsi *vsi, char *basename) | |||
1122 | { | 1122 | { |
1123 | int q_vectors = vsi->num_q_vectors; | 1123 | int q_vectors = vsi->num_q_vectors; |
1124 | struct ice_pf *pf = vsi->back; | 1124 | struct ice_pf *pf = vsi->back; |
1125 | int base = vsi->base_vector; | 1125 | int base = vsi->sw_base_vector; |
1126 | int rx_int_idx = 0; | 1126 | int rx_int_idx = 0; |
1127 | int tx_int_idx = 0; | 1127 | int tx_int_idx = 0; |
1128 | int vector, err; | 1128 | int vector, err; |
@@ -1203,7 +1203,7 @@ static void ice_ena_misc_vector(struct ice_pf *pf) | |||
1203 | wr32(hw, PFINT_OICR_ENA, val); | 1203 | wr32(hw, PFINT_OICR_ENA, val); |
1204 | 1204 | ||
1205 | /* SW_ITR_IDX = 0, but don't change INTENA */ | 1205 | /* SW_ITR_IDX = 0, but don't change INTENA */ |
1206 | wr32(hw, GLINT_DYN_CTL(pf->oicr_idx), | 1206 | wr32(hw, GLINT_DYN_CTL(pf->hw_oicr_idx), |
1207 | GLINT_DYN_CTL_SW_ITR_INDX_M | GLINT_DYN_CTL_INTENA_MSK_M); | 1207 | GLINT_DYN_CTL_SW_ITR_INDX_M | GLINT_DYN_CTL_INTENA_MSK_M); |
1208 | } | 1208 | } |
1209 | 1209 | ||
@@ -1321,12 +1321,15 @@ static void ice_free_irq_msix_misc(struct ice_pf *pf) | |||
1321 | ice_flush(&pf->hw); | 1321 | ice_flush(&pf->hw); |
1322 | 1322 | ||
1323 | if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags) && pf->msix_entries) { | 1323 | if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags) && pf->msix_entries) { |
1324 | synchronize_irq(pf->msix_entries[pf->oicr_idx].vector); | 1324 | synchronize_irq(pf->msix_entries[pf->sw_oicr_idx].vector); |
1325 | devm_free_irq(&pf->pdev->dev, | 1325 | devm_free_irq(&pf->pdev->dev, |
1326 | pf->msix_entries[pf->oicr_idx].vector, pf); | 1326 | pf->msix_entries[pf->sw_oicr_idx].vector, pf); |
1327 | } | 1327 | } |
1328 | 1328 | ||
1329 | ice_free_res(pf->irq_tracker, pf->oicr_idx, ICE_RES_MISC_VEC_ID); | 1329 | pf->num_avail_sw_msix += 1; |
1330 | ice_free_res(pf->sw_irq_tracker, pf->sw_oicr_idx, ICE_RES_MISC_VEC_ID); | ||
1331 | pf->num_avail_hw_msix += 1; | ||
1332 | ice_free_res(pf->hw_irq_tracker, pf->hw_oicr_idx, ICE_RES_MISC_VEC_ID); | ||
1330 | } | 1333 | } |
1331 | 1334 | ||
1332 | /** | 1335 | /** |
@@ -1356,39 +1359,53 @@ static int ice_req_irq_msix_misc(struct ice_pf *pf) | |||
1356 | if (ice_is_reset_in_progress(pf->state)) | 1359 | if (ice_is_reset_in_progress(pf->state)) |
1357 | goto skip_req_irq; | 1360 | goto skip_req_irq; |
1358 | 1361 | ||
1359 | /* reserve one vector in irq_tracker for misc interrupts */ | 1362 | /* reserve one vector in sw_irq_tracker for misc interrupts */ |
1360 | oicr_idx = ice_get_res(pf, pf->irq_tracker, 1, ICE_RES_MISC_VEC_ID); | 1363 | oicr_idx = ice_get_res(pf, pf->sw_irq_tracker, 1, ICE_RES_MISC_VEC_ID); |
1361 | if (oicr_idx < 0) | 1364 | if (oicr_idx < 0) |
1362 | return oicr_idx; | 1365 | return oicr_idx; |
1363 | 1366 | ||
1364 | pf->oicr_idx = oicr_idx; | 1367 | pf->num_avail_sw_msix -= 1; |
1368 | pf->sw_oicr_idx = oicr_idx; | ||
1369 | |||
1370 | /* reserve one vector in hw_irq_tracker for misc interrupts */ | ||
1371 | oicr_idx = ice_get_res(pf, pf->hw_irq_tracker, 1, ICE_RES_MISC_VEC_ID); | ||
1372 | if (oicr_idx < 0) { | ||
1373 | ice_free_res(pf->sw_irq_tracker, 1, ICE_RES_MISC_VEC_ID); | ||
1374 | pf->num_avail_sw_msix += 1; | ||
1375 | return oicr_idx; | ||
1376 | } | ||
1377 | pf->num_avail_hw_msix -= 1; | ||
1378 | pf->hw_oicr_idx = oicr_idx; | ||
1365 | 1379 | ||
1366 | err = devm_request_irq(&pf->pdev->dev, | 1380 | err = devm_request_irq(&pf->pdev->dev, |
1367 | pf->msix_entries[pf->oicr_idx].vector, | 1381 | pf->msix_entries[pf->sw_oicr_idx].vector, |
1368 | ice_misc_intr, 0, pf->int_name, pf); | 1382 | ice_misc_intr, 0, pf->int_name, pf); |
1369 | if (err) { | 1383 | if (err) { |
1370 | dev_err(&pf->pdev->dev, | 1384 | dev_err(&pf->pdev->dev, |
1371 | "devm_request_irq for %s failed: %d\n", | 1385 | "devm_request_irq for %s failed: %d\n", |
1372 | pf->int_name, err); | 1386 | pf->int_name, err); |
1373 | ice_free_res(pf->irq_tracker, 1, ICE_RES_MISC_VEC_ID); | 1387 | ice_free_res(pf->sw_irq_tracker, 1, ICE_RES_MISC_VEC_ID); |
1388 | pf->num_avail_sw_msix += 1; | ||
1389 | ice_free_res(pf->hw_irq_tracker, 1, ICE_RES_MISC_VEC_ID); | ||
1390 | pf->num_avail_hw_msix += 1; | ||
1374 | return err; | 1391 | return err; |
1375 | } | 1392 | } |
1376 | 1393 | ||
1377 | skip_req_irq: | 1394 | skip_req_irq: |
1378 | ice_ena_misc_vector(pf); | 1395 | ice_ena_misc_vector(pf); |
1379 | 1396 | ||
1380 | val = ((pf->oicr_idx & PFINT_OICR_CTL_MSIX_INDX_M) | | 1397 | val = ((pf->hw_oicr_idx & PFINT_OICR_CTL_MSIX_INDX_M) | |
1381 | PFINT_OICR_CTL_CAUSE_ENA_M); | 1398 | PFINT_OICR_CTL_CAUSE_ENA_M); |
1382 | wr32(hw, PFINT_OICR_CTL, val); | 1399 | wr32(hw, PFINT_OICR_CTL, val); |
1383 | 1400 | ||
1384 | /* This enables Admin queue Interrupt causes */ | 1401 | /* This enables Admin queue Interrupt causes */ |
1385 | val = ((pf->oicr_idx & PFINT_FW_CTL_MSIX_INDX_M) | | 1402 | val = ((pf->hw_oicr_idx & PFINT_FW_CTL_MSIX_INDX_M) | |
1386 | PFINT_FW_CTL_CAUSE_ENA_M); | 1403 | PFINT_FW_CTL_CAUSE_ENA_M); |
1387 | wr32(hw, PFINT_FW_CTL, val); | 1404 | wr32(hw, PFINT_FW_CTL, val); |
1388 | 1405 | ||
1389 | itr_gran = hw->itr_gran_200; | 1406 | itr_gran = hw->itr_gran_200; |
1390 | 1407 | ||
1391 | wr32(hw, GLINT_ITR(ICE_RX_ITR, pf->oicr_idx), | 1408 | wr32(hw, GLINT_ITR(ICE_RX_ITR, pf->hw_oicr_idx), |
1392 | ITR_TO_REG(ICE_ITR_8K, itr_gran)); | 1409 | ITR_TO_REG(ICE_ITR_8K, itr_gran)); |
1393 | 1410 | ||
1394 | ice_flush(hw); | 1411 | ice_flush(hw); |
@@ -1797,6 +1814,7 @@ static int ice_ena_msix_range(struct ice_pf *pf) | |||
1797 | /* reserve vectors for LAN traffic */ | 1814 | /* reserve vectors for LAN traffic */ |
1798 | pf->num_lan_msix = min_t(int, num_online_cpus(), v_left); | 1815 | pf->num_lan_msix = min_t(int, num_online_cpus(), v_left); |
1799 | v_budget += pf->num_lan_msix; | 1816 | v_budget += pf->num_lan_msix; |
1817 | v_left -= pf->num_lan_msix; | ||
1800 | 1818 | ||
1801 | pf->msix_entries = devm_kcalloc(&pf->pdev->dev, v_budget, | 1819 | pf->msix_entries = devm_kcalloc(&pf->pdev->dev, v_budget, |
1802 | sizeof(struct msix_entry), GFP_KERNEL); | 1820 | sizeof(struct msix_entry), GFP_KERNEL); |
@@ -1824,10 +1842,11 @@ static int ice_ena_msix_range(struct ice_pf *pf) | |||
1824 | "not enough vectors. requested = %d, obtained = %d\n", | 1842 | "not enough vectors. requested = %d, obtained = %d\n", |
1825 | v_budget, v_actual); | 1843 | v_budget, v_actual); |
1826 | if (v_actual >= (pf->num_lan_msix + 1)) { | 1844 | if (v_actual >= (pf->num_lan_msix + 1)) { |
1827 | pf->num_avail_msix = v_actual - (pf->num_lan_msix + 1); | 1845 | pf->num_avail_sw_msix = v_actual - |
1846 | (pf->num_lan_msix + 1); | ||
1828 | } else if (v_actual >= 2) { | 1847 | } else if (v_actual >= 2) { |
1829 | pf->num_lan_msix = 1; | 1848 | pf->num_lan_msix = 1; |
1830 | pf->num_avail_msix = v_actual - 2; | 1849 | pf->num_avail_sw_msix = v_actual - 2; |
1831 | } else { | 1850 | } else { |
1832 | pci_disable_msix(pf->pdev); | 1851 | pci_disable_msix(pf->pdev); |
1833 | err = -ERANGE; | 1852 | err = -ERANGE; |
@@ -1860,12 +1879,32 @@ static void ice_dis_msix(struct ice_pf *pf) | |||
1860 | } | 1879 | } |
1861 | 1880 | ||
1862 | /** | 1881 | /** |
1882 | * ice_clear_interrupt_scheme - Undo things done by ice_init_interrupt_scheme | ||
1883 | * @pf: board private structure | ||
1884 | */ | ||
1885 | static void ice_clear_interrupt_scheme(struct ice_pf *pf) | ||
1886 | { | ||
1887 | if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags)) | ||
1888 | ice_dis_msix(pf); | ||
1889 | |||
1890 | if (pf->sw_irq_tracker) { | ||
1891 | devm_kfree(&pf->pdev->dev, pf->sw_irq_tracker); | ||
1892 | pf->sw_irq_tracker = NULL; | ||
1893 | } | ||
1894 | |||
1895 | if (pf->hw_irq_tracker) { | ||
1896 | devm_kfree(&pf->pdev->dev, pf->hw_irq_tracker); | ||
1897 | pf->hw_irq_tracker = NULL; | ||
1898 | } | ||
1899 | } | ||
1900 | |||
1901 | /** | ||
1863 | * ice_init_interrupt_scheme - Determine proper interrupt scheme | 1902 | * ice_init_interrupt_scheme - Determine proper interrupt scheme |
1864 | * @pf: board private structure to initialize | 1903 | * @pf: board private structure to initialize |
1865 | */ | 1904 | */ |
1866 | static int ice_init_interrupt_scheme(struct ice_pf *pf) | 1905 | static int ice_init_interrupt_scheme(struct ice_pf *pf) |
1867 | { | 1906 | { |
1868 | int vectors = 0; | 1907 | int vectors = 0, hw_vectors = 0; |
1869 | ssize_t size; | 1908 | ssize_t size; |
1870 | 1909 | ||
1871 | if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags)) | 1910 | if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags)) |
@@ -1879,30 +1918,31 @@ static int ice_init_interrupt_scheme(struct ice_pf *pf) | |||
1879 | /* set up vector assignment tracking */ | 1918 | /* set up vector assignment tracking */ |
1880 | size = sizeof(struct ice_res_tracker) + (sizeof(u16) * vectors); | 1919 | size = sizeof(struct ice_res_tracker) + (sizeof(u16) * vectors); |
1881 | 1920 | ||
1882 | pf->irq_tracker = devm_kzalloc(&pf->pdev->dev, size, GFP_KERNEL); | 1921 | pf->sw_irq_tracker = devm_kzalloc(&pf->pdev->dev, size, GFP_KERNEL); |
1883 | if (!pf->irq_tracker) { | 1922 | if (!pf->sw_irq_tracker) { |
1884 | ice_dis_msix(pf); | 1923 | ice_dis_msix(pf); |
1885 | return -ENOMEM; | 1924 | return -ENOMEM; |
1886 | } | 1925 | } |
1887 | 1926 | ||
1888 | pf->irq_tracker->num_entries = vectors; | 1927 | /* populate SW interrupts pool with number of OS granted IRQs. */ |
1928 | pf->num_avail_sw_msix = vectors; | ||
1929 | pf->sw_irq_tracker->num_entries = vectors; | ||
1889 | 1930 | ||
1890 | return 0; | 1931 | /* set up HW vector assignment tracking */ |
1891 | } | 1932 | hw_vectors = pf->hw.func_caps.common_cap.num_msix_vectors; |
1933 | size = sizeof(struct ice_res_tracker) + (sizeof(u16) * hw_vectors); | ||
1892 | 1934 | ||
1893 | /** | 1935 | pf->hw_irq_tracker = devm_kzalloc(&pf->pdev->dev, size, GFP_KERNEL); |
1894 | * ice_clear_interrupt_scheme - Undo things done by ice_init_interrupt_scheme | 1936 | if (!pf->hw_irq_tracker) { |
1895 | * @pf: board private structure | 1937 | ice_clear_interrupt_scheme(pf); |
1896 | */ | 1938 | return -ENOMEM; |
1897 | static void ice_clear_interrupt_scheme(struct ice_pf *pf) | ||
1898 | { | ||
1899 | if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags)) | ||
1900 | ice_dis_msix(pf); | ||
1901 | |||
1902 | if (pf->irq_tracker) { | ||
1903 | devm_kfree(&pf->pdev->dev, pf->irq_tracker); | ||
1904 | pf->irq_tracker = NULL; | ||
1905 | } | 1939 | } |
1940 | |||
1941 | /* populate HW interrupts pool with number of HW supported irqs. */ | ||
1942 | pf->num_avail_hw_msix = hw_vectors; | ||
1943 | pf->hw_irq_tracker->num_entries = hw_vectors; | ||
1944 | |||
1945 | return 0; | ||
1906 | } | 1946 | } |
1907 | 1947 | ||
1908 | /** | 1948 | /** |
@@ -3213,6 +3253,12 @@ static void ice_rebuild(struct ice_pf *pf) | |||
3213 | if (err) | 3253 | if (err) |
3214 | goto err_sched_init_port; | 3254 | goto err_sched_init_port; |
3215 | 3255 | ||
3256 | /* reset search_hint of irq_trackers to 0 since interrupts are | ||
3257 | * reclaimed and could be allocated from beginning during VSI rebuild | ||
3258 | */ | ||
3259 | pf->sw_irq_tracker->search_hint = 0; | ||
3260 | pf->hw_irq_tracker->search_hint = 0; | ||
3261 | |||
3216 | err = ice_vsi_rebuild_all(pf); | 3262 | err = ice_vsi_rebuild_all(pf); |
3217 | if (err) { | 3263 | if (err) { |
3218 | dev_err(dev, "ice_vsi_rebuild_all failed\n"); | 3264 | dev_err(dev, "ice_vsi_rebuild_all failed\n"); |
@@ -3610,7 +3656,7 @@ static void ice_tx_timeout(struct net_device *netdev) | |||
3610 | if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags)) | 3656 | if (test_bit(ICE_FLAG_MSIX_ENA, pf->flags)) |
3611 | val = rd32(&pf->hw, | 3657 | val = rd32(&pf->hw, |
3612 | GLINT_DYN_CTL(tx_ring->q_vector->v_idx + | 3658 | GLINT_DYN_CTL(tx_ring->q_vector->v_idx + |
3613 | tx_ring->vsi->base_vector - 1)); | 3659 | tx_ring->vsi->hw_base_vector)); |
3614 | 3660 | ||
3615 | netdev_info(netdev, "tx_timeout: VSI_num: %d, Q %d, NTC: 0x%x, HWB: 0x%x, NTU: 0x%x, TAIL: 0x%x, INT: 0x%x\n", | 3661 | netdev_info(netdev, "tx_timeout: VSI_num: %d, Q %d, NTC: 0x%x, HWB: 0x%x, NTU: 0x%x, TAIL: 0x%x, INT: 0x%x\n", |
3616 | vsi->vsi_num, hung_queue, tx_ring->next_to_clean, | 3662 | vsi->vsi_num, hung_queue, tx_ring->next_to_clean, |