@@ -284,8 +284,26 @@ void bnxt_vf_reps_open(struct bnxt *bp)
284
284
if (bp -> eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV )
285
285
return ;
286
286
287
- for (i = 0 ; i < pci_num_vf (bp -> pdev ); i ++ )
288
- bnxt_vf_rep_open (bp -> vf_reps [i ]-> dev );
287
+ for (i = 0 ; i < pci_num_vf (bp -> pdev ); i ++ ) {
288
+ /* Open the VF-Rep only if it is allocated in the FW */
289
+ if (bp -> vf_reps [i ]-> tx_cfa_action != CFA_HANDLE_INVALID )
290
+ bnxt_vf_rep_open (bp -> vf_reps [i ]-> dev );
291
+ }
292
+ }
293
+
294
+ static void __bnxt_free_one_vf_rep (struct bnxt * bp , struct bnxt_vf_rep * vf_rep )
295
+ {
296
+ if (!vf_rep )
297
+ return ;
298
+
299
+ if (vf_rep -> dst ) {
300
+ dst_release ((struct dst_entry * )vf_rep -> dst );
301
+ vf_rep -> dst = NULL ;
302
+ }
303
+ if (vf_rep -> tx_cfa_action != CFA_HANDLE_INVALID ) {
304
+ hwrm_cfa_vfr_free (bp , vf_rep -> vf_idx );
305
+ vf_rep -> tx_cfa_action = CFA_HANDLE_INVALID ;
306
+ }
289
307
}
290
308
291
309
static void __bnxt_vf_reps_destroy (struct bnxt * bp )
@@ -297,11 +315,7 @@ static void __bnxt_vf_reps_destroy(struct bnxt *bp)
297
315
for (i = 0 ; i < num_vfs ; i ++ ) {
298
316
vf_rep = bp -> vf_reps [i ];
299
317
if (vf_rep ) {
300
- dst_release ((struct dst_entry * )vf_rep -> dst );
301
-
302
- if (vf_rep -> tx_cfa_action != CFA_HANDLE_INVALID )
303
- hwrm_cfa_vfr_free (bp , vf_rep -> vf_idx );
304
-
318
+ __bnxt_free_one_vf_rep (bp , vf_rep );
305
319
if (vf_rep -> dev ) {
306
320
/* if register_netdev failed, then netdev_ops
307
321
* would have been set to NULL
@@ -350,6 +364,80 @@ void bnxt_vf_reps_destroy(struct bnxt *bp)
350
364
__bnxt_vf_reps_destroy (bp );
351
365
}
352
366
367
+ /* Free the VF-Reps in firmware, during firmware hot-reset processing.
368
+ * Note that the VF-Rep netdevs are still active (not unregistered) during
369
+ * this process. As the mode transition from SWITCHDEV to LEGACY happens
370
+ * under the rtnl_lock() this routine is safe under the rtnl_lock().
371
+ */
372
+ void bnxt_vf_reps_free (struct bnxt * bp )
373
+ {
374
+ u16 num_vfs = pci_num_vf (bp -> pdev );
375
+ int i ;
376
+
377
+ if (bp -> eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV )
378
+ return ;
379
+
380
+ for (i = 0 ; i < num_vfs ; i ++ )
381
+ __bnxt_free_one_vf_rep (bp , bp -> vf_reps [i ]);
382
+ }
383
+
384
+ static int bnxt_alloc_vf_rep (struct bnxt * bp , struct bnxt_vf_rep * vf_rep ,
385
+ u16 * cfa_code_map )
386
+ {
387
+ /* get cfa handles from FW */
388
+ if (hwrm_cfa_vfr_alloc (bp , vf_rep -> vf_idx , & vf_rep -> tx_cfa_action ,
389
+ & vf_rep -> rx_cfa_code ))
390
+ return - ENOLINK ;
391
+
392
+ cfa_code_map [vf_rep -> rx_cfa_code ] = vf_rep -> vf_idx ;
393
+ vf_rep -> dst = metadata_dst_alloc (0 , METADATA_HW_PORT_MUX , GFP_KERNEL );
394
+ if (!vf_rep -> dst )
395
+ return - ENOMEM ;
396
+
397
+ /* only cfa_action is needed to mux a packet while TXing */
398
+ vf_rep -> dst -> u .port_info .port_id = vf_rep -> tx_cfa_action ;
399
+ vf_rep -> dst -> u .port_info .lower_dev = bp -> dev ;
400
+
401
+ return 0 ;
402
+ }
403
+
404
+ /* Allocate the VF-Reps in firmware, during firmware hot-reset processing.
405
+ * Note that the VF-Rep netdevs are still active (not unregistered) during
406
+ * this process. As the mode transition from SWITCHDEV to LEGACY happens
407
+ * under the rtnl_lock() this routine is safe under the rtnl_lock().
408
+ */
409
+ int bnxt_vf_reps_alloc (struct bnxt * bp )
410
+ {
411
+ u16 * cfa_code_map = bp -> cfa_code_map , num_vfs = pci_num_vf (bp -> pdev );
412
+ struct bnxt_vf_rep * vf_rep ;
413
+ int rc , i ;
414
+
415
+ if (bp -> eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV )
416
+ return 0 ;
417
+
418
+ if (!cfa_code_map )
419
+ return - EINVAL ;
420
+
421
+ for (i = 0 ; i < MAX_CFA_CODE ; i ++ )
422
+ cfa_code_map [i ] = VF_IDX_INVALID ;
423
+
424
+ for (i = 0 ; i < num_vfs ; i ++ ) {
425
+ vf_rep = bp -> vf_reps [i ];
426
+ vf_rep -> vf_idx = i ;
427
+
428
+ rc = bnxt_alloc_vf_rep (bp , vf_rep , cfa_code_map );
429
+ if (rc )
430
+ goto err ;
431
+ }
432
+
433
+ return 0 ;
434
+
435
+ err :
436
+ netdev_info (bp -> dev , "%s error=%d\n" , __func__ , rc );
437
+ bnxt_vf_reps_free (bp );
438
+ return rc ;
439
+ }
440
+
353
441
/* Use the OUI of the PF's perm addr and report the same mac addr
354
442
* for the same VF-rep each time
355
443
*/
@@ -428,25 +516,9 @@ static int bnxt_vf_reps_create(struct bnxt *bp)
428
516
vf_rep -> vf_idx = i ;
429
517
vf_rep -> tx_cfa_action = CFA_HANDLE_INVALID ;
430
518
431
- /* get cfa handles from FW */
432
- rc = hwrm_cfa_vfr_alloc (bp , vf_rep -> vf_idx ,
433
- & vf_rep -> tx_cfa_action ,
434
- & vf_rep -> rx_cfa_code );
435
- if (rc ) {
436
- rc = - ENOLINK ;
519
+ rc = bnxt_alloc_vf_rep (bp , vf_rep , cfa_code_map );
520
+ if (rc )
437
521
goto err ;
438
- }
439
- cfa_code_map [vf_rep -> rx_cfa_code ] = vf_rep -> vf_idx ;
440
-
441
- vf_rep -> dst = metadata_dst_alloc (0 , METADATA_HW_PORT_MUX ,
442
- GFP_KERNEL );
443
- if (!vf_rep -> dst ) {
444
- rc = - ENOMEM ;
445
- goto err ;
446
- }
447
- /* only cfa_action is needed to mux a packet while TXing */
448
- vf_rep -> dst -> u .port_info .port_id = vf_rep -> tx_cfa_action ;
449
- vf_rep -> dst -> u .port_info .lower_dev = bp -> dev ;
450
522
451
523
bnxt_vf_rep_netdev_init (bp , vf_rep , dev );
452
524
rc = register_netdev (dev );
0 commit comments