aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm/ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/ops.c')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c481
1 files changed, 444 insertions, 37 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index a3d43de342d7..9545d7fdd4bf 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -61,6 +61,7 @@
61 * 61 *
62 *****************************************************************************/ 62 *****************************************************************************/
63#include <linux/module.h> 63#include <linux/module.h>
64#include <linux/vmalloc.h>
64#include <net/mac80211.h> 65#include <net/mac80211.h>
65 66
66#include "iwl-notif-wait.h" 67#include "iwl-notif-wait.h"
@@ -78,6 +79,7 @@
78#include "iwl-prph.h" 79#include "iwl-prph.h"
79#include "rs.h" 80#include "rs.h"
80#include "fw-api-scan.h" 81#include "fw-api-scan.h"
82#include "fw-error-dump.h"
81#include "time-event.h" 83#include "time-event.h"
82 84
83/* 85/*
@@ -185,9 +187,10 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
185 * (PCIe power is lost before PERST# is asserted), causing ME FW 187 * (PCIe power is lost before PERST# is asserted), causing ME FW
186 * to lose ownership and not being able to obtain it back. 188 * to lose ownership and not being able to obtain it back.
187 */ 189 */
188 iwl_set_bits_mask_prph(mvm->trans, APMG_PS_CTRL_REG, 190 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000)
189 APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, 191 iwl_set_bits_mask_prph(mvm->trans, APMG_PS_CTRL_REG,
190 ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); 192 APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
193 ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
191} 194}
192 195
193struct iwl_rx_handlers { 196struct iwl_rx_handlers {
@@ -219,13 +222,17 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
219 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true), 222 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
220 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false), 223 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false),
221 RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics, true), 224 RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics, true),
225 RX_HANDLER(ANTENNA_COUPLING_NOTIFICATION,
226 iwl_mvm_rx_ant_coupling_notif, true),
222 227
223 RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false), 228 RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false),
224 229
230 RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, false),
231
225 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), 232 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
226 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), 233 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true),
227 RX_HANDLER(SCAN_OFFLOAD_COMPLETE, 234 RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
228 iwl_mvm_rx_scan_offload_complete_notif, false), 235 iwl_mvm_rx_scan_offload_complete_notif, true),
229 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_sched_scan_results, 236 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_sched_scan_results,
230 false), 237 false),
231 238
@@ -242,7 +249,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
242#undef RX_HANDLER 249#undef RX_HANDLER
243#define CMD(x) [x] = #x 250#define CMD(x) [x] = #x
244 251
245static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { 252static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
246 CMD(MVM_ALIVE), 253 CMD(MVM_ALIVE),
247 CMD(REPLY_ERROR), 254 CMD(REPLY_ERROR),
248 CMD(INIT_COMPLETE_NOTIF), 255 CMD(INIT_COMPLETE_NOTIF),
@@ -284,9 +291,11 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
284 CMD(BEACON_NOTIFICATION), 291 CMD(BEACON_NOTIFICATION),
285 CMD(BEACON_TEMPLATE_CMD), 292 CMD(BEACON_TEMPLATE_CMD),
286 CMD(STATISTICS_NOTIFICATION), 293 CMD(STATISTICS_NOTIFICATION),
294 CMD(EOSP_NOTIFICATION),
287 CMD(REDUCE_TX_POWER_CMD), 295 CMD(REDUCE_TX_POWER_CMD),
288 CMD(TX_ANT_CONFIGURATION_CMD), 296 CMD(TX_ANT_CONFIGURATION_CMD),
289 CMD(D3_CONFIG_CMD), 297 CMD(D3_CONFIG_CMD),
298 CMD(D0I3_END_CMD),
290 CMD(PROT_OFFLOAD_CONFIG_CMD), 299 CMD(PROT_OFFLOAD_CONFIG_CMD),
291 CMD(OFFLOADS_QUERY_CMD), 300 CMD(OFFLOADS_QUERY_CMD),
292 CMD(REMOTE_WAKE_CONFIG_CMD), 301 CMD(REMOTE_WAKE_CONFIG_CMD),
@@ -309,17 +318,37 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
309 CMD(BT_PROFILE_NOTIFICATION), 318 CMD(BT_PROFILE_NOTIFICATION),
310 CMD(BT_CONFIG), 319 CMD(BT_CONFIG),
311 CMD(MCAST_FILTER_CMD), 320 CMD(MCAST_FILTER_CMD),
321 CMD(BCAST_FILTER_CMD),
312 CMD(REPLY_SF_CFG_CMD), 322 CMD(REPLY_SF_CFG_CMD),
313 CMD(REPLY_BEACON_FILTERING_CMD), 323 CMD(REPLY_BEACON_FILTERING_CMD),
314 CMD(REPLY_THERMAL_MNG_BACKOFF), 324 CMD(REPLY_THERMAL_MNG_BACKOFF),
315 CMD(MAC_PM_POWER_TABLE), 325 CMD(MAC_PM_POWER_TABLE),
316 CMD(BT_COEX_CI), 326 CMD(BT_COEX_CI),
317 CMD(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION), 327 CMD(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION),
328 CMD(ANTENNA_COUPLING_NOTIFICATION),
318}; 329};
319#undef CMD 330#undef CMD
320 331
321/* this forward declaration can avoid to export the function */ 332/* this forward declaration can avoid to export the function */
322static void iwl_mvm_async_handlers_wk(struct work_struct *wk); 333static void iwl_mvm_async_handlers_wk(struct work_struct *wk);
334static void iwl_mvm_d0i3_exit_work(struct work_struct *wk);
335
336static u32 calc_min_backoff(struct iwl_trans *trans, const struct iwl_cfg *cfg)
337{
338 const struct iwl_pwr_tx_backoff *pwr_tx_backoff = cfg->pwr_tx_backoffs;
339
340 if (!pwr_tx_backoff)
341 return 0;
342
343 while (pwr_tx_backoff->pwr) {
344 if (trans->dflt_pwr_limit >= pwr_tx_backoff->pwr)
345 return pwr_tx_backoff->backoff;
346
347 pwr_tx_backoff++;
348 }
349
350 return 0;
351}
323 352
324static struct iwl_op_mode * 353static struct iwl_op_mode *
325iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, 354iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
@@ -333,6 +362,14 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
333 TX_CMD, 362 TX_CMD,
334 }; 363 };
335 int err, scan_size; 364 int err, scan_size;
365 u32 min_backoff;
366
367 /*
368 * We use IWL_MVM_STATION_COUNT to check the validity of the station
369 * index all over the driver - check that its value corresponds to the
370 * array size.
371 */
372 BUILD_BUG_ON(ARRAY_SIZE(mvm->fw_id_to_mac_id) != IWL_MVM_STATION_COUNT);
336 373
337 /******************************** 374 /********************************
338 * 1. Allocating and configuring HW data 375 * 1. Allocating and configuring HW data
@@ -373,6 +410,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
373 INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk); 410 INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk);
374 INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk); 411 INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk);
375 INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk); 412 INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk);
413 INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work);
414
415 spin_lock_init(&mvm->d0i3_tx_lock);
416 skb_queue_head_init(&mvm->d0i3_tx);
417 init_waitqueue_head(&mvm->d0i3_exit_waitq);
376 418
377 SET_IEEE80211_DEV(mvm->hw, mvm->trans->dev); 419 SET_IEEE80211_DEV(mvm->hw, mvm->trans->dev);
378 420
@@ -421,7 +463,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
421 IWL_INFO(mvm, "Detected %s, REV=0x%X\n", 463 IWL_INFO(mvm, "Detected %s, REV=0x%X\n",
422 mvm->cfg->name, mvm->trans->hw_rev); 464 mvm->cfg->name, mvm->trans->hw_rev);
423 465
424 iwl_mvm_tt_initialize(mvm); 466 min_backoff = calc_min_backoff(trans, cfg);
467 iwl_mvm_tt_initialize(mvm, min_backoff);
425 468
426 /* 469 /*
427 * If the NVM exists in an external file, 470 * If the NVM exists in an external file,
@@ -462,13 +505,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
462 if (err) 505 if (err)
463 goto out_unregister; 506 goto out_unregister;
464 507
465 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)
466 mvm->pm_ops = &pm_mac_ops;
467 else
468 mvm->pm_ops = &pm_legacy_ops;
469
470 memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx)); 508 memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx));
471 509
510 /* rpm starts with a taken ref. only set the appropriate bit here. */
511 set_bit(IWL_MVM_REF_UCODE_DOWN, mvm->ref_bitmap);
512
472 return op_mode; 513 return op_mode;
473 514
474 out_unregister: 515 out_unregister:
@@ -495,6 +536,8 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
495 ieee80211_unregister_hw(mvm->hw); 536 ieee80211_unregister_hw(mvm->hw);
496 537
497 kfree(mvm->scan_cmd); 538 kfree(mvm->scan_cmd);
539 vfree(mvm->fw_error_dump);
540 kfree(mvm->fw_error_sram);
498 kfree(mvm->mcast_filter_cmd); 541 kfree(mvm->mcast_filter_cmd);
499 mvm->mcast_filter_cmd = NULL; 542 mvm->mcast_filter_cmd = NULL;
500 543
@@ -508,7 +551,7 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
508 mvm->phy_db = NULL; 551 mvm->phy_db = NULL;
509 552
510 iwl_free_nvm_data(mvm->nvm_data); 553 iwl_free_nvm_data(mvm->nvm_data);
511 for (i = 0; i < NVM_NUM_OF_SECTIONS; i++) 554 for (i = 0; i < NVM_MAX_NUM_SECTIONS; i++)
512 kfree(mvm->nvm_sections[i].data); 555 kfree(mvm->nvm_sections[i].data);
513 556
514 ieee80211_free_hw(mvm->hw); 557 ieee80211_free_hw(mvm->hw);
@@ -658,7 +701,7 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
658 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm)); 701 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
659} 702}
660 703
661static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) 704static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
662{ 705{
663 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 706 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
664 707
@@ -667,9 +710,9 @@ static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
667 else 710 else
668 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status); 711 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
669 712
670 if (state && mvm->cur_ucode != IWL_UCODE_INIT)
671 iwl_trans_stop_device(mvm->trans);
672 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm)); 713 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
714
715 return state && mvm->cur_ucode != IWL_UCODE_INIT;
673} 716}
674 717
675static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) 718static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
@@ -703,6 +746,29 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
703 iwl_abort_notification_waits(&mvm->notif_wait); 746 iwl_abort_notification_waits(&mvm->notif_wait);
704 747
705 /* 748 /*
749 * This is a bit racy, but worst case we tell mac80211 about
750 * a stopped/aborted scan when that was already done which
751 * is not a problem. It is necessary to abort any os scan
752 * here because mac80211 requires having the scan cleared
753 * before restarting.
754 * We'll reset the scan_status to NONE in restart cleanup in
755 * the next start() call from mac80211. If restart isn't called
756 * (no fw restart) scan status will stay busy.
757 */
758 switch (mvm->scan_status) {
759 case IWL_MVM_SCAN_NONE:
760 break;
761 case IWL_MVM_SCAN_OS:
762 ieee80211_scan_completed(mvm->hw, true);
763 break;
764 case IWL_MVM_SCAN_SCHED:
765 /* Sched scan will be restarted by mac80211 in restart_hw. */
766 if (!mvm->restart_fw)
767 ieee80211_sched_scan_stopped(mvm->hw);
768 break;
769 }
770
771 /*
706 * If we're restarting already, don't cycle restarts. 772 * If we're restarting already, don't cycle restarts.
707 * If INIT fw asserted, it will likely fail again. 773 * If INIT fw asserted, it will likely fail again.
708 * If WoWLAN fw asserted, don't restart either, mac80211 774 * If WoWLAN fw asserted, don't restart either, mac80211
@@ -733,25 +799,8 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
733 INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); 799 INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk);
734 schedule_work(&reprobe->work); 800 schedule_work(&reprobe->work);
735 } else if (mvm->cur_ucode == IWL_UCODE_REGULAR && mvm->restart_fw) { 801 } else if (mvm->cur_ucode == IWL_UCODE_REGULAR && mvm->restart_fw) {
736 /* 802 /* don't let the transport/FW power down */
737 * This is a bit racy, but worst case we tell mac80211 about 803 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
738 * a stopped/aborted (sched) scan when that was already done
739 * which is not a problem. It is necessary to abort any scan
740 * here because mac80211 requires having the scan cleared
741 * before restarting.
742 * We'll reset the scan_status to NONE in restart cleanup in
743 * the next start() call from mac80211.
744 */
745 switch (mvm->scan_status) {
746 case IWL_MVM_SCAN_NONE:
747 break;
748 case IWL_MVM_SCAN_OS:
749 ieee80211_scan_completed(mvm->hw, true);
750 break;
751 case IWL_MVM_SCAN_SCHED:
752 ieee80211_sched_scan_stopped(mvm->hw);
753 break;
754 }
755 804
756 if (mvm->restart_fw > 0) 805 if (mvm->restart_fw > 0)
757 mvm->restart_fw--; 806 mvm->restart_fw--;
@@ -759,13 +808,52 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
759 } 808 }
760} 809}
761 810
811#ifdef CONFIG_IWLWIFI_DEBUGFS
812void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
813{
814 struct iwl_fw_error_dump_file *dump_file;
815 struct iwl_fw_error_dump_data *dump_data;
816 u32 file_len;
817
818 lockdep_assert_held(&mvm->mutex);
819
820 if (mvm->fw_error_dump)
821 return;
822
823 file_len = mvm->fw_error_sram_len +
824 sizeof(*dump_file) +
825 sizeof(*dump_data);
826
827 dump_file = vmalloc(file_len);
828 if (!dump_file)
829 return;
830
831 mvm->fw_error_dump = dump_file;
832
833 dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
834 dump_file->file_len = cpu_to_le32(file_len);
835 dump_data = (void *)dump_file->data;
836 dump_data->type = IWL_FW_ERROR_DUMP_SRAM;
837 dump_data->len = cpu_to_le32(mvm->fw_error_sram_len);
838
839 /*
840 * No need for lock since at the stage the FW isn't loaded. So it
841 * can't assert - we are the only one who can possibly be accessing
842 * mvm->fw_error_sram right now.
843 */
844 memcpy(dump_data->data, mvm->fw_error_sram, mvm->fw_error_sram_len);
845}
846#endif
847
762static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) 848static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
763{ 849{
764 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 850 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
765 851
766 iwl_mvm_dump_nic_error_log(mvm); 852 iwl_mvm_dump_nic_error_log(mvm);
767 if (!mvm->restart_fw) 853
768 iwl_mvm_dump_sram(mvm); 854#ifdef CONFIG_IWLWIFI_DEBUGFS
855 iwl_mvm_fw_error_sram_dump(mvm);
856#endif
769 857
770 iwl_mvm_nic_restart(mvm); 858 iwl_mvm_nic_restart(mvm);
771} 859}
@@ -778,6 +866,323 @@ static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
778 iwl_mvm_nic_restart(mvm); 866 iwl_mvm_nic_restart(mvm);
779} 867}
780 868
869struct iwl_d0i3_iter_data {
870 struct iwl_mvm *mvm;
871 u8 ap_sta_id;
872 u8 vif_count;
873 u8 offloading_tid;
874 bool disable_offloading;
875};
876
877static bool iwl_mvm_disallow_offloading(struct iwl_mvm *mvm,
878 struct ieee80211_vif *vif,
879 struct iwl_d0i3_iter_data *iter_data)
880{
881 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
882 struct ieee80211_sta *ap_sta;
883 struct iwl_mvm_sta *mvmsta;
884 u32 available_tids = 0;
885 u8 tid;
886
887 if (WARN_ON(vif->type != NL80211_IFTYPE_STATION ||
888 mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT))
889 return false;
890
891 ap_sta = rcu_dereference(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id]);
892 if (IS_ERR_OR_NULL(ap_sta))
893 return false;
894
895 mvmsta = iwl_mvm_sta_from_mac80211(ap_sta);
896 spin_lock_bh(&mvmsta->lock);
897 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
898 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
899
900 /*
901 * in case of pending tx packets, don't use this tid
902 * for offloading in order to prevent reuse of the same
903 * qos seq counters.
904 */
905 if (iwl_mvm_tid_queued(tid_data))
906 continue;
907
908 if (tid_data->state != IWL_AGG_OFF)
909 continue;
910
911 available_tids |= BIT(tid);
912 }
913 spin_unlock_bh(&mvmsta->lock);
914
915 /*
916 * disallow protocol offloading if we have no available tid
917 * (with no pending frames and no active aggregation,
918 * as we don't handle "holes" properly - the scheduler needs the
919 * frame's seq number and TFD index to match)
920 */
921 if (!available_tids)
922 return true;
923
924 /* for simplicity, just use the first available tid */
925 iter_data->offloading_tid = ffs(available_tids) - 1;
926 return false;
927}
928
929static void iwl_mvm_enter_d0i3_iterator(void *_data, u8 *mac,
930 struct ieee80211_vif *vif)
931{
932 struct iwl_d0i3_iter_data *data = _data;
933 struct iwl_mvm *mvm = data->mvm;
934 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
935 u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE;
936
937 IWL_DEBUG_RPM(mvm, "entering D0i3 - vif %pM\n", vif->addr);
938 if (vif->type != NL80211_IFTYPE_STATION ||
939 !vif->bss_conf.assoc)
940 return;
941
942 /*
943 * in case of pending tx packets or active aggregations,
944 * avoid offloading features in order to prevent reuse of
945 * the same qos seq counters.
946 */
947 if (iwl_mvm_disallow_offloading(mvm, vif, data))
948 data->disable_offloading = true;
949
950 iwl_mvm_update_d0i3_power_mode(mvm, vif, true, flags);
951 iwl_mvm_send_proto_offload(mvm, vif, data->disable_offloading, flags);
952
953 /*
954 * on init/association, mvm already configures POWER_TABLE_CMD
955 * and REPLY_MCAST_FILTER_CMD, so currently don't
956 * reconfigure them (we might want to use different
957 * params later on, though).
958 */
959 data->ap_sta_id = mvmvif->ap_sta_id;
960 data->vif_count++;
961}
962
963static void iwl_mvm_set_wowlan_data(struct iwl_mvm *mvm,
964 struct iwl_wowlan_config_cmd_v3 *cmd,
965 struct iwl_d0i3_iter_data *iter_data)
966{
967 struct ieee80211_sta *ap_sta;
968 struct iwl_mvm_sta *mvm_ap_sta;
969
970 if (iter_data->ap_sta_id == IWL_MVM_STATION_COUNT)
971 return;
972
973 rcu_read_lock();
974
975 ap_sta = rcu_dereference(mvm->fw_id_to_mac_id[iter_data->ap_sta_id]);
976 if (IS_ERR_OR_NULL(ap_sta))
977 goto out;
978
979 mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);
980 cmd->common.is_11n_connection = ap_sta->ht_cap.ht_supported;
981 cmd->offloading_tid = iter_data->offloading_tid;
982
983 /*
984 * The d0i3 uCode takes care of the nonqos counters,
985 * so configure only the qos seq ones.
986 */
987 iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, &cmd->common);
988out:
989 rcu_read_unlock();
990}
991static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
992{
993 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
994 u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE;
995 int ret;
996 struct iwl_d0i3_iter_data d0i3_iter_data = {
997 .mvm = mvm,
998 };
999 struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {
1000 .common = {
1001 .wakeup_filter =
1002 cpu_to_le32(IWL_WOWLAN_WAKEUP_RX_FRAME |
1003 IWL_WOWLAN_WAKEUP_BEACON_MISS |
1004 IWL_WOWLAN_WAKEUP_LINK_CHANGE |
1005 IWL_WOWLAN_WAKEUP_BCN_FILTERING),
1006 },
1007 };
1008 struct iwl_d3_manager_config d3_cfg_cmd = {
1009 .min_sleep_time = cpu_to_le32(1000),
1010 };
1011
1012 IWL_DEBUG_RPM(mvm, "MVM entering D0i3\n");
1013
1014 /* make sure we have no running tx while configuring the qos */
1015 set_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
1016 synchronize_net();
1017
1018 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
1019 IEEE80211_IFACE_ITER_NORMAL,
1020 iwl_mvm_enter_d0i3_iterator,
1021 &d0i3_iter_data);
1022 if (d0i3_iter_data.vif_count == 1) {
1023 mvm->d0i3_ap_sta_id = d0i3_iter_data.ap_sta_id;
1024 mvm->d0i3_offloading = !d0i3_iter_data.disable_offloading;
1025 } else {
1026 WARN_ON_ONCE(d0i3_iter_data.vif_count > 1);
1027 mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT;
1028 mvm->d0i3_offloading = false;
1029 }
1030
1031 iwl_mvm_set_wowlan_data(mvm, &wowlan_config_cmd, &d0i3_iter_data);
1032 ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, flags,
1033 sizeof(wowlan_config_cmd),
1034 &wowlan_config_cmd);
1035 if (ret)
1036 return ret;
1037
1038 return iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD,
1039 flags | CMD_MAKE_TRANS_IDLE,
1040 sizeof(d3_cfg_cmd), &d3_cfg_cmd);
1041}
1042
1043static void iwl_mvm_exit_d0i3_iterator(void *_data, u8 *mac,
1044 struct ieee80211_vif *vif)
1045{
1046 struct iwl_mvm *mvm = _data;
1047 u32 flags = CMD_ASYNC | CMD_HIGH_PRIO;
1048
1049 IWL_DEBUG_RPM(mvm, "exiting D0i3 - vif %pM\n", vif->addr);
1050 if (vif->type != NL80211_IFTYPE_STATION ||
1051 !vif->bss_conf.assoc)
1052 return;
1053
1054 iwl_mvm_update_d0i3_power_mode(mvm, vif, false, flags);
1055}
1056
1057static void iwl_mvm_d0i3_disconnect_iter(void *data, u8 *mac,
1058 struct ieee80211_vif *vif)
1059{
1060 struct iwl_mvm *mvm = data;
1061 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1062
1063 if (vif->type == NL80211_IFTYPE_STATION && vif->bss_conf.assoc &&
1064 mvm->d0i3_ap_sta_id == mvmvif->ap_sta_id)
1065 ieee80211_connection_loss(vif);
1066}
1067
1068void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq)
1069{
1070 struct ieee80211_sta *sta = NULL;
1071 struct iwl_mvm_sta *mvm_ap_sta;
1072 int i;
1073 bool wake_queues = false;
1074
1075 lockdep_assert_held(&mvm->mutex);
1076
1077 spin_lock_bh(&mvm->d0i3_tx_lock);
1078
1079 if (mvm->d0i3_ap_sta_id == IWL_MVM_STATION_COUNT)
1080 goto out;
1081
1082 IWL_DEBUG_RPM(mvm, "re-enqueue packets\n");
1083
1084 /* get the sta in order to update seq numbers and re-enqueue skbs */
1085 sta = rcu_dereference_protected(
1086 mvm->fw_id_to_mac_id[mvm->d0i3_ap_sta_id],
1087 lockdep_is_held(&mvm->mutex));
1088
1089 if (IS_ERR_OR_NULL(sta)) {
1090 sta = NULL;
1091 goto out;
1092 }
1093
1094 if (mvm->d0i3_offloading && qos_seq) {
1095 /* update qos seq numbers if offloading was enabled */
1096 mvm_ap_sta = (struct iwl_mvm_sta *)sta->drv_priv;
1097 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
1098 u16 seq = le16_to_cpu(qos_seq[i]);
1099 /* firmware stores last-used one, we store next one */
1100 seq += 0x10;
1101 mvm_ap_sta->tid_data[i].seq_number = seq;
1102 }
1103 }
1104out:
1105 /* re-enqueue (or drop) all packets */
1106 while (!skb_queue_empty(&mvm->d0i3_tx)) {
1107 struct sk_buff *skb = __skb_dequeue(&mvm->d0i3_tx);
1108
1109 if (!sta || iwl_mvm_tx_skb(mvm, skb, sta))
1110 ieee80211_free_txskb(mvm->hw, skb);
1111
1112 /* if the skb_queue is not empty, we need to wake queues */
1113 wake_queues = true;
1114 }
1115 clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
1116 wake_up(&mvm->d0i3_exit_waitq);
1117 mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT;
1118 if (wake_queues)
1119 ieee80211_wake_queues(mvm->hw);
1120
1121 spin_unlock_bh(&mvm->d0i3_tx_lock);
1122}
1123
1124static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
1125{
1126 struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, d0i3_exit_work);
1127 struct iwl_host_cmd get_status_cmd = {
1128 .id = WOWLAN_GET_STATUSES,
1129 .flags = CMD_SYNC | CMD_HIGH_PRIO | CMD_WANT_SKB,
1130 };
1131 struct iwl_wowlan_status_v6 *status;
1132 int ret;
1133 u32 disconnection_reasons, wakeup_reasons;
1134 __le16 *qos_seq = NULL;
1135
1136 mutex_lock(&mvm->mutex);
1137 ret = iwl_mvm_send_cmd(mvm, &get_status_cmd);
1138 if (ret)
1139 goto out;
1140
1141 if (!get_status_cmd.resp_pkt)
1142 goto out;
1143
1144 status = (void *)get_status_cmd.resp_pkt->data;
1145 wakeup_reasons = le32_to_cpu(status->wakeup_reasons);
1146 qos_seq = status->qos_seq_ctr;
1147
1148 IWL_DEBUG_RPM(mvm, "wakeup reasons: 0x%x\n", wakeup_reasons);
1149
1150 disconnection_reasons =
1151 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
1152 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH;
1153 if (wakeup_reasons & disconnection_reasons)
1154 ieee80211_iterate_active_interfaces(
1155 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1156 iwl_mvm_d0i3_disconnect_iter, mvm);
1157
1158 iwl_free_resp(&get_status_cmd);
1159out:
1160 iwl_mvm_d0i3_enable_tx(mvm, qos_seq);
1161 mutex_unlock(&mvm->mutex);
1162}
1163
1164static int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
1165{
1166 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
1167 u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE |
1168 CMD_WAKE_UP_TRANS;
1169 int ret;
1170
1171 IWL_DEBUG_RPM(mvm, "MVM exiting D0i3\n");
1172
1173 ret = iwl_mvm_send_cmd_pdu(mvm, D0I3_END_CMD, flags, 0, NULL);
1174 if (ret)
1175 goto out;
1176
1177 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
1178 IEEE80211_IFACE_ITER_NORMAL,
1179 iwl_mvm_exit_d0i3_iterator,
1180 mvm);
1181out:
1182 schedule_work(&mvm->d0i3_exit_work);
1183 return ret;
1184}
1185
781static const struct iwl_op_mode_ops iwl_mvm_ops = { 1186static const struct iwl_op_mode_ops iwl_mvm_ops = {
782 .start = iwl_op_mode_mvm_start, 1187 .start = iwl_op_mode_mvm_start,
783 .stop = iwl_op_mode_mvm_stop, 1188 .stop = iwl_op_mode_mvm_stop,
@@ -789,4 +1194,6 @@ static const struct iwl_op_mode_ops iwl_mvm_ops = {
789 .nic_error = iwl_mvm_nic_error, 1194 .nic_error = iwl_mvm_nic_error,
790 .cmd_queue_full = iwl_mvm_cmd_queue_full, 1195 .cmd_queue_full = iwl_mvm_cmd_queue_full,
791 .nic_config = iwl_mvm_nic_config, 1196 .nic_config = iwl_mvm_nic_config,
1197 .enter_d0i3 = iwl_mvm_enter_d0i3,
1198 .exit_d0i3 = iwl_mvm_exit_d0i3,
792}; 1199};