diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/ops.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 63 |
1 files changed, 56 insertions, 7 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 5e4f8b767d10..ba27dce4c2bb 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c | |||
@@ -82,7 +82,6 @@ | |||
82 | #include "fw/api/scan.h" | 82 | #include "fw/api/scan.h" |
83 | #include "time-event.h" | 83 | #include "time-event.h" |
84 | #include "fw-api.h" | 84 | #include "fw-api.h" |
85 | #include "fw/api/scan.h" | ||
86 | #include "fw/acpi.h" | 85 | #include "fw/acpi.h" |
87 | 86 | ||
88 | #define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux" | 87 | #define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux" |
@@ -301,6 +300,14 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { | |||
301 | RX_HANDLER_ASYNC_LOCKED), | 300 | RX_HANDLER_ASYNC_LOCKED), |
302 | RX_HANDLER(MFUART_LOAD_NOTIFICATION, iwl_mvm_rx_mfuart_notif, | 301 | RX_HANDLER(MFUART_LOAD_NOTIFICATION, iwl_mvm_rx_mfuart_notif, |
303 | RX_HANDLER_SYNC), | 302 | RX_HANDLER_SYNC), |
303 | RX_HANDLER_GRP(LOCATION_GROUP, TOF_RESPONDER_STATS, | ||
304 | iwl_mvm_ftm_responder_stats, RX_HANDLER_ASYNC_LOCKED), | ||
305 | |||
306 | RX_HANDLER_GRP(LOCATION_GROUP, TOF_RANGE_RESPONSE_NOTIF, | ||
307 | iwl_mvm_ftm_range_resp, RX_HANDLER_ASYNC_LOCKED), | ||
308 | RX_HANDLER_GRP(LOCATION_GROUP, TOF_LC_NOTIF, | ||
309 | iwl_mvm_ftm_lc_notif, RX_HANDLER_ASYNC_LOCKED), | ||
310 | |||
304 | RX_HANDLER_GRP(DEBUG_GROUP, MFU_ASSERT_DUMP_NTF, | 311 | RX_HANDLER_GRP(DEBUG_GROUP, MFU_ASSERT_DUMP_NTF, |
305 | iwl_mvm_mfu_assert_dump_notif, RX_HANDLER_SYNC), | 312 | iwl_mvm_mfu_assert_dump_notif, RX_HANDLER_SYNC), |
306 | RX_HANDLER_GRP(PROT_OFFLOAD_GROUP, STORED_BEACON_NTF, | 313 | RX_HANDLER_GRP(PROT_OFFLOAD_GROUP, STORED_BEACON_NTF, |
@@ -415,12 +422,14 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = { | |||
415 | static const struct iwl_hcmd_names iwl_mvm_system_names[] = { | 422 | static const struct iwl_hcmd_names iwl_mvm_system_names[] = { |
416 | HCMD_NAME(SHARED_MEM_CFG_CMD), | 423 | HCMD_NAME(SHARED_MEM_CFG_CMD), |
417 | HCMD_NAME(INIT_EXTENDED_CFG_CMD), | 424 | HCMD_NAME(INIT_EXTENDED_CFG_CMD), |
425 | HCMD_NAME(FW_ERROR_RECOVERY_CMD), | ||
418 | }; | 426 | }; |
419 | 427 | ||
420 | /* Please keep this array *SORTED* by hex value. | 428 | /* Please keep this array *SORTED* by hex value. |
421 | * Access is done through binary search | 429 | * Access is done through binary search |
422 | */ | 430 | */ |
423 | static const struct iwl_hcmd_names iwl_mvm_mac_conf_names[] = { | 431 | static const struct iwl_hcmd_names iwl_mvm_mac_conf_names[] = { |
432 | HCMD_NAME(CHANNEL_SWITCH_TIME_EVENT_CMD), | ||
424 | HCMD_NAME(CHANNEL_SWITCH_NOA_NOTIF), | 433 | HCMD_NAME(CHANNEL_SWITCH_NOA_NOTIF), |
425 | }; | 434 | }; |
426 | 435 | ||
@@ -445,6 +454,7 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = { | |||
445 | HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD), | 454 | HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD), |
446 | HCMD_NAME(STA_HE_CTXT_CMD), | 455 | HCMD_NAME(STA_HE_CTXT_CMD), |
447 | HCMD_NAME(RFH_QUEUE_CONFIG_CMD), | 456 | HCMD_NAME(RFH_QUEUE_CONFIG_CMD), |
457 | HCMD_NAME(TLC_MNG_CONFIG_CMD), | ||
448 | HCMD_NAME(CHEST_COLLECTOR_FILTER_CONFIG_CMD), | 458 | HCMD_NAME(CHEST_COLLECTOR_FILTER_CONFIG_CMD), |
449 | HCMD_NAME(STA_PM_NOTIF), | 459 | HCMD_NAME(STA_PM_NOTIF), |
450 | HCMD_NAME(MU_GROUP_MGMT_NOTIF), | 460 | HCMD_NAME(MU_GROUP_MGMT_NOTIF), |
@@ -591,11 +601,17 @@ static int iwl_mvm_fwrt_send_hcmd(void *ctx, struct iwl_host_cmd *host_cmd) | |||
591 | return ret; | 601 | return ret; |
592 | } | 602 | } |
593 | 603 | ||
604 | static bool iwl_mvm_d3_debug_enable(void *ctx) | ||
605 | { | ||
606 | return IWL_MVM_D3_DEBUG; | ||
607 | } | ||
608 | |||
594 | static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = { | 609 | static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = { |
595 | .dump_start = iwl_mvm_fwrt_dump_start, | 610 | .dump_start = iwl_mvm_fwrt_dump_start, |
596 | .dump_end = iwl_mvm_fwrt_dump_end, | 611 | .dump_end = iwl_mvm_fwrt_dump_end, |
597 | .fw_running = iwl_mvm_fwrt_fw_running, | 612 | .fw_running = iwl_mvm_fwrt_fw_running, |
598 | .send_hcmd = iwl_mvm_fwrt_send_hcmd, | 613 | .send_hcmd = iwl_mvm_fwrt_send_hcmd, |
614 | .d3_debug_enable = iwl_mvm_d3_debug_enable, | ||
599 | }; | 615 | }; |
600 | 616 | ||
601 | static struct iwl_op_mode * | 617 | static struct iwl_op_mode * |
@@ -690,6 +706,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
690 | INIT_LIST_HEAD(&mvm->aux_roc_te_list); | 706 | INIT_LIST_HEAD(&mvm->aux_roc_te_list); |
691 | INIT_LIST_HEAD(&mvm->async_handlers_list); | 707 | INIT_LIST_HEAD(&mvm->async_handlers_list); |
692 | spin_lock_init(&mvm->time_event_lock); | 708 | spin_lock_init(&mvm->time_event_lock); |
709 | INIT_LIST_HEAD(&mvm->ftm_initiator.loc_list); | ||
693 | 710 | ||
694 | INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk); | 711 | INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk); |
695 | INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk); | 712 | INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk); |
@@ -817,8 +834,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
817 | mutex_lock(&mvm->mutex); | 834 | mutex_lock(&mvm->mutex); |
818 | iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE); | 835 | iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE); |
819 | err = iwl_run_init_mvm_ucode(mvm, true); | 836 | err = iwl_run_init_mvm_ucode(mvm, true); |
820 | if (test_bit(IWL_FWRT_STATUS_WAIT_ALIVE, &mvm->fwrt.status)) | 837 | if (err) |
821 | iwl_fw_alive_error_dump(&mvm->fwrt); | 838 | iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_DRIVER); |
822 | if (!iwlmvm_mod_params.init_dbg || !err) | 839 | if (!iwlmvm_mod_params.init_dbg || !err) |
823 | iwl_mvm_stop_device(mvm); | 840 | iwl_mvm_stop_device(mvm); |
824 | iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE); | 841 | iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE); |
@@ -902,15 +919,15 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) | |||
902 | 919 | ||
903 | iwl_mvm_thermal_exit(mvm); | 920 | iwl_mvm_thermal_exit(mvm); |
904 | 921 | ||
905 | if (mvm->init_status & IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE) { | 922 | ieee80211_unregister_hw(mvm->hw); |
906 | ieee80211_unregister_hw(mvm->hw); | ||
907 | mvm->init_status &= ~IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE; | ||
908 | } | ||
909 | 923 | ||
910 | kfree(mvm->scan_cmd); | 924 | kfree(mvm->scan_cmd); |
911 | kfree(mvm->mcast_filter_cmd); | 925 | kfree(mvm->mcast_filter_cmd); |
912 | mvm->mcast_filter_cmd = NULL; | 926 | mvm->mcast_filter_cmd = NULL; |
913 | 927 | ||
928 | kfree(mvm->error_recovery_buf); | ||
929 | mvm->error_recovery_buf = NULL; | ||
930 | |||
914 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS) | 931 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS) |
915 | kfree(mvm->d3_resume_sram); | 932 | kfree(mvm->d3_resume_sram); |
916 | #endif | 933 | #endif |
@@ -1105,6 +1122,12 @@ static void iwl_mvm_async_cb(struct iwl_op_mode *op_mode, | |||
1105 | iwl_trans_block_txq_ptrs(mvm->trans, false); | 1122 | iwl_trans_block_txq_ptrs(mvm->trans, false); |
1106 | } | 1123 | } |
1107 | 1124 | ||
1125 | static int iwl_mvm_is_static_queue(struct iwl_mvm *mvm, int queue) | ||
1126 | { | ||
1127 | return queue == mvm->aux_queue || queue == mvm->probe_queue || | ||
1128 | queue == mvm->p2p_dev_queue || queue == mvm->snif_queue; | ||
1129 | } | ||
1130 | |||
1108 | static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode, | 1131 | static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode, |
1109 | int hw_queue, bool start) | 1132 | int hw_queue, bool start) |
1110 | { | 1133 | { |
@@ -1131,6 +1154,15 @@ static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode, | |||
1131 | goto out; | 1154 | goto out; |
1132 | mvmsta = iwl_mvm_sta_from_mac80211(sta); | 1155 | mvmsta = iwl_mvm_sta_from_mac80211(sta); |
1133 | 1156 | ||
1157 | if (iwl_mvm_is_static_queue(mvm, hw_queue)) { | ||
1158 | if (!start) | ||
1159 | ieee80211_stop_queues(mvm->hw); | ||
1160 | else if (mvmsta->sta_state != IEEE80211_STA_NOTEXIST) | ||
1161 | ieee80211_wake_queues(mvm->hw); | ||
1162 | |||
1163 | goto out; | ||
1164 | } | ||
1165 | |||
1134 | if (iwl_mvm_has_new_tx_api(mvm)) { | 1166 | if (iwl_mvm_has_new_tx_api(mvm)) { |
1135 | int tid = mvm->tvqm_info[hw_queue].txq_tid; | 1167 | int tid = mvm->tvqm_info[hw_queue].txq_tid; |
1136 | 1168 | ||
@@ -1285,12 +1317,29 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) | |||
1285 | reprobe->dev = mvm->trans->dev; | 1317 | reprobe->dev = mvm->trans->dev; |
1286 | INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); | 1318 | INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); |
1287 | schedule_work(&reprobe->work); | 1319 | schedule_work(&reprobe->work); |
1320 | } else if (test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, | ||
1321 | &mvm->status)) { | ||
1322 | IWL_ERR(mvm, "HW restart already requested, but not started\n"); | ||
1288 | } else if (mvm->fwrt.cur_fw_img == IWL_UCODE_REGULAR && | 1323 | } else if (mvm->fwrt.cur_fw_img == IWL_UCODE_REGULAR && |
1289 | mvm->hw_registered && | 1324 | mvm->hw_registered && |
1290 | !test_bit(STATUS_TRANS_DEAD, &mvm->trans->status)) { | 1325 | !test_bit(STATUS_TRANS_DEAD, &mvm->trans->status)) { |
1291 | /* don't let the transport/FW power down */ | 1326 | /* don't let the transport/FW power down */ |
1292 | iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); | 1327 | iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); |
1293 | 1328 | ||
1329 | if (mvm->fw->ucode_capa.error_log_size) { | ||
1330 | u32 src_size = mvm->fw->ucode_capa.error_log_size; | ||
1331 | u32 src_addr = mvm->fw->ucode_capa.error_log_addr; | ||
1332 | u8 *recover_buf = kzalloc(src_size, GFP_ATOMIC); | ||
1333 | |||
1334 | if (recover_buf) { | ||
1335 | mvm->error_recovery_buf = recover_buf; | ||
1336 | iwl_trans_read_mem_bytes(mvm->trans, | ||
1337 | src_addr, | ||
1338 | recover_buf, | ||
1339 | src_size); | ||
1340 | } | ||
1341 | } | ||
1342 | |||
1294 | if (fw_error && mvm->fw_restart > 0) | 1343 | if (fw_error && mvm->fw_restart > 0) |
1295 | mvm->fw_restart--; | 1344 | mvm->fw_restart--; |
1296 | set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status); | 1345 | set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status); |