@@ -445,12 +445,13 @@ int pdsc_setup(struct pdsc *pdsc, bool init)
445445 goto err_out_teardown ;
446446
447447 /* Set up the VIFs */
448- err = pdsc_viftypes_init (pdsc );
449- if (err )
450- goto err_out_teardown ;
448+ if (init ) {
449+ err = pdsc_viftypes_init (pdsc );
450+ if (err )
451+ goto err_out_teardown ;
451452
452- if (init )
453453 pdsc_debugfs_add_viftype (pdsc );
454+ }
454455
455456 clear_bit (PDSC_S_FW_DEAD , & pdsc -> state );
456457 return 0 ;
@@ -469,8 +470,10 @@ void pdsc_teardown(struct pdsc *pdsc, bool removing)
469470 pdsc_qcq_free (pdsc , & pdsc -> notifyqcq );
470471 pdsc_qcq_free (pdsc , & pdsc -> adminqcq );
471472
472- kfree (pdsc -> viftype_status );
473- pdsc -> viftype_status = NULL ;
473+ if (removing ) {
474+ kfree (pdsc -> viftype_status );
475+ pdsc -> viftype_status = NULL ;
476+ }
474477
475478 if (pdsc -> intr_info ) {
476479 for (i = 0 ; i < pdsc -> nintrs ; i ++ )
@@ -512,18 +515,21 @@ void pdsc_stop(struct pdsc *pdsc)
512515 PDS_CORE_INTR_MASK_SET );
513516}
514517
515- static void pdsc_fw_down (struct pdsc * pdsc )
518+ void pdsc_fw_down (struct pdsc * pdsc )
516519{
517520 union pds_core_notifyq_comp reset_event = {
518521 .reset .ecode = cpu_to_le16 (PDS_EVENT_RESET ),
519522 .reset .state = 0 ,
520523 };
521524
522525 if (test_and_set_bit (PDSC_S_FW_DEAD , & pdsc -> state )) {
523- dev_err (pdsc -> dev , "%s: already happening\n" , __func__ );
526+ dev_warn (pdsc -> dev , "%s: already happening\n" , __func__ );
524527 return ;
525528 }
526529
530+ if (pdsc -> pdev -> is_virtfn )
531+ return ;
532+
527533 /* Notify clients of fw_down */
528534 if (pdsc -> fw_reporter )
529535 devlink_health_report (pdsc -> fw_reporter , "FW down reported" , pdsc );
@@ -533,7 +539,7 @@ static void pdsc_fw_down(struct pdsc *pdsc)
533539 pdsc_teardown (pdsc , PDSC_TEARDOWN_RECOVERY );
534540}
535541
536- static void pdsc_fw_up (struct pdsc * pdsc )
542+ void pdsc_fw_up (struct pdsc * pdsc )
537543{
538544 union pds_core_notifyq_comp reset_event = {
539545 .reset .ecode = cpu_to_le16 (PDS_EVENT_RESET ),
@@ -546,6 +552,11 @@ static void pdsc_fw_up(struct pdsc *pdsc)
546552 return ;
547553 }
548554
555+ if (pdsc -> pdev -> is_virtfn ) {
556+ clear_bit (PDSC_S_FW_DEAD , & pdsc -> state );
557+ return ;
558+ }
559+
549560 err = pdsc_setup (pdsc , PDSC_SETUP_RECOVERY );
550561 if (err )
551562 goto err_out ;
@@ -567,6 +578,18 @@ static void pdsc_fw_up(struct pdsc *pdsc)
567578 pdsc_teardown (pdsc , PDSC_TEARDOWN_RECOVERY );
568579}
569580
581+ static void pdsc_check_pci_health (struct pdsc * pdsc )
582+ {
583+ u8 fw_status = ioread8 (& pdsc -> info_regs -> fw_status );
584+
585+ /* is PCI broken? */
586+ if (fw_status != PDS_RC_BAD_PCI )
587+ return ;
588+
589+ pdsc_reset_prepare (pdsc -> pdev );
590+ pdsc_reset_done (pdsc -> pdev );
591+ }
592+
570593void pdsc_health_thread (struct work_struct * work )
571594{
572595 struct pdsc * pdsc = container_of (work , struct pdsc , health_work );
@@ -593,6 +616,8 @@ void pdsc_health_thread(struct work_struct *work)
593616 pdsc_fw_down (pdsc );
594617 }
595618
619+ pdsc_check_pci_health (pdsc );
620+
596621 pdsc -> fw_generation = pdsc -> fw_status & PDS_CORE_FW_STS_F_GENERATION ;
597622
598623out_unlock :
0 commit comments