Lines Matching +full:reset +full:- +full:synchronized

1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
4 * Copyright (C) 2016-2017 Intel Deutschland GmbH
5 * Copyright (C) 2019-2021, 2023-2025 Intel Corporation
12 #include "iwl-trans.h"
13 #include "iwl-drv.h"
14 #include "iwl-fh.h"
18 #include "pcie/iwl-context-info-v2.h"
39 if (strcmp(tmp->name, name)) in iwl_trans_get_restart_data()
53 strcpy(data->name, name); in iwl_trans_get_restart_data()
55 list_add_tail(&data->list, &restart_data_list); in iwl_trans_get_restart_data()
67 data->last_error = ktime_get_boottime_seconds(); in iwl_trans_inc_restart_count()
68 data->restart_count++; in iwl_trans_inc_restart_count()
78 list_del(&tmp->list); in iwl_trans_free_restart_list()
94 if (device_reprobe(reprobe->dev)) in iwl_trans_reprobe_wk()
95 dev_err(reprobe->dev, "reprobe failed!\n"); in iwl_trans_reprobe_wk()
96 put_device(reprobe->dev); in iwl_trans_reprobe_wk()
112 IWL_ERR(trans, "Module is being unloaded - abort\n"); in iwl_trans_schedule_reprobe()
121 reprobe->dev = get_device(trans->dev); in iwl_trans_schedule_reprobe()
122 INIT_DELAYED_WORK(&reprobe->work, iwl_trans_reprobe_wk); in iwl_trans_schedule_reprobe()
123 schedule_delayed_work(&reprobe->work, msecs_to_jiffies(delay_ms)); in iwl_trans_schedule_reprobe()
156 /* used by TOP fatal error/TOP reset */ in iwl_trans_determine_restart_mode()
157 if (trans->restart.mode.type == IWL_ERR_TYPE_TOP_RESET_FAILED) in iwl_trans_determine_restart_mode()
160 if (trans->request_top_reset) { in iwl_trans_determine_restart_mode()
161 trans->request_top_reset = 0; in iwl_trans_determine_restart_mode()
162 if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_SC) in iwl_trans_determine_restart_mode()
167 if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_SC) { in iwl_trans_determine_restart_mode()
175 if (trans->restart.during_reset) in iwl_trans_determine_restart_mode()
178 data = iwl_trans_get_restart_data(trans->dev); in iwl_trans_determine_restart_mode()
182 if (!data->backoff && in iwl_trans_determine_restart_mode()
183 ktime_get_boottime_seconds() - data->last_error >= in iwl_trans_determine_restart_mode()
185 data->restart_count = 0; in iwl_trans_determine_restart_mode()
187 index = data->restart_count; in iwl_trans_determine_restart_mode()
189 index = escalation_list_size - 1; in iwl_trans_determine_restart_mode()
190 if (!data->backoff) { in iwl_trans_determine_restart_mode()
191 data->backoff = true; in iwl_trans_determine_restart_mode()
194 data->backoff = false; in iwl_trans_determine_restart_mode()
210 if (trans->restart.mode.type == IWL_ERR_TYPE_TOP_RESET_BY_BT) { in iwl_trans_restart_wk()
215 if (!trans->op_mode) in iwl_trans_restart_wk()
218 /* might have been scheduled before marked as dead, re-check */ in iwl_trans_restart_wk()
219 if (test_bit(STATUS_TRANS_DEAD, &trans->status)) in iwl_trans_restart_wk()
222 iwl_op_mode_dump_error(trans->op_mode, &trans->restart.mode); in iwl_trans_restart_wk()
226 * reset, then we'll have done the dump already (synchronized by the in iwl_trans_restart_wk()
228 * managed that via trans->restart.mode. in iwl_trans_restart_wk()
232 if (!test_and_clear_bit(STATUS_RESET_PENDING, &trans->status)) in iwl_trans_restart_wk()
240 IWL_ERR(trans, "Too many device errors - delay next reset\n"); in iwl_trans_restart_wk()
241 queue_delayed_work(system_unbound_wq, &trans->restart.wk, in iwl_trans_restart_wk()
246 iwl_trans_inc_restart_count(trans->dev); in iwl_trans_restart_wk()
250 trans->do_top_reset = 1; in iwl_trans_restart_wk()
251 IWL_ERR(trans, "Device error - TOP reset\n"); in iwl_trans_restart_wk()
255 IWL_ERR(trans, "Device error - SW reset\n"); in iwl_trans_restart_wk()
256 iwl_trans_opmode_sw_reset(trans, trans->restart.mode.type); in iwl_trans_restart_wk()
259 IWL_ERR(trans, "Device error - reprobe!\n"); in iwl_trans_restart_wk()
284 trans->mac_cfg = mac_cfg; in iwl_trans_alloc()
287 lockdep_init_map(&trans->sync_cmd_lockdep_map, "sync_cmd_lockdep_map", in iwl_trans_alloc()
291 trans->dev = dev; in iwl_trans_alloc()
293 INIT_DELAYED_WORK(&trans->restart.wk, iwl_trans_restart_wk); in iwl_trans_alloc()
295 snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name), in iwl_trans_alloc()
296 "iwl_cmd_pool:%s", dev_name(trans->dev)); in iwl_trans_alloc()
297 trans->dev_cmd_pool = in iwl_trans_alloc()
298 kmem_cache_create(trans->dev_cmd_pool_name, in iwl_trans_alloc()
301 if (!trans->dev_cmd_pool) in iwl_trans_alloc()
309 cancel_delayed_work_sync(&trans->restart.wk); in iwl_trans_free()
310 kmem_cache_destroy(trans->dev_cmd_pool); in iwl_trans_free()
317 if (unlikely(!(cmd->flags & CMD_SEND_IN_RFKILL) && in iwl_trans_send_cmd()
318 test_bit(STATUS_RFKILL_OPMODE, &trans->status))) in iwl_trans_send_cmd()
319 return -ERFKILL; in iwl_trans_send_cmd()
321 if (unlikely(test_bit(STATUS_SUSPENDED, &trans->status))) in iwl_trans_send_cmd()
322 return -EHOSTDOWN; in iwl_trans_send_cmd()
324 if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status))) in iwl_trans_send_cmd()
325 return -EIO; in iwl_trans_send_cmd()
327 if (WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, in iwl_trans_send_cmd()
328 "bad state = %d\n", trans->state)) in iwl_trans_send_cmd()
329 return -EIO; in iwl_trans_send_cmd()
331 if (!(cmd->flags & CMD_ASYNC)) in iwl_trans_send_cmd()
332 lock_map_acquire_read(&trans->sync_cmd_lockdep_map); in iwl_trans_send_cmd()
334 if (trans->conf.wide_cmd_header && !iwl_cmd_groupid(cmd->id)) { in iwl_trans_send_cmd()
335 if (cmd->id != REPLY_ERROR) in iwl_trans_send_cmd()
336 cmd->id = DEF_ID(cmd->id); in iwl_trans_send_cmd()
341 if (!(cmd->flags & CMD_ASYNC)) in iwl_trans_send_cmd()
342 lock_map_release(&trans->sync_cmd_lockdep_map); in iwl_trans_send_cmd()
344 if (WARN_ON((cmd->flags & CMD_WANT_SKB) && !ret && !cmd->resp_pkt)) in iwl_trans_send_cmd()
345 return -EIO; in iwl_trans_send_cmd()
363 u8 cmd2 = name->cmd_id; in iwl_hcmd_names_cmp()
365 return (*cmd1 - cmd2); in iwl_hcmd_names_cmp()
378 if (!trans->conf.command_groups || in iwl_get_cmd_string()
379 grp >= trans->conf.command_groups_size || in iwl_get_cmd_string()
380 !trans->conf.command_groups[grp].arr) in iwl_get_cmd_string()
383 arr = &trans->conf.command_groups[grp]; in iwl_get_cmd_string()
384 ret = bsearch(&cmd, arr->arr, arr->size, size, iwl_hcmd_names_cmp); in iwl_get_cmd_string()
387 return ret->cmd_name; in iwl_get_cmd_string()
394 trans->op_mode = op_mode; in iwl_trans_op_mode_enter()
396 if (WARN_ON(trans->conf.n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS)) in iwl_trans_op_mode_enter()
397 trans->conf.n_no_reclaim_cmds = in iwl_trans_op_mode_enter()
398 ARRAY_SIZE(trans->conf.no_reclaim_cmds); in iwl_trans_op_mode_enter()
400 WARN_ON_ONCE(!trans->conf.rx_mpdu_cmd); in iwl_trans_op_mode_enter()
410 clear_bit(STATUS_TRANS_RESET_IN_PROGRESS, &trans->status); in iwl_trans_start_hw()
412 clear_bit(STATUS_SUSPENDED, &trans->status); in iwl_trans_start_hw()
422 if (trans->mac_cfg->gen2) in iwl_trans_op_mode_leave()
427 cancel_delayed_work_sync(&trans->restart.wk); in iwl_trans_op_mode_leave()
429 trans->op_mode = NULL; in iwl_trans_op_mode_leave()
430 memset(&trans->conf, 0, sizeof(trans->conf)); in iwl_trans_op_mode_leave()
432 trans->state = IWL_TRANS_NO_FW; in iwl_trans_op_mode_leave()
481 ret = -EBUSY; in iwl_trans_write_mem()
490 set_bit(STATUS_TPOWER_PMI, &trans->status); in iwl_trans_set_pmi()
492 clear_bit(STATUS_TPOWER_PMI, &trans->status); in iwl_trans_set_pmi()
510 int iwl_trans_d3_suspend(struct iwl_trans *trans, bool test, bool reset) in iwl_trans_d3_suspend() argument
516 err = iwl_trans_pcie_d3_suspend(trans, test, reset); in iwl_trans_d3_suspend()
519 set_bit(STATUS_SUSPENDED, &trans->status); in iwl_trans_d3_suspend()
526 bool test, bool reset) in iwl_trans_d3_resume() argument
532 err = iwl_trans_pcie_d3_resume(trans, status, test, reset); in iwl_trans_d3_resume()
534 clear_bit(STATUS_SUSPENDED, &trans->status); in iwl_trans_d3_resume()
586 trans->state = IWL_TRANS_FW_ALIVE; in iwl_trans_fw_alive()
588 if (trans->mac_cfg->gen2) in iwl_trans_fw_alive()
605 return -EINVAL; in iwl_trans_start_fw()
607 clear_bit(STATUS_FW_ERROR, &trans->status); in iwl_trans_start_fw()
609 if (trans->mac_cfg->gen2) in iwl_trans_start_fw()
617 trans->state = IWL_TRANS_FW_STARTED; in iwl_trans_start_fw()
630 * When the opmode stops the device while a reset is pending, the in iwl_trans_stop_device()
638 * The trans->restart.mode is a handshake with the opmode, we set in iwl_trans_stop_device()
645 if (test_and_clear_bit(STATUS_RESET_PENDING, &trans->status)) { in iwl_trans_stop_device()
648 mode = trans->restart.mode; in iwl_trans_stop_device()
650 trans->restart.mode.context = IWL_ERR_CONTEXT_ABORT; in iwl_trans_stop_device()
652 iwl_op_mode_dump_error(trans->op_mode, &mode); in iwl_trans_stop_device()
655 if (trans->mac_cfg->gen2) in iwl_trans_stop_device()
660 trans->state = IWL_TRANS_NO_FW; in iwl_trans_stop_device()
667 if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status))) in iwl_trans_tx()
668 return -EIO; in iwl_trans_tx()
670 if (WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, in iwl_trans_tx()
671 "bad state = %d\n", trans->state)) in iwl_trans_tx()
672 return -EIO; in iwl_trans_tx()
674 if (trans->mac_cfg->gen2) in iwl_trans_tx()
684 if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status))) in iwl_trans_reclaim()
687 if (WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, in iwl_trans_reclaim()
688 "bad state = %d\n", trans->state)) in iwl_trans_reclaim()
708 if (WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, in iwl_trans_txq_enable_cfg()
709 "bad state = %d\n", trans->state)) in iwl_trans_txq_enable_cfg()
719 if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status))) in iwl_trans_wait_txq_empty()
720 return -EIO; in iwl_trans_wait_txq_empty()
722 if (WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, in iwl_trans_wait_txq_empty()
723 "bad state = %d\n", trans->state)) in iwl_trans_wait_txq_empty()
724 return -EIO; in iwl_trans_wait_txq_empty()
732 if (WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, in iwl_trans_wait_tx_queues_empty()
733 "bad state = %d\n", trans->state)) in iwl_trans_wait_tx_queues_empty()
734 return -EIO; in iwl_trans_wait_tx_queues_empty()
743 if (WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, in iwl_trans_freeze_txq_timer()
744 "bad state = %d\n", trans->state)) in iwl_trans_freeze_txq_timer()
767 if (WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, in iwl_trans_set_q_ptrs()
768 "bad state = %d\n", trans->state)) in iwl_trans_set_q_ptrs()
780 if (WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, in iwl_trans_txq_alloc()
781 "bad state = %d\n", trans->state)) in iwl_trans_txq_alloc()
782 return -EIO; in iwl_trans_txq_alloc()