@@ -20,6 +20,19 @@ ice_init_irq_tracker(struct ice_pf *pf, unsigned int max_vectors,
20
20
xa_init_flags (& pf -> irq_tracker .entries , XA_FLAGS_ALLOC );
21
21
}
22
22
23
+ static int
24
+ ice_init_virt_irq_tracker (struct ice_pf * pf , u32 base , u32 num_entries )
25
+ {
26
+ pf -> virt_irq_tracker .bm = bitmap_zalloc (num_entries , GFP_KERNEL );
27
+ if (!pf -> virt_irq_tracker .bm )
28
+ return - ENOMEM ;
29
+
30
+ pf -> virt_irq_tracker .num_entries = num_entries ;
31
+ pf -> virt_irq_tracker .base = base ;
32
+
33
+ return 0 ;
34
+ }
35
+
23
36
/**
24
37
* ice_deinit_irq_tracker - free xarray tracker
25
38
* @pf: board private structure
@@ -29,6 +42,11 @@ static void ice_deinit_irq_tracker(struct ice_pf *pf)
29
42
xa_destroy (& pf -> irq_tracker .entries );
30
43
}
31
44
45
+ static void ice_deinit_virt_irq_tracker (struct ice_pf * pf )
46
+ {
47
+ bitmap_free (pf -> virt_irq_tracker .bm );
48
+ }
49
+
32
50
/**
33
51
* ice_free_irq_res - free a block of resources
34
52
* @pf: board private structure
@@ -101,6 +119,7 @@ void ice_clear_interrupt_scheme(struct ice_pf *pf)
101
119
{
102
120
pci_free_irq_vectors (pf -> pdev );
103
121
ice_deinit_irq_tracker (pf );
122
+ ice_deinit_virt_irq_tracker (pf );
104
123
}
105
124
106
125
/**
@@ -120,6 +139,9 @@ int ice_init_interrupt_scheme(struct ice_pf *pf)
120
139
pf -> msix .max = min (total_vectors ,
121
140
ice_get_default_msix_amount (pf ));
122
141
142
+ pf -> msix .total = total_vectors ;
143
+ pf -> msix .rest = total_vectors - pf -> msix .max ;
144
+
123
145
if (pci_msix_can_alloc_dyn (pf -> pdev ))
124
146
vectors = pf -> msix .min ;
125
147
else
@@ -132,7 +154,7 @@ int ice_init_interrupt_scheme(struct ice_pf *pf)
132
154
133
155
ice_init_irq_tracker (pf , pf -> msix .max , vectors );
134
156
135
- return 0 ;
157
+ return ice_init_virt_irq_tracker ( pf , pf -> msix . max , pf -> msix . rest ) ;
136
158
}
137
159
138
160
/**
@@ -159,7 +181,6 @@ int ice_init_interrupt_scheme(struct ice_pf *pf)
159
181
*/
160
182
struct msi_map ice_alloc_irq (struct ice_pf * pf , bool dyn_allowed )
161
183
{
162
- int sriov_base_vector = pf -> sriov_base_vector ;
163
184
struct msi_map map = { .index = - ENOENT };
164
185
struct device * dev = ice_pf_to_dev (pf );
165
186
struct ice_irq_entry * entry ;
@@ -168,10 +189,6 @@ struct msi_map ice_alloc_irq(struct ice_pf *pf, bool dyn_allowed)
168
189
if (!entry )
169
190
return map ;
170
191
171
- /* fail if we're about to violate SRIOV vectors space */
172
- if (sriov_base_vector && entry -> index >= sriov_base_vector )
173
- goto exit_free_res ;
174
-
175
192
if (pci_msix_can_alloc_dyn (pf -> pdev ) && entry -> dynamic ) {
176
193
map = pci_msix_alloc_irq_at (pf -> pdev , entry -> index , NULL );
177
194
if (map .index < 0 )
@@ -219,26 +236,40 @@ void ice_free_irq(struct ice_pf *pf, struct msi_map map)
219
236
}
220
237
221
238
/**
222
- * ice_get_max_used_msix_vector - Get the max used interrupt vector
223
- * @pf: board private structure
239
+ * ice_virt_get_irqs - get irqs for SR-IOV usacase
240
+ * @pf: pointer to PF structure
241
+ * @needed: number of irqs to get
224
242
*
225
- * Return index of maximum used interrupt vectors with respect to the
226
- * beginning of the MSIX table. Take into account that some interrupts
227
- * may have been dynamically allocated after MSIX was initially enabled.
243
+ * This returns the first MSI-X vector index in PF space that is used by this
244
+ * VF. This index is used when accessing PF relative registers such as
245
+ * GLINT_VECT2FUNC and GLINT_DYN_CTL.
246
+ * This will always be the OICR index in the AVF driver so any functionality
247
+ * using vf->first_vector_idx for queue configuration_id: id of VF which will
248
+ * use this irqs
228
249
*/
229
- int ice_get_max_used_msix_vector (struct ice_pf * pf )
250
+ int ice_virt_get_irqs (struct ice_pf * pf , u32 needed )
230
251
{
231
- unsigned long start , index , max_idx ;
232
- void * entry ;
252
+ int res = bitmap_find_next_zero_area (pf -> virt_irq_tracker .bm ,
253
+ pf -> virt_irq_tracker .num_entries ,
254
+ 0 , needed , 0 );
233
255
234
- /* Treat all preallocated interrupts as used */
235
- start = pf -> irq_tracker .num_static ;
236
- max_idx = start - 1 ;
256
+ if (res >= pf -> virt_irq_tracker .num_entries )
257
+ return - ENOENT ;
237
258
238
- xa_for_each_start (& pf -> irq_tracker .entries , index , entry , start ) {
239
- if (index > max_idx )
240
- max_idx = index ;
241
- }
259
+ bitmap_set (pf -> virt_irq_tracker .bm , res , needed );
242
260
243
- return max_idx ;
261
+ /* conversion from number in bitmap to global irq index */
262
+ return res + pf -> virt_irq_tracker .base ;
263
+ }
264
+
265
+ /**
266
+ * ice_virt_free_irqs - free irqs used by the VF
267
+ * @pf: pointer to PF structure
268
+ * @index: first index to be free
269
+ * @irqs: number of irqs to free
270
+ */
271
+ void ice_virt_free_irqs (struct ice_pf * pf , u32 index , u32 irqs )
272
+ {
273
+ bitmap_clear (pf -> virt_irq_tracker .bm , index - pf -> virt_irq_tracker .base ,
274
+ irqs );
244
275
}
0 commit comments