Loading drivers/net/wireless/ath/wil6210/main.c +25 −8 Original line number Diff line number Diff line Loading @@ -996,6 +996,7 @@ static void wil_pre_fw_config(struct wil6210_priv *wil) int wil_reset(struct wil6210_priv *wil, bool load_fw) { int rc; unsigned long status_flags = BIT(wil_status_resetting); wil_dbg_misc(wil, "reset\n"); Loading Loading @@ -1038,6 +1039,14 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) } set_bit(wil_status_resetting, wil->status); if (test_bit(wil_status_collecting_dumps, wil->status)) { /* Device collects crash dump, cancel the reset. * following crash dump collection, reset would take place. */ wil_dbg_misc(wil, "reject reset while collecting crash dump\n"); rc = -EBUSY; goto out; } cancel_work_sync(&wil->disconnect_worker); wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); Loading @@ -1052,7 +1061,11 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) /* prevent NAPI from being scheduled and prevent wmi commands */ mutex_lock(&wil->wmi_mutex); bitmap_zero(wil->status, wil_status_last); if (test_bit(wil_status_suspending, wil->status)) status_flags |= BIT(wil_status_suspending); bitmap_and(wil->status, wil->status, &status_flags, wil_status_last); wil_dbg_misc(wil, "wil->status (0x%lx)\n", *wil->status); mutex_unlock(&wil->wmi_mutex); wil_mask_irq(wil); Loading @@ -1070,14 +1083,14 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) wil_rx_fini(wil); if (rc) { wil_bl_crash_info(wil, true); return rc; goto out; } rc = wil_get_bl_info(wil); if (rc == -EAGAIN && !load_fw) /* ignore RF error if not going up */ rc = 0; if (rc) return rc; goto out; wil_set_oob_mode(wil, oob_mode); if (load_fw) { Loading @@ -1089,10 +1102,10 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) /* Loading f/w from the file */ rc = wil_request_firmware(wil, wil->wil_fw_name, true); if (rc) return rc; goto out; rc = wil_request_firmware(wil, WIL_BOARD_FILE_NAME, true); if (rc) return rc; goto out; wil_pre_fw_config(wil); wil_release_cpu(wil); Loading @@ -1104,6 +1117,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) reinit_completion(&wil->wmi_call); reinit_completion(&wil->halp.comp); clear_bit(wil_status_resetting, wil->status); if (load_fw) { wil_configure_interrupt_moderation(wil); wil_unmask_irq(wil); Loading Loading @@ -1140,6 +1155,10 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) } return rc; out: clear_bit(wil_status_resetting, wil->status); return rc; } void wil_fw_error_recovery(struct wil6210_priv *wil) Loading Loading @@ -1247,9 +1266,7 @@ int __wil_down(struct wil6210_priv *wil) wil_abort_scan(wil, false); mutex_unlock(&wil->p2p_wdev_mutex); wil_reset(wil, false); return 0; return wil_reset(wil, false); } int wil_down(struct wil6210_priv *wil) Loading drivers/net/wireless/ath/wil6210/pm.c +17 −0 Original line number Diff line number Diff line Loading @@ -141,6 +141,13 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil) /* Prevent handling of new tx and wmi commands */ set_bit(wil_status_suspending, wil->status); if (test_bit(wil_status_collecting_dumps, wil->status)) { /* Device collects crash dump, cancel the suspend */ wil_dbg_pm(wil, "reject suspend while collecting crash dump\n"); clear_bit(wil_status_suspending, wil->status); wil->suspend_stats.rejected_by_host++; return -EBUSY; } wil_update_net_queues_bh(wil, NULL, true); if (!wil_is_tx_idle(wil)) { Loading Loading @@ -251,6 +258,15 @@ static int wil_suspend_radio_off(struct wil6210_priv *wil) wil_dbg_pm(wil, "suspend radio off\n"); set_bit(wil_status_suspending, wil->status); if (test_bit(wil_status_collecting_dumps, wil->status)) { /* Device collects crash dump, cancel the suspend */ wil_dbg_pm(wil, "reject suspend while collecting crash dump\n"); clear_bit(wil_status_suspending, wil->status); wil->suspend_stats.rejected_by_host++; return -EBUSY; } /* if netif up, hardware is alive, shut it down */ if (ndev->flags & IFF_UP) { rc = wil_down(wil); Loading @@ -275,6 +291,7 @@ static int wil_suspend_radio_off(struct wil6210_priv *wil) set_bit(wil_status_suspended, wil->status); out: clear_bit(wil_status_suspending, wil->status); wil_dbg_pm(wil, "suspend radio off: %d\n", rc); return rc; Loading drivers/net/wireless/ath/wil6210/wil6210.h +1 −0 Original line number Diff line number Diff line Loading @@ -446,6 +446,7 @@ enum { /* for wil6210_priv.status */ wil_status_suspending, /* suspend in progress */ wil_status_suspended, /* suspend completed, device is suspended */ wil_status_resuming, /* resume in progress */ wil_status_collecting_dumps, /* crashdump collection in progress */ wil_status_last /* keep last */ }; Loading drivers/net/wireless/ath/wil6210/wil_crash_dump.c +11 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,15 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size) return -EINVAL; } set_bit(wil_status_collecting_dumps, wil->status); if (test_bit(wil_status_suspending, wil->status) || test_bit(wil_status_suspended, wil->status) || test_bit(wil_status_resetting, wil->status)) { wil_err(wil, "cannot collect fw dump during suspend/reset\n"); clear_bit(wil_status_collecting_dumps, wil->status); return -EINVAL; } /* copy to crash dump area */ for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) { map = &fw_mapping[i]; Loading @@ -91,6 +100,8 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size) (const void __iomem * __force)data, len); } clear_bit(wil_status_collecting_dumps, wil->status); return 0; } Loading Loading
drivers/net/wireless/ath/wil6210/main.c +25 −8 Original line number Diff line number Diff line Loading @@ -996,6 +996,7 @@ static void wil_pre_fw_config(struct wil6210_priv *wil) int wil_reset(struct wil6210_priv *wil, bool load_fw) { int rc; unsigned long status_flags = BIT(wil_status_resetting); wil_dbg_misc(wil, "reset\n"); Loading Loading @@ -1038,6 +1039,14 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) } set_bit(wil_status_resetting, wil->status); if (test_bit(wil_status_collecting_dumps, wil->status)) { /* Device collects crash dump, cancel the reset. * following crash dump collection, reset would take place. */ wil_dbg_misc(wil, "reject reset while collecting crash dump\n"); rc = -EBUSY; goto out; } cancel_work_sync(&wil->disconnect_worker); wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); Loading @@ -1052,7 +1061,11 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) /* prevent NAPI from being scheduled and prevent wmi commands */ mutex_lock(&wil->wmi_mutex); bitmap_zero(wil->status, wil_status_last); if (test_bit(wil_status_suspending, wil->status)) status_flags |= BIT(wil_status_suspending); bitmap_and(wil->status, wil->status, &status_flags, wil_status_last); wil_dbg_misc(wil, "wil->status (0x%lx)\n", *wil->status); mutex_unlock(&wil->wmi_mutex); wil_mask_irq(wil); Loading @@ -1070,14 +1083,14 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) wil_rx_fini(wil); if (rc) { wil_bl_crash_info(wil, true); return rc; goto out; } rc = wil_get_bl_info(wil); if (rc == -EAGAIN && !load_fw) /* ignore RF error if not going up */ rc = 0; if (rc) return rc; goto out; wil_set_oob_mode(wil, oob_mode); if (load_fw) { Loading @@ -1089,10 +1102,10 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) /* Loading f/w from the file */ rc = wil_request_firmware(wil, wil->wil_fw_name, true); if (rc) return rc; goto out; rc = wil_request_firmware(wil, WIL_BOARD_FILE_NAME, true); if (rc) return rc; goto out; wil_pre_fw_config(wil); wil_release_cpu(wil); Loading @@ -1104,6 +1117,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) reinit_completion(&wil->wmi_call); reinit_completion(&wil->halp.comp); clear_bit(wil_status_resetting, wil->status); if (load_fw) { wil_configure_interrupt_moderation(wil); wil_unmask_irq(wil); Loading Loading @@ -1140,6 +1155,10 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) } return rc; out: clear_bit(wil_status_resetting, wil->status); return rc; } void wil_fw_error_recovery(struct wil6210_priv *wil) Loading Loading @@ -1247,9 +1266,7 @@ int __wil_down(struct wil6210_priv *wil) wil_abort_scan(wil, false); mutex_unlock(&wil->p2p_wdev_mutex); wil_reset(wil, false); return 0; return wil_reset(wil, false); } int wil_down(struct wil6210_priv *wil) Loading
drivers/net/wireless/ath/wil6210/pm.c +17 −0 Original line number Diff line number Diff line Loading @@ -141,6 +141,13 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil) /* Prevent handling of new tx and wmi commands */ set_bit(wil_status_suspending, wil->status); if (test_bit(wil_status_collecting_dumps, wil->status)) { /* Device collects crash dump, cancel the suspend */ wil_dbg_pm(wil, "reject suspend while collecting crash dump\n"); clear_bit(wil_status_suspending, wil->status); wil->suspend_stats.rejected_by_host++; return -EBUSY; } wil_update_net_queues_bh(wil, NULL, true); if (!wil_is_tx_idle(wil)) { Loading Loading @@ -251,6 +258,15 @@ static int wil_suspend_radio_off(struct wil6210_priv *wil) wil_dbg_pm(wil, "suspend radio off\n"); set_bit(wil_status_suspending, wil->status); if (test_bit(wil_status_collecting_dumps, wil->status)) { /* Device collects crash dump, cancel the suspend */ wil_dbg_pm(wil, "reject suspend while collecting crash dump\n"); clear_bit(wil_status_suspending, wil->status); wil->suspend_stats.rejected_by_host++; return -EBUSY; } /* if netif up, hardware is alive, shut it down */ if (ndev->flags & IFF_UP) { rc = wil_down(wil); Loading @@ -275,6 +291,7 @@ static int wil_suspend_radio_off(struct wil6210_priv *wil) set_bit(wil_status_suspended, wil->status); out: clear_bit(wil_status_suspending, wil->status); wil_dbg_pm(wil, "suspend radio off: %d\n", rc); return rc; Loading
drivers/net/wireless/ath/wil6210/wil6210.h +1 −0 Original line number Diff line number Diff line Loading @@ -446,6 +446,7 @@ enum { /* for wil6210_priv.status */ wil_status_suspending, /* suspend in progress */ wil_status_suspended, /* suspend completed, device is suspended */ wil_status_resuming, /* resume in progress */ wil_status_collecting_dumps, /* crashdump collection in progress */ wil_status_last /* keep last */ }; Loading
drivers/net/wireless/ath/wil6210/wil_crash_dump.c +11 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,15 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size) return -EINVAL; } set_bit(wil_status_collecting_dumps, wil->status); if (test_bit(wil_status_suspending, wil->status) || test_bit(wil_status_suspended, wil->status) || test_bit(wil_status_resetting, wil->status)) { wil_err(wil, "cannot collect fw dump during suspend/reset\n"); clear_bit(wil_status_collecting_dumps, wil->status); return -EINVAL; } /* copy to crash dump area */ for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) { map = &fw_mapping[i]; Loading @@ -91,6 +100,8 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size) (const void __iomem * __force)data, len); } clear_bit(wil_status_collecting_dumps, wil->status); return 0; } Loading