23
23
24
24
#include "fpga_mgmt_internal.h"
25
25
26
+ /** Synchronous API (load/clear) default timeout and delay msecs */
27
+ #define FPGA_MGMT_SYNC_TIMEOUT 300
28
+ #define FPGA_MGMT_SYNC_DELAY_MSEC 200
29
+
26
30
struct fgpa_mgmt_state_s fpga_mgmt_state = {
27
31
.timeout = FPGA_MGMT_TIMEOUT_DFLT ,
28
- .delay_msec = FPGA_MGMT_DELAY_MSEC_DFLT
32
+ .delay_msec = FPGA_MGMT_DELAY_MSEC_DFLT ,
29
33
};
30
34
31
35
int fpga_mgmt_init (void )
@@ -132,14 +136,16 @@ const char *fpga_mgmt_get_status_name(int status)
132
136
return FPGA_STATUS2STR (status );
133
137
}
134
138
135
- const char * fpga_mgmt_strerror (int err ) {
139
+ const char * fpga_mgmt_strerror (int err )
140
+ {
136
141
if (err < 0 ) {
137
142
return strerror (- err );
138
143
}
139
144
return FPGA_ERR2STR (err );
140
145
}
141
146
142
- int fpga_mgmt_clear_local_image (int slot_id ) {
147
+ int fpga_mgmt_clear_local_image (int slot_id )
148
+ {
143
149
int ret ;
144
150
uint32_t len ;
145
151
union afi_cmd cmd ;
@@ -162,7 +168,53 @@ int fpga_mgmt_clear_local_image(int slot_id) {
162
168
return ret ;
163
169
}
164
170
165
- int fpga_mgmt_load_local_image (int slot_id , char * afi_id ) {
171
+ int fpga_mgmt_clear_local_image_sync (int slot_id ,
172
+ uint32_t timeout , uint32_t delay_msec ,
173
+ struct fpga_mgmt_image_info * info )
174
+ {
175
+ struct fpga_mgmt_image_info tmp_info ;
176
+ uint32_t retries = 0 ;
177
+ bool done = false;
178
+ int status ;
179
+ int ret ;
180
+
181
+ uint32_t timeout_tmp = (timeout > FPGA_MGMT_SYNC_TIMEOUT ) ?
182
+ timeout : FPGA_MGMT_SYNC_TIMEOUT ;
183
+ uint32_t delay_msec_tmp = (delay_msec > FPGA_MGMT_SYNC_DELAY_MSEC ) ?
184
+ delay_msec : FPGA_MGMT_SYNC_DELAY_MSEC ;
185
+
186
+ memset (& tmp_info , 0 , sizeof (tmp_info ));
187
+
188
+ ret = fpga_mgmt_clear_local_image (slot_id );
189
+ fail_on (ret , out , "fpga_mgmt_clear_local_image failed" );
190
+
191
+ while (!done ) {
192
+ ret = fpga_mgmt_describe_local_image (slot_id , & tmp_info , 0 ); /** flags==0 */
193
+
194
+ status = (ret == 0 ) ? tmp_info .status : FPGA_STATUS_END ;
195
+ if (status == FPGA_STATUS_CLEARED ) {
196
+ done = true;
197
+ } else {
198
+ fail_on (ret = (retries >= timeout_tmp ) ? - ETIMEDOUT : 0 , out ,
199
+ "fpga_mgmt_describe_local_image timed out, status=%s(%d), retries=%u" ,
200
+ FPGA_STATUS2STR (status ), status , retries );
201
+ retries ++ ;
202
+ msleep (delay_msec_tmp );
203
+ }
204
+ }
205
+
206
+ ret = fpga_pci_rescan_slot_app_pfs (slot_id );
207
+ fail_on (ret , out , "fpga_pci_rescan_slot_app_pfs failed" );
208
+
209
+ if (info ) {
210
+ * info = tmp_info ;
211
+ }
212
+ out :
213
+ return ret ;
214
+ }
215
+
216
+ int fpga_mgmt_load_local_image (int slot_id , char * afi_id )
217
+ {
166
218
int ret ;
167
219
uint32_t len ;
168
220
union afi_cmd cmd ;
@@ -185,58 +237,113 @@ int fpga_mgmt_load_local_image(int slot_id, char *afi_id) {
185
237
return ret ;
186
238
}
187
239
188
- int fpga_mgmt_get_vLED_status (int slot_id , uint16_t * status ) {
240
+ int fpga_mgmt_load_local_image_sync (int slot_id , char * afi_id ,
241
+ uint32_t timeout , uint32_t delay_msec ,
242
+ struct fpga_mgmt_image_info * info )
243
+ {
244
+ struct fpga_mgmt_image_info tmp_info ;
245
+ uint32_t retries = 0 ;
246
+ bool done = false;
247
+ int status ;
189
248
int ret ;
190
- pci_bar_handle_t led_pci_bar ;
191
- uint32_t read_data ;
192
249
193
- ret = fpga_pci_attach (slot_id , FPGA_MGMT_PF , MGMT_PF_BAR0 , 0 , & led_pci_bar );
194
- if (ret )
195
- return FPGA_ERR_FAIL ;
250
+ uint32_t timeout_tmp = (timeout > FPGA_MGMT_SYNC_TIMEOUT ) ?
251
+ timeout : FPGA_MGMT_SYNC_TIMEOUT ;
252
+ uint32_t delay_msec_tmp = (delay_msec > FPGA_MGMT_SYNC_DELAY_MSEC ) ?
253
+ delay_msec : FPGA_MGMT_SYNC_DELAY_MSEC ;
254
+
255
+ memset (& tmp_info , 0 , sizeof (tmp_info ));
256
+
257
+ ret = fpga_mgmt_load_local_image (slot_id , afi_id );
258
+ fail_on (ret , out , "fpga_mgmt_load_local_image failed" );
259
+
260
+ while (!done ) {
261
+ ret = fpga_mgmt_describe_local_image (slot_id , & tmp_info , 0 ); /** flags==0 */
262
+
263
+ status = (ret == 0 ) ? tmp_info .status : FPGA_STATUS_END ;
264
+ if (status == FPGA_STATUS_LOADED ) {
265
+ /** Sanity check the afi_id */
266
+ ret = strncmp (afi_id , tmp_info .ids .afi_id , sizeof (tmp_info .ids .afi_id ));
267
+ fail_on (ret , out , "AFI ID mismatch: requested afi_id=%s, loaded afi_id=%s" ,
268
+ afi_id , tmp_info .ids .afi_id );
269
+ done = true;
270
+ } else {
271
+ fail_on (ret = (retries >= timeout_tmp ) ? - ETIMEDOUT : 0 , out ,
272
+ "fpga_mgmt_describe_local_image timed out, status=%s(%d), retries=%u" ,
273
+ FPGA_STATUS2STR (status ), status , retries );
274
+ retries ++ ;
275
+ msleep (delay_msec_tmp );
276
+ }
277
+ }
278
+
279
+ ret = fpga_pci_rescan_slot_app_pfs (slot_id );
280
+ fail_on (ret , out , "fpga_pci_rescan_slot_app_pfs failed" );
281
+
282
+ if (info ) {
283
+ * info = tmp_info ;
284
+ }
285
+ out :
286
+ return ret ;
287
+ }
288
+
289
+ int fpga_mgmt_get_vLED_status (int slot_id , uint16_t * status )
290
+ {
291
+ pci_bar_handle_t led_pci_bar ;
292
+ uint32_t read_data ;
293
+ int ret ;
294
+
295
+ ret = fpga_pci_attach (slot_id , FPGA_MGMT_PF , MGMT_PF_BAR0 , 0 , & led_pci_bar );
296
+ fail_on (ret , out , "fpga_pci_attach failed" );
196
297
197
- ret = fpga_pci_peek (led_pci_bar ,F1_VIRTUAL_LED_REG_OFFSET ,& read_data );
198
- /* All this code assumes little endian, it would need rework for supporting non x86/arm platforms */
199
- * (status ) = (uint16_t )( read_data & 0x0000FFFF );
298
+ ret = fpga_pci_peek (led_pci_bar , F1_VIRTUAL_LED_REG_OFFSET , & read_data );
299
+ fail_on (ret , out , "fpga_pci_peek failed" );
200
300
301
+ /* All this code assumes little endian, it would need rework for supporting non x86/arm platforms */
302
+ * status = (uint16_t )(read_data & 0x0000FFFF );
201
303
202
- fpga_pci_detach (led_pci_bar );
304
+ ret = fpga_pci_detach (led_pci_bar );
305
+ fail_on (ret , out , "fpga_pci_detach failed" );
306
+ out :
203
307
return ret ;
204
308
}
205
309
206
- int fpga_mgmt_set_vDIP (int slot_id , uint16_t value ) {
207
- int ret ;
208
- pci_bar_handle_t dip_pci_bar ;
209
- uint32_t write_data ;
210
-
211
- ret = fpga_pci_attach (slot_id , FPGA_MGMT_PF , MGMT_PF_BAR0 , 0 , & dip_pci_bar );
212
- if (ret )
213
- return FPGA_ERR_FAIL ;
310
+ int fpga_mgmt_set_vDIP (int slot_id , uint16_t value )
311
+ {
312
+ pci_bar_handle_t dip_pci_bar ;
313
+ uint32_t write_data ;
314
+ int ret ;
214
315
316
+ ret = fpga_pci_attach (slot_id , FPGA_MGMT_PF , MGMT_PF_BAR0 , 0 , & dip_pci_bar );
317
+ fail_on (ret , out , "fpga_pci_attach failed" );
215
318
216
319
write_data = (uint32_t ) value ;
217
320
218
- ret = fpga_pci_poke (dip_pci_bar ,F1_VIRTUAL_DIP_REG_OFFSET ,write_data );
219
-
321
+ ret = fpga_pci_poke (dip_pci_bar , F1_VIRTUAL_DIP_REG_OFFSET , write_data );
322
+ fail_on ( ret , out , "fpga_pci_poke failed" );
220
323
221
- fpga_pci_detach (dip_pci_bar );
222
- return ret ;
324
+ ret = fpga_pci_detach (dip_pci_bar );
325
+ fail_on (ret , out , "fpga_pci_detach failed" );
326
+ out :
327
+ return ret ;
223
328
}
224
329
225
- int fpga_mgmt_get_vDIP_status (int slot_id , uint16_t * value ) {
226
-
227
- int ret ;
228
- pci_bar_handle_t dip_pci_bar ;
229
- uint32_t read_data ;
330
+ int fpga_mgmt_get_vDIP_status (int slot_id , uint16_t * value )
331
+ {
332
+ pci_bar_handle_t dip_pci_bar ;
333
+ uint32_t read_data ;
334
+ int ret ;
230
335
231
- ret = fpga_pci_attach (slot_id , FPGA_MGMT_PF , MGMT_PF_BAR0 , 0 , & dip_pci_bar );
232
- if (ret )
233
- return FPGA_ERR_FAIL ;
336
+ ret = fpga_pci_attach (slot_id , FPGA_MGMT_PF , MGMT_PF_BAR0 , 0 , & dip_pci_bar );
337
+ fail_on (ret , out , "fpga_pci_attach failed" );
234
338
235
- ret = fpga_pci_peek (dip_pci_bar ,F1_VIRTUAL_DIP_REG_OFFSET ,& read_data );
236
- /* All this code assumes little endian, it would need rework for supporting non x86/arm platforms */
237
- * (value ) = (uint16_t )read_data ;
339
+ ret = fpga_pci_peek (dip_pci_bar , F1_VIRTUAL_DIP_REG_OFFSET , & read_data );
340
+ fail_on (ret , out , "fpga_pci_peek failed" );
238
341
239
- fpga_pci_detach ( dip_pci_bar );
240
- return ret ;
342
+ /* All this code assumes little endian, it would need rework for supporting non x86/arm platforms */
343
+ * value = ( uint16_t ) read_data ;
241
344
345
+ ret = fpga_pci_detach (dip_pci_bar );
346
+ fail_on (ret , out , "fpga_pci_detach failed" );
347
+ out :
348
+ return ret ;
242
349
}
0 commit comments