66#include "fw_reset.h"
77#include "diag/fw_tracer.h"
88#include "lib/tout.h"
9+ #include "sf/sf.h"
910
1011enum {
1112 MLX5_FW_RESET_FLAGS_RESET_REQUESTED ,
1213 MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST ,
1314 MLX5_FW_RESET_FLAGS_PENDING_COMP ,
1415 MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS ,
15- MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED
16+ MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED ,
17+ MLX5_FW_RESET_FLAGS_UNLOAD_EVENT ,
1618};
1719
1820struct mlx5_fw_reset {
@@ -219,7 +221,7 @@ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev)
219221 return mlx5_reg_mfrl_set (dev , MLX5_MFRL_REG_RESET_LEVEL0 , 0 , 0 , false);
220222}
221223
222- static void mlx5_fw_reset_complete_reload (struct mlx5_core_dev * dev , bool unloaded )
224+ static void mlx5_fw_reset_complete_reload (struct mlx5_core_dev * dev )
223225{
224226 struct mlx5_fw_reset * fw_reset = dev -> priv .fw_reset ;
225227 struct devlink * devlink = priv_to_devlink (dev );
@@ -228,8 +230,7 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unload
228230 if (test_bit (MLX5_FW_RESET_FLAGS_PENDING_COMP , & fw_reset -> reset_flags )) {
229231 complete (& fw_reset -> done );
230232 } else {
231- if (!unloaded )
232- mlx5_unload_one (dev , false);
233+ mlx5_sync_reset_unload_flow (dev , false);
233234 if (mlx5_health_wait_pci_up (dev ))
234235 mlx5_core_err (dev , "reset reload flow aborted, PCI reads still not working\n" );
235236 else
@@ -272,7 +273,7 @@ static void mlx5_sync_reset_reload_work(struct work_struct *work)
272273
273274 mlx5_sync_reset_clear_reset_requested (dev , false);
274275 mlx5_enter_error_state (dev , true);
275- mlx5_fw_reset_complete_reload (dev , false );
276+ mlx5_fw_reset_complete_reload (dev );
276277}
277278
278279#define MLX5_RESET_POLL_INTERVAL (HZ / 10)
@@ -428,6 +429,11 @@ static bool mlx5_is_reset_now_capable(struct mlx5_core_dev *dev,
428429 return false;
429430 }
430431
432+ if (!mlx5_core_is_ecpf (dev ) && !mlx5_sf_table_empty (dev )) {
433+ mlx5_core_warn (dev , "SFs should be removed before reset\n" );
434+ return false;
435+ }
436+
431437#if IS_ENABLED (CONFIG_HOTPLUG_PCI_PCIE )
432438 if (reset_method != MLX5_MFRL_REG_PCI_RESET_METHOD_HOT_RESET ) {
433439 err = mlx5_check_hotplug_interrupt (dev , bridge );
@@ -586,6 +592,65 @@ static int mlx5_sync_pci_reset(struct mlx5_core_dev *dev, u8 reset_method)
586592 return err ;
587593}
588594
595+ void mlx5_sync_reset_unload_flow (struct mlx5_core_dev * dev , bool locked )
596+ {
597+ struct mlx5_fw_reset * fw_reset = dev -> priv .fw_reset ;
598+ unsigned long timeout ;
599+ int poll_freq = 20 ;
600+ bool reset_action ;
601+ u8 rst_state ;
602+ int err ;
603+
604+ if (locked )
605+ mlx5_unload_one_devl_locked (dev , false);
606+ else
607+ mlx5_unload_one (dev , false);
608+
609+ if (!test_bit (MLX5_FW_RESET_FLAGS_UNLOAD_EVENT , & fw_reset -> reset_flags ))
610+ return ;
611+
612+ mlx5_set_fw_rst_ack (dev );
613+ mlx5_core_warn (dev , "Sync Reset Unload done, device reset expected\n" );
614+
615+ reset_action = false;
616+ timeout = jiffies + msecs_to_jiffies (mlx5_tout_ms (dev , RESET_UNLOAD ));
617+ do {
618+ rst_state = mlx5_get_fw_rst_state (dev );
619+ if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
620+ rst_state == MLX5_FW_RST_STATE_IDLE ) {
621+ reset_action = true;
622+ break ;
623+ }
624+ if (rst_state == MLX5_FW_RST_STATE_DROP_MODE ) {
625+ mlx5_core_info (dev , "Sync Reset Drop mode ack\n" );
626+ mlx5_set_fw_rst_ack (dev );
627+ poll_freq = 1000 ;
628+ }
629+ msleep (poll_freq );
630+ } while (!time_after (jiffies , timeout ));
631+
632+ if (!reset_action ) {
633+ mlx5_core_err (dev , "Got timeout waiting for sync reset action, state = %u\n" ,
634+ rst_state );
635+ fw_reset -> ret = - ETIMEDOUT ;
636+ goto done ;
637+ }
638+
639+ mlx5_core_warn (dev , "Sync Reset, got reset action. rst_state = %u\n" ,
640+ rst_state );
641+ if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ) {
642+ err = mlx5_sync_pci_reset (dev , fw_reset -> reset_method );
643+ if (err ) {
644+ mlx5_core_warn (dev , "mlx5_sync_pci_reset failed, err %d\n" ,
645+ err );
646+ fw_reset -> ret = err ;
647+ }
648+ }
649+
650+ done :
651+ clear_bit (MLX5_FW_RESET_FLAGS_UNLOAD_EVENT , & fw_reset -> reset_flags );
652+ }
653+
589654static void mlx5_sync_reset_now_event (struct work_struct * work )
590655{
591656 struct mlx5_fw_reset * fw_reset = container_of (work , struct mlx5_fw_reset ,
@@ -613,17 +678,13 @@ static void mlx5_sync_reset_now_event(struct work_struct *work)
613678 mlx5_enter_error_state (dev , true);
614679done :
615680 fw_reset -> ret = err ;
616- mlx5_fw_reset_complete_reload (dev , false );
681+ mlx5_fw_reset_complete_reload (dev );
617682}
618683
619684static void mlx5_sync_reset_unload_event (struct work_struct * work )
620685{
621686 struct mlx5_fw_reset * fw_reset ;
622687 struct mlx5_core_dev * dev ;
623- unsigned long timeout ;
624- int poll_freq = 20 ;
625- bool reset_action ;
626- u8 rst_state ;
627688 int err ;
628689
629690 fw_reset = container_of (work , struct mlx5_fw_reset , reset_unload_work );
@@ -632,6 +693,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
632693 if (mlx5_sync_reset_clear_reset_requested (dev , false))
633694 return ;
634695
696+ set_bit (MLX5_FW_RESET_FLAGS_UNLOAD_EVENT , & fw_reset -> reset_flags );
635697 mlx5_core_warn (dev , "Sync Reset Unload. Function is forced down.\n" );
636698
637699 err = mlx5_cmd_fast_teardown_hca (dev );
@@ -640,49 +702,7 @@ static void mlx5_sync_reset_unload_event(struct work_struct *work)
640702 else
641703 mlx5_enter_error_state (dev , true);
642704
643- if (test_bit (MLX5_FW_RESET_FLAGS_PENDING_COMP , & fw_reset -> reset_flags ))
644- mlx5_unload_one_devl_locked (dev , false);
645- else
646- mlx5_unload_one (dev , false);
647-
648- mlx5_set_fw_rst_ack (dev );
649- mlx5_core_warn (dev , "Sync Reset Unload done, device reset expected\n" );
650-
651- reset_action = false;
652- timeout = jiffies + msecs_to_jiffies (mlx5_tout_ms (dev , RESET_UNLOAD ));
653- do {
654- rst_state = mlx5_get_fw_rst_state (dev );
655- if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ||
656- rst_state == MLX5_FW_RST_STATE_IDLE ) {
657- reset_action = true;
658- break ;
659- }
660- if (rst_state == MLX5_FW_RST_STATE_DROP_MODE ) {
661- mlx5_core_info (dev , "Sync Reset Drop mode ack\n" );
662- mlx5_set_fw_rst_ack (dev );
663- poll_freq = 1000 ;
664- }
665- msleep (poll_freq );
666- } while (!time_after (jiffies , timeout ));
667-
668- if (!reset_action ) {
669- mlx5_core_err (dev , "Got timeout waiting for sync reset action, state = %u\n" ,
670- rst_state );
671- fw_reset -> ret = - ETIMEDOUT ;
672- goto done ;
673- }
674-
675- mlx5_core_warn (dev , "Sync Reset, got reset action. rst_state = %u\n" , rst_state );
676- if (rst_state == MLX5_FW_RST_STATE_TOGGLE_REQ ) {
677- err = mlx5_sync_pci_reset (dev , fw_reset -> reset_method );
678- if (err ) {
679- mlx5_core_warn (dev , "mlx5_sync_pci_reset failed, err %d\n" , err );
680- fw_reset -> ret = err ;
681- }
682- }
683-
684- done :
685- mlx5_fw_reset_complete_reload (dev , true);
705+ mlx5_fw_reset_complete_reload (dev );
686706}
687707
688708static void mlx5_sync_reset_abort_event (struct work_struct * work )
0 commit comments