aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/ops.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ops.c63
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[] = {
415static const struct iwl_hcmd_names iwl_mvm_system_names[] = { 422static 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 */
423static const struct iwl_hcmd_names iwl_mvm_mac_conf_names[] = { 431static 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
604static bool iwl_mvm_d3_debug_enable(void *ctx)
605{
606 return IWL_MVM_D3_DEBUG;
607}
608
594static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = { 609static 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
601static struct iwl_op_mode * 617static 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
1125static 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
1108static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode, 1131static 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);