aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/binding.c20
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c21
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c57
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c546
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c689
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.h101
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h20
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h31
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h9
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h17
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h69
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c32
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/led.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c211
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c342
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h63
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c51
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c28
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c400
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power_legacy.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c2192
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h154
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c72
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sf.c291
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c50
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/testmode.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c27
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c21
41 files changed, 3331 insertions, 2274 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index 6d73817850ce..f98ec2b23898 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -1,10 +1,10 @@
1obj-$(CONFIG_IWLMVM) += iwlmvm.o 1obj-$(CONFIG_IWLMVM) += iwlmvm.o
2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o 2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o 3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o
4iwlmvm-y += scan.o time-event.o rs.o 4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o power_legacy.o bt-coex.o 5iwlmvm-y += power.o power_legacy.o bt-coex.o
6iwlmvm-y += led.o tt.o 6iwlmvm-y += led.o tt.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o 7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o
8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o 8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
9 9
10ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../ 10ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../
diff --git a/drivers/net/wireless/iwlwifi/mvm/binding.c b/drivers/net/wireless/iwlwifi/mvm/binding.c
index 93fd1457954b..a1376539d2dc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/binding.c
+++ b/drivers/net/wireless/iwlwifi/mvm/binding.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -183,15 +183,29 @@ int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
183 if (WARN_ON_ONCE(!mvmvif->phy_ctxt)) 183 if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
184 return -EINVAL; 184 return -EINVAL;
185 185
186 /*
187 * Update SF - Disable if needed. if this fails, SF might still be on
188 * while many macs are bound, which is forbidden - so fail the binding.
189 */
190 if (iwl_mvm_sf_update(mvm, vif, false))
191 return -EINVAL;
192
186 return iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, true); 193 return iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, true);
187} 194}
188 195
189int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 196int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
190{ 197{
191 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 198 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
199 int ret;
192 200
193 if (WARN_ON_ONCE(!mvmvif->phy_ctxt)) 201 if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
194 return -EINVAL; 202 return -EINVAL;
195 203
196 return iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, false); 204 ret = iwl_mvm_binding_update(mvm, vif, mvmvif->phy_ctxt, false);
205
206 if (!ret)
207 if (iwl_mvm_sf_update(mvm, vif, true))
208 IWL_ERR(mvm, "Failed to update SF state\n");
209
210 return ret;
197} 211}
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
index 75b72a956552..76cde6ce6551 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -294,9 +294,9 @@ static const __le64 iwl_ci_mask[][3] = {
294 cpu_to_le64(0x0) 294 cpu_to_le64(0x0)
295 }, 295 },
296 { 296 {
297 cpu_to_le64(0xFE00000000ULL), 297 cpu_to_le64(0xFFC0000000ULL),
298 cpu_to_le64(0x0ULL), 298 cpu_to_le64(0x0ULL),
299 cpu_to_le64(0x0) 299 cpu_to_le64(0x0ULL)
300 }, 300 },
301}; 301};
302 302
@@ -396,7 +396,8 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
396 BT_VALID_ANT_ISOLATION | 396 BT_VALID_ANT_ISOLATION |
397 BT_VALID_ANT_ISOLATION_THRS | 397 BT_VALID_ANT_ISOLATION_THRS |
398 BT_VALID_TXTX_DELTA_FREQ_THRS | 398 BT_VALID_TXTX_DELTA_FREQ_THRS |
399 BT_VALID_TXRX_MAX_FREQ_0); 399 BT_VALID_TXRX_MAX_FREQ_0 |
400 BT_VALID_SYNC_TO_SCO);
400 401
401 if (mvm->cfg->bt_shared_single_ant) 402 if (mvm->cfg->bt_shared_single_ant)
402 memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant, 403 memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant,
@@ -514,7 +515,7 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
514 if (IS_ERR_OR_NULL(sta)) 515 if (IS_ERR_OR_NULL(sta))
515 return 0; 516 return 0;
516 517
517 mvmsta = (void *)sta->drv_priv; 518 mvmsta = iwl_mvm_sta_from_mac80211(sta);
518 519
519 /* nothing to do */ 520 /* nothing to do */
520 if (mvmsta->bt_reduced_txpower == enable) 521 if (mvmsta->bt_reduced_txpower == enable)
@@ -846,7 +847,7 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
846 if (IS_ERR_OR_NULL(sta)) 847 if (IS_ERR_OR_NULL(sta))
847 return; 848 return;
848 849
849 mvmsta = (void *)sta->drv_priv; 850 mvmsta = iwl_mvm_sta_from_mac80211(sta);
850 851
851 data->num_bss_ifaces++; 852 data->num_bss_ifaces++;
852 853
@@ -917,11 +918,11 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
917u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm, 918u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm,
918 struct ieee80211_sta *sta) 919 struct ieee80211_sta *sta)
919{ 920{
920 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 921 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
921 enum iwl_bt_coex_lut_type lut_type; 922 enum iwl_bt_coex_lut_type lut_type;
922 923
923 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < 924 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
924 BT_LOW_TRAFFIC) 925 BT_HIGH_TRAFFIC)
925 return LINK_QUAL_AGG_TIME_LIMIT_DEF; 926 return LINK_QUAL_AGG_TIME_LIMIT_DEF;
926 927
927 lut_type = iwl_get_coex_type(mvm, mvmsta->vif); 928 lut_type = iwl_get_coex_type(mvm, mvmsta->vif);
@@ -936,7 +937,7 @@ u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm,
936bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm, 937bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
937 struct ieee80211_sta *sta) 938 struct ieee80211_sta *sta)
938{ 939{
939 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 940 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
940 941
941 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < 942 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
942 BT_HIGH_TRAFFIC) 943 BT_HIGH_TRAFFIC)
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index 4b6d670c3509..036857698565 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index b9b81e881dd0..f36a7ee0267f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -886,8 +886,7 @@ static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm *mvm,
886 if (err) 886 if (err)
887 return err; 887 return err;
888 888
889 size = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 889 size = iwl_rx_packet_payload_len(cmd.resp_pkt);
890 size -= sizeof(cmd.resp_pkt->hdr);
891 if (size < sizeof(__le16)) { 890 if (size < sizeof(__le16)) {
892 err = -EINVAL; 891 err = -EINVAL;
893 } else { 892 } else {
@@ -1211,15 +1210,10 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1211 if (ret) 1210 if (ret)
1212 goto out; 1211 goto out;
1213#ifdef CONFIG_IWLWIFI_DEBUGFS 1212#ifdef CONFIG_IWLWIFI_DEBUGFS
1214 len = le32_to_cpu(d3_cfg_cmd.resp_pkt->len_n_flags) & 1213 len = iwl_rx_packet_payload_len(d3_cfg_cmd.resp_pkt);
1215 FH_RSCSR_FRAME_SIZE_MSK; 1214 if (len >= sizeof(u32)) {
1216 if (len >= sizeof(u32) * 2) {
1217 mvm->d3_test_pme_ptr = 1215 mvm->d3_test_pme_ptr =
1218 le32_to_cpup((__le32 *)d3_cfg_cmd.resp_pkt->data); 1216 le32_to_cpup((__le32 *)d3_cfg_cmd.resp_pkt->data);
1219 } else if (test) {
1220 /* in test mode we require the pointer */
1221 ret = -EIO;
1222 goto out;
1223 } 1217 }
1224#endif 1218#endif
1225 iwl_free_resp(&d3_cfg_cmd); 1219 iwl_free_resp(&d3_cfg_cmd);
@@ -1231,10 +1225,11 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1231 mvm->aux_sta.sta_id = old_aux_sta_id; 1225 mvm->aux_sta.sta_id = old_aux_sta_id;
1232 mvm_ap_sta->sta_id = old_ap_sta_id; 1226 mvm_ap_sta->sta_id = old_ap_sta_id;
1233 mvmvif->ap_sta_id = old_ap_sta_id; 1227 mvmvif->ap_sta_id = old_ap_sta_id;
1234 out_noreset: 1228
1235 kfree(key_data.rsc_tsc);
1236 if (ret < 0) 1229 if (ret < 0)
1237 ieee80211_restart_hw(mvm->hw); 1230 ieee80211_restart_hw(mvm->hw);
1231 out_noreset:
1232 kfree(key_data.rsc_tsc);
1238 1233
1239 mutex_unlock(&mvm->mutex); 1234 mutex_unlock(&mvm->mutex);
1240 1235
@@ -1537,10 +1532,16 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
1537 struct iwl_mvm_d3_gtk_iter_data gtkdata = { 1532 struct iwl_mvm_d3_gtk_iter_data gtkdata = {
1538 .status = status, 1533 .status = status,
1539 }; 1534 };
1535 u32 disconnection_reasons =
1536 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
1537 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH;
1540 1538
1541 if (!status || !vif->bss_conf.bssid) 1539 if (!status || !vif->bss_conf.bssid)
1542 return false; 1540 return false;
1543 1541
1542 if (le32_to_cpu(status->wakeup_reasons) & disconnection_reasons)
1543 return false;
1544
1544 /* find last GTK that we used initially, if any */ 1545 /* find last GTK that we used initially, if any */
1545 gtkdata.find_phase = true; 1546 gtkdata.find_phase = true;
1546 ieee80211_iter_keys(mvm->hw, vif, 1547 ieee80211_iter_keys(mvm->hw, vif,
@@ -1665,8 +1666,8 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1665 else 1666 else
1666 status_size = sizeof(struct iwl_wowlan_status_v4); 1667 status_size = sizeof(struct iwl_wowlan_status_v4);
1667 1668
1668 len = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 1669 len = iwl_rx_packet_payload_len(cmd.resp_pkt);
1669 if (len - sizeof(struct iwl_cmd_header) < status_size) { 1670 if (len < status_size) {
1670 IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); 1671 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
1671 goto out_free_resp; 1672 goto out_free_resp;
1672 } 1673 }
@@ -1701,8 +1702,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1701 status.wake_packet = status_v4->wake_packet; 1702 status.wake_packet = status_v4->wake_packet;
1702 } 1703 }
1703 1704
1704 if (len - sizeof(struct iwl_cmd_header) != 1705 if (len != status_size + ALIGN(status.wake_packet_bufsize, 4)) {
1705 status_size + ALIGN(status.wake_packet_bufsize, 4)) {
1706 IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); 1706 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
1707 goto out_free_resp; 1707 goto out_free_resp;
1708 } 1708 }
@@ -1805,6 +1805,10 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
1805 iwl_mvm_read_d3_sram(mvm); 1805 iwl_mvm_read_d3_sram(mvm);
1806 1806
1807 keep = iwl_mvm_query_wakeup_reasons(mvm, vif); 1807 keep = iwl_mvm_query_wakeup_reasons(mvm, vif);
1808#ifdef CONFIG_IWLWIFI_DEBUGFS
1809 if (keep)
1810 mvm->keep_vif = vif;
1811#endif
1808 /* has unlocked the mutex, so skip that */ 1812 /* has unlocked the mutex, so skip that */
1809 goto out; 1813 goto out;
1810 1814
@@ -1861,6 +1865,7 @@ static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file)
1861 return err; 1865 return err;
1862 } 1866 }
1863 mvm->d3_test_active = true; 1867 mvm->d3_test_active = true;
1868 mvm->keep_vif = NULL;
1864 return 0; 1869 return 0;
1865} 1870}
1866 1871
@@ -1871,10 +1876,14 @@ static ssize_t iwl_mvm_d3_test_read(struct file *file, char __user *user_buf,
1871 u32 pme_asserted; 1876 u32 pme_asserted;
1872 1877
1873 while (true) { 1878 while (true) {
1874 pme_asserted = iwl_trans_read_mem32(mvm->trans, 1879 /* read pme_ptr if available */
1875 mvm->d3_test_pme_ptr); 1880 if (mvm->d3_test_pme_ptr) {
1876 if (pme_asserted) 1881 pme_asserted = iwl_trans_read_mem32(mvm->trans,
1877 break; 1882 mvm->d3_test_pme_ptr);
1883 if (pme_asserted)
1884 break;
1885 }
1886
1878 if (msleep_interruptible(100)) 1887 if (msleep_interruptible(100))
1879 break; 1888 break;
1880 } 1889 }
@@ -1885,6 +1894,10 @@ static ssize_t iwl_mvm_d3_test_read(struct file *file, char __user *user_buf,
1885static void iwl_mvm_d3_test_disconn_work_iter(void *_data, u8 *mac, 1894static void iwl_mvm_d3_test_disconn_work_iter(void *_data, u8 *mac,
1886 struct ieee80211_vif *vif) 1895 struct ieee80211_vif *vif)
1887{ 1896{
1897 /* skip the one we keep connection on */
1898 if (_data == vif)
1899 return;
1900
1888 if (vif->type == NL80211_IFTYPE_STATION) 1901 if (vif->type == NL80211_IFTYPE_STATION)
1889 ieee80211_connection_loss(vif); 1902 ieee80211_connection_loss(vif);
1890} 1903}
@@ -1911,7 +1924,7 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
1911 1924
1912 ieee80211_iterate_active_interfaces_atomic( 1925 ieee80211_iterate_active_interfaces_atomic(
1913 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 1926 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1914 iwl_mvm_d3_test_disconn_work_iter, NULL); 1927 iwl_mvm_d3_test_disconn_work_iter, mvm->keep_vif);
1915 1928
1916 ieee80211_wake_queues(mvm->hw); 1929 ieee80211_wake_queues(mvm->hw);
1917 1930
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
new file mode 100644
index 000000000000..0e29cd83a06a
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
@@ -0,0 +1,546 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#include "mvm.h"
64#include "debugfs.h"
65
66static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
67 struct ieee80211_vif *vif,
68 enum iwl_dbgfs_pm_mask param, int val)
69{
70 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
71 struct iwl_dbgfs_pm *dbgfs_pm = &mvmvif->dbgfs_pm;
72
73 dbgfs_pm->mask |= param;
74
75 switch (param) {
76 case MVM_DEBUGFS_PM_KEEP_ALIVE: {
77 struct ieee80211_hw *hw = mvm->hw;
78 int dtimper = hw->conf.ps_dtim_period ?: 1;
79 int dtimper_msec = dtimper * vif->bss_conf.beacon_int;
80
81 IWL_DEBUG_POWER(mvm, "debugfs: set keep_alive= %d sec\n", val);
82 if (val * MSEC_PER_SEC < 3 * dtimper_msec)
83 IWL_WARN(mvm,
84 "debugfs: keep alive period (%ld msec) is less than minimum required (%d msec)\n",
85 val * MSEC_PER_SEC, 3 * dtimper_msec);
86 dbgfs_pm->keep_alive_seconds = val;
87 break;
88 }
89 case MVM_DEBUGFS_PM_SKIP_OVER_DTIM:
90 IWL_DEBUG_POWER(mvm, "skip_over_dtim %s\n",
91 val ? "enabled" : "disabled");
92 dbgfs_pm->skip_over_dtim = val;
93 break;
94 case MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS:
95 IWL_DEBUG_POWER(mvm, "skip_dtim_periods=%d\n", val);
96 dbgfs_pm->skip_dtim_periods = val;
97 break;
98 case MVM_DEBUGFS_PM_RX_DATA_TIMEOUT:
99 IWL_DEBUG_POWER(mvm, "rx_data_timeout=%d\n", val);
100 dbgfs_pm->rx_data_timeout = val;
101 break;
102 case MVM_DEBUGFS_PM_TX_DATA_TIMEOUT:
103 IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val);
104 dbgfs_pm->tx_data_timeout = val;
105 break;
106 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
107 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
108 dbgfs_pm->disable_power_off = val;
109 break;
110 case MVM_DEBUGFS_PM_LPRX_ENA:
111 IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled");
112 dbgfs_pm->lprx_ena = val;
113 break;
114 case MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD:
115 IWL_DEBUG_POWER(mvm, "lprx_rssi_threshold=%d\n", val);
116 dbgfs_pm->lprx_rssi_threshold = val;
117 break;
118 case MVM_DEBUGFS_PM_SNOOZE_ENABLE:
119 IWL_DEBUG_POWER(mvm, "snooze_enable=%d\n", val);
120 dbgfs_pm->snooze_ena = val;
121 break;
122 case MVM_DEBUGFS_PM_UAPSD_MISBEHAVING:
123 IWL_DEBUG_POWER(mvm, "uapsd_misbehaving_enable=%d\n", val);
124 dbgfs_pm->uapsd_misbehaving = val;
125 break;
126 }
127}
128
129static ssize_t iwl_dbgfs_pm_params_write(struct ieee80211_vif *vif, char *buf,
130 size_t count, loff_t *ppos)
131{
132 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
133 struct iwl_mvm *mvm = mvmvif->mvm;
134 enum iwl_dbgfs_pm_mask param;
135 int val, ret;
136
137 if (!strncmp("keep_alive=", buf, 11)) {
138 if (sscanf(buf + 11, "%d", &val) != 1)
139 return -EINVAL;
140 param = MVM_DEBUGFS_PM_KEEP_ALIVE;
141 } else if (!strncmp("skip_over_dtim=", buf, 15)) {
142 if (sscanf(buf + 15, "%d", &val) != 1)
143 return -EINVAL;
144 param = MVM_DEBUGFS_PM_SKIP_OVER_DTIM;
145 } else if (!strncmp("skip_dtim_periods=", buf, 18)) {
146 if (sscanf(buf + 18, "%d", &val) != 1)
147 return -EINVAL;
148 param = MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS;
149 } else if (!strncmp("rx_data_timeout=", buf, 16)) {
150 if (sscanf(buf + 16, "%d", &val) != 1)
151 return -EINVAL;
152 param = MVM_DEBUGFS_PM_RX_DATA_TIMEOUT;
153 } else if (!strncmp("tx_data_timeout=", buf, 16)) {
154 if (sscanf(buf + 16, "%d", &val) != 1)
155 return -EINVAL;
156 param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
157 } else if (!strncmp("disable_power_off=", buf, 18) &&
158 !(mvm->fw->ucode_capa.flags &
159 IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) {
160 if (sscanf(buf + 18, "%d", &val) != 1)
161 return -EINVAL;
162 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
163 } else if (!strncmp("lprx=", buf, 5)) {
164 if (sscanf(buf + 5, "%d", &val) != 1)
165 return -EINVAL;
166 param = MVM_DEBUGFS_PM_LPRX_ENA;
167 } else if (!strncmp("lprx_rssi_threshold=", buf, 20)) {
168 if (sscanf(buf + 20, "%d", &val) != 1)
169 return -EINVAL;
170 if (val > POWER_LPRX_RSSI_THRESHOLD_MAX || val <
171 POWER_LPRX_RSSI_THRESHOLD_MIN)
172 return -EINVAL;
173 param = MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD;
174 } else if (!strncmp("snooze_enable=", buf, 14)) {
175 if (sscanf(buf + 14, "%d", &val) != 1)
176 return -EINVAL;
177 param = MVM_DEBUGFS_PM_SNOOZE_ENABLE;
178 } else if (!strncmp("uapsd_misbehaving=", buf, 18)) {
179 if (sscanf(buf + 18, "%d", &val) != 1)
180 return -EINVAL;
181 param = MVM_DEBUGFS_PM_UAPSD_MISBEHAVING;
182 } else {
183 return -EINVAL;
184 }
185
186 mutex_lock(&mvm->mutex);
187 iwl_dbgfs_update_pm(mvm, vif, param, val);
188 ret = iwl_mvm_power_update_mode(mvm, vif);
189 mutex_unlock(&mvm->mutex);
190
191 return ret ?: count;
192}
193
194static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
195 char __user *user_buf,
196 size_t count, loff_t *ppos)
197{
198 struct ieee80211_vif *vif = file->private_data;
199 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
200 struct iwl_mvm *mvm = mvmvif->mvm;
201 char buf[512];
202 int bufsz = sizeof(buf);
203 int pos;
204
205 pos = iwl_mvm_power_dbgfs_read(mvm, vif, buf, bufsz);
206
207 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
208}
209
210static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
211 char __user *user_buf,
212 size_t count, loff_t *ppos)
213{
214 struct ieee80211_vif *vif = file->private_data;
215 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
216 struct iwl_mvm *mvm = mvmvif->mvm;
217 u8 ap_sta_id;
218 struct ieee80211_chanctx_conf *chanctx_conf;
219 char buf[512];
220 int bufsz = sizeof(buf);
221 int pos = 0;
222 int i;
223
224 mutex_lock(&mvm->mutex);
225
226 ap_sta_id = mvmvif->ap_sta_id;
227
228 pos += scnprintf(buf+pos, bufsz-pos, "mac id/color: %d / %d\n",
229 mvmvif->id, mvmvif->color);
230 pos += scnprintf(buf+pos, bufsz-pos, "bssid: %pM\n",
231 vif->bss_conf.bssid);
232 pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n");
233 for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++)
234 pos += scnprintf(buf+pos, bufsz-pos,
235 "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n",
236 i, mvmvif->queue_params[i].txop,
237 mvmvif->queue_params[i].cw_min,
238 mvmvif->queue_params[i].cw_max,
239 mvmvif->queue_params[i].aifs,
240 mvmvif->queue_params[i].uapsd);
241
242 if (vif->type == NL80211_IFTYPE_STATION &&
243 ap_sta_id != IWL_MVM_STATION_COUNT) {
244 struct ieee80211_sta *sta;
245
246 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[ap_sta_id],
247 lockdep_is_held(&mvm->mutex));
248 if (!IS_ERR_OR_NULL(sta)) {
249 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
250
251 pos += scnprintf(buf+pos, bufsz-pos,
252 "ap_sta_id %d - reduced Tx power %d\n",
253 ap_sta_id,
254 mvm_sta->bt_reduced_txpower);
255 }
256 }
257
258 rcu_read_lock();
259 chanctx_conf = rcu_dereference(vif->chanctx_conf);
260 if (chanctx_conf)
261 pos += scnprintf(buf+pos, bufsz-pos,
262 "idle rx chains %d, active rx chains: %d\n",
263 chanctx_conf->rx_chains_static,
264 chanctx_conf->rx_chains_dynamic);
265 rcu_read_unlock();
266
267 mutex_unlock(&mvm->mutex);
268
269 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
270}
271
272static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif,
273 enum iwl_dbgfs_bf_mask param, int value)
274{
275 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
276 struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
277
278 dbgfs_bf->mask |= param;
279
280 switch (param) {
281 case MVM_DEBUGFS_BF_ENERGY_DELTA:
282 dbgfs_bf->bf_energy_delta = value;
283 break;
284 case MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA:
285 dbgfs_bf->bf_roaming_energy_delta = value;
286 break;
287 case MVM_DEBUGFS_BF_ROAMING_STATE:
288 dbgfs_bf->bf_roaming_state = value;
289 break;
290 case MVM_DEBUGFS_BF_TEMP_THRESHOLD:
291 dbgfs_bf->bf_temp_threshold = value;
292 break;
293 case MVM_DEBUGFS_BF_TEMP_FAST_FILTER:
294 dbgfs_bf->bf_temp_fast_filter = value;
295 break;
296 case MVM_DEBUGFS_BF_TEMP_SLOW_FILTER:
297 dbgfs_bf->bf_temp_slow_filter = value;
298 break;
299 case MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER:
300 dbgfs_bf->bf_enable_beacon_filter = value;
301 break;
302 case MVM_DEBUGFS_BF_DEBUG_FLAG:
303 dbgfs_bf->bf_debug_flag = value;
304 break;
305 case MVM_DEBUGFS_BF_ESCAPE_TIMER:
306 dbgfs_bf->bf_escape_timer = value;
307 break;
308 case MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT:
309 dbgfs_bf->ba_enable_beacon_abort = value;
310 break;
311 case MVM_DEBUGFS_BA_ESCAPE_TIMER:
312 dbgfs_bf->ba_escape_timer = value;
313 break;
314 }
315}
316
317static ssize_t iwl_dbgfs_bf_params_write(struct ieee80211_vif *vif, char *buf,
318 size_t count, loff_t *ppos)
319{
320 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
321 struct iwl_mvm *mvm = mvmvif->mvm;
322 enum iwl_dbgfs_bf_mask param;
323 int value, ret = 0;
324
325 if (!strncmp("bf_energy_delta=", buf, 16)) {
326 if (sscanf(buf+16, "%d", &value) != 1)
327 return -EINVAL;
328 if (value < IWL_BF_ENERGY_DELTA_MIN ||
329 value > IWL_BF_ENERGY_DELTA_MAX)
330 return -EINVAL;
331 param = MVM_DEBUGFS_BF_ENERGY_DELTA;
332 } else if (!strncmp("bf_roaming_energy_delta=", buf, 24)) {
333 if (sscanf(buf+24, "%d", &value) != 1)
334 return -EINVAL;
335 if (value < IWL_BF_ROAMING_ENERGY_DELTA_MIN ||
336 value > IWL_BF_ROAMING_ENERGY_DELTA_MAX)
337 return -EINVAL;
338 param = MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA;
339 } else if (!strncmp("bf_roaming_state=", buf, 17)) {
340 if (sscanf(buf+17, "%d", &value) != 1)
341 return -EINVAL;
342 if (value < IWL_BF_ROAMING_STATE_MIN ||
343 value > IWL_BF_ROAMING_STATE_MAX)
344 return -EINVAL;
345 param = MVM_DEBUGFS_BF_ROAMING_STATE;
346 } else if (!strncmp("bf_temp_threshold=", buf, 18)) {
347 if (sscanf(buf+18, "%d", &value) != 1)
348 return -EINVAL;
349 if (value < IWL_BF_TEMP_THRESHOLD_MIN ||
350 value > IWL_BF_TEMP_THRESHOLD_MAX)
351 return -EINVAL;
352 param = MVM_DEBUGFS_BF_TEMP_THRESHOLD;
353 } else if (!strncmp("bf_temp_fast_filter=", buf, 20)) {
354 if (sscanf(buf+20, "%d", &value) != 1)
355 return -EINVAL;
356 if (value < IWL_BF_TEMP_FAST_FILTER_MIN ||
357 value > IWL_BF_TEMP_FAST_FILTER_MAX)
358 return -EINVAL;
359 param = MVM_DEBUGFS_BF_TEMP_FAST_FILTER;
360 } else if (!strncmp("bf_temp_slow_filter=", buf, 20)) {
361 if (sscanf(buf+20, "%d", &value) != 1)
362 return -EINVAL;
363 if (value < IWL_BF_TEMP_SLOW_FILTER_MIN ||
364 value > IWL_BF_TEMP_SLOW_FILTER_MAX)
365 return -EINVAL;
366 param = MVM_DEBUGFS_BF_TEMP_SLOW_FILTER;
367 } else if (!strncmp("bf_enable_beacon_filter=", buf, 24)) {
368 if (sscanf(buf+24, "%d", &value) != 1)
369 return -EINVAL;
370 if (value < 0 || value > 1)
371 return -EINVAL;
372 param = MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER;
373 } else if (!strncmp("bf_debug_flag=", buf, 14)) {
374 if (sscanf(buf+14, "%d", &value) != 1)
375 return -EINVAL;
376 if (value < 0 || value > 1)
377 return -EINVAL;
378 param = MVM_DEBUGFS_BF_DEBUG_FLAG;
379 } else if (!strncmp("bf_escape_timer=", buf, 16)) {
380 if (sscanf(buf+16, "%d", &value) != 1)
381 return -EINVAL;
382 if (value < IWL_BF_ESCAPE_TIMER_MIN ||
383 value > IWL_BF_ESCAPE_TIMER_MAX)
384 return -EINVAL;
385 param = MVM_DEBUGFS_BF_ESCAPE_TIMER;
386 } else if (!strncmp("ba_escape_timer=", buf, 16)) {
387 if (sscanf(buf+16, "%d", &value) != 1)
388 return -EINVAL;
389 if (value < IWL_BA_ESCAPE_TIMER_MIN ||
390 value > IWL_BA_ESCAPE_TIMER_MAX)
391 return -EINVAL;
392 param = MVM_DEBUGFS_BA_ESCAPE_TIMER;
393 } else if (!strncmp("ba_enable_beacon_abort=", buf, 23)) {
394 if (sscanf(buf+23, "%d", &value) != 1)
395 return -EINVAL;
396 if (value < 0 || value > 1)
397 return -EINVAL;
398 param = MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT;
399 } else {
400 return -EINVAL;
401 }
402
403 mutex_lock(&mvm->mutex);
404 iwl_dbgfs_update_bf(vif, param, value);
405 if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value)
406 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
407 else
408 ret = iwl_mvm_enable_beacon_filter(mvm, vif);
409 mutex_unlock(&mvm->mutex);
410
411 return ret ?: count;
412}
413
414static ssize_t iwl_dbgfs_bf_params_read(struct file *file,
415 char __user *user_buf,
416 size_t count, loff_t *ppos)
417{
418 struct ieee80211_vif *vif = file->private_data;
419 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
420 char buf[256];
421 int pos = 0;
422 const size_t bufsz = sizeof(buf);
423 struct iwl_beacon_filter_cmd cmd = {
424 IWL_BF_CMD_CONFIG_DEFAULTS,
425 .bf_enable_beacon_filter =
426 cpu_to_le32(IWL_BF_ENABLE_BEACON_FILTER_DEFAULT),
427 .ba_enable_beacon_abort =
428 cpu_to_le32(IWL_BA_ENABLE_BEACON_ABORT_DEFAULT),
429 };
430
431 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
432 if (mvmvif->bf_data.bf_enabled)
433 cmd.bf_enable_beacon_filter = cpu_to_le32(1);
434 else
435 cmd.bf_enable_beacon_filter = 0;
436
437 pos += scnprintf(buf+pos, bufsz-pos, "bf_energy_delta = %d\n",
438 le32_to_cpu(cmd.bf_energy_delta));
439 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_energy_delta = %d\n",
440 le32_to_cpu(cmd.bf_roaming_energy_delta));
441 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_state = %d\n",
442 le32_to_cpu(cmd.bf_roaming_state));
443 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_threshold = %d\n",
444 le32_to_cpu(cmd.bf_temp_threshold));
445 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_fast_filter = %d\n",
446 le32_to_cpu(cmd.bf_temp_fast_filter));
447 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_slow_filter = %d\n",
448 le32_to_cpu(cmd.bf_temp_slow_filter));
449 pos += scnprintf(buf+pos, bufsz-pos, "bf_enable_beacon_filter = %d\n",
450 le32_to_cpu(cmd.bf_enable_beacon_filter));
451 pos += scnprintf(buf+pos, bufsz-pos, "bf_debug_flag = %d\n",
452 le32_to_cpu(cmd.bf_debug_flag));
453 pos += scnprintf(buf+pos, bufsz-pos, "bf_escape_timer = %d\n",
454 le32_to_cpu(cmd.bf_escape_timer));
455 pos += scnprintf(buf+pos, bufsz-pos, "ba_escape_timer = %d\n",
456 le32_to_cpu(cmd.ba_escape_timer));
457 pos += scnprintf(buf+pos, bufsz-pos, "ba_enable_beacon_abort = %d\n",
458 le32_to_cpu(cmd.ba_enable_beacon_abort));
459
460 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
461}
462
463#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
464 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
465#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
466 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
467#define MVM_DEBUGFS_ADD_FILE_VIF(name, parent, mode) do { \
468 if (!debugfs_create_file(#name, mode, parent, vif, \
469 &iwl_dbgfs_##name##_ops)) \
470 goto err; \
471 } while (0)
472
473MVM_DEBUGFS_READ_FILE_OPS(mac_params);
474MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params, 32);
475MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256);
476
477void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
478{
479 struct dentry *dbgfs_dir = vif->debugfs_dir;
480 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
481 char buf[100];
482
483 /*
484 * Check if debugfs directory already exist before creating it.
485 * This may happen when, for example, resetting hw or suspend-resume
486 */
487 if (!dbgfs_dir || mvmvif->dbgfs_dir)
488 return;
489
490 mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
491 mvmvif->mvm = mvm;
492
493 if (!mvmvif->dbgfs_dir) {
494 IWL_ERR(mvm, "Failed to create debugfs directory under %s\n",
495 dbgfs_dir->d_name.name);
496 return;
497 }
498
499 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
500 ((vif->type == NL80211_IFTYPE_STATION && !vif->p2p) ||
501 (vif->type == NL80211_IFTYPE_STATION && vif->p2p &&
502 mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS)))
503 MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR |
504 S_IRUSR);
505
506 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir,
507 S_IRUSR);
508
509 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
510 mvmvif == mvm->bf_allowed_vif)
511 MVM_DEBUGFS_ADD_FILE_VIF(bf_params, mvmvif->dbgfs_dir,
512 S_IRUSR | S_IWUSR);
513
514 /*
515 * Create symlink for convenience pointing to interface specific
516 * debugfs entries for the driver. For example, under
517 * /sys/kernel/debug/iwlwifi/0000\:02\:00.0/iwlmvm/
518 * find
519 * netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/
520 */
521 snprintf(buf, 100, "../../../%s/%s/%s/%s",
522 dbgfs_dir->d_parent->d_parent->d_name.name,
523 dbgfs_dir->d_parent->d_name.name,
524 dbgfs_dir->d_name.name,
525 mvmvif->dbgfs_dir->d_name.name);
526
527 mvmvif->dbgfs_slink = debugfs_create_symlink(dbgfs_dir->d_name.name,
528 mvm->debugfs_dir, buf);
529 if (!mvmvif->dbgfs_slink)
530 IWL_ERR(mvm, "Can't create debugfs symbolic link under %s\n",
531 dbgfs_dir->d_name.name);
532 return;
533err:
534 IWL_ERR(mvm, "Can't create debugfs entity\n");
535}
536
537void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
538{
539 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
540
541 debugfs_remove(mvmvif->dbgfs_slink);
542 mvmvif->dbgfs_slink = NULL;
543
544 debugfs_remove_recursive(mvmvif->dbgfs_dir);
545 mvmvif->dbgfs_dir = NULL;
546}
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index a8fe6b41f9a3..369d4c90e669 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -63,30 +63,18 @@
63#include "mvm.h" 63#include "mvm.h"
64#include "sta.h" 64#include "sta.h"
65#include "iwl-io.h" 65#include "iwl-io.h"
66#include "iwl-prph.h"
67#include "debugfs.h"
66 68
67struct iwl_dbgfs_mvm_ctx { 69static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
68 struct iwl_mvm *mvm;
69 struct ieee80211_vif *vif;
70};
71
72static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,
73 const char __user *user_buf,
74 size_t count, loff_t *ppos) 70 size_t count, loff_t *ppos)
75{ 71{
76 struct iwl_mvm *mvm = file->private_data; 72 int ret;
77
78 char buf[16];
79 int buf_size, ret;
80 u32 scd_q_msk; 73 u32 scd_q_msk;
81 74
82 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR) 75 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
83 return -EIO; 76 return -EIO;
84 77
85 memset(buf, 0, sizeof(buf));
86 buf_size = min(count, sizeof(buf) - 1);
87 if (copy_from_user(buf, user_buf, buf_size))
88 return -EFAULT;
89
90 if (sscanf(buf, "%x", &scd_q_msk) != 1) 78 if (sscanf(buf, "%x", &scd_q_msk) != 1)
91 return -EINVAL; 79 return -EINVAL;
92 80
@@ -99,24 +87,15 @@ static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,
99 return ret; 87 return ret;
100} 88}
101 89
102static ssize_t iwl_dbgfs_sta_drain_write(struct file *file, 90static ssize_t iwl_dbgfs_sta_drain_write(struct iwl_mvm *mvm, char *buf,
103 const char __user *user_buf,
104 size_t count, loff_t *ppos) 91 size_t count, loff_t *ppos)
105{ 92{
106 struct iwl_mvm *mvm = file->private_data;
107 struct ieee80211_sta *sta; 93 struct ieee80211_sta *sta;
108 94 int sta_id, drain, ret;
109 char buf[8];
110 int buf_size, sta_id, drain, ret;
111 95
112 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR) 96 if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
113 return -EIO; 97 return -EIO;
114 98
115 memset(buf, 0, sizeof(buf));
116 buf_size = min(count, sizeof(buf) - 1);
117 if (copy_from_user(buf, user_buf, buf_size))
118 return -EFAULT;
119
120 if (sscanf(buf, "%d %d", &sta_id, &drain) != 2) 99 if (sscanf(buf, "%d %d", &sta_id, &drain) != 2)
121 return -EINVAL; 100 return -EINVAL;
122 if (sta_id < 0 || sta_id >= IWL_MVM_STATION_COUNT) 101 if (sta_id < 0 || sta_id >= IWL_MVM_STATION_COUNT)
@@ -144,73 +123,57 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
144{ 123{
145 struct iwl_mvm *mvm = file->private_data; 124 struct iwl_mvm *mvm = file->private_data;
146 const struct fw_img *img; 125 const struct fw_img *img;
147 int ofs, len, pos = 0; 126 unsigned int ofs, len;
148 size_t bufsz, ret; 127 size_t ret;
149 char *buf;
150 u8 *ptr; 128 u8 *ptr;
151 129
152 if (!mvm->ucode_loaded) 130 if (!mvm->ucode_loaded)
153 return -EINVAL; 131 return -EINVAL;
154 132
155 /* default is to dump the entire data segment */ 133 /* default is to dump the entire data segment */
156 if (!mvm->dbgfs_sram_offset && !mvm->dbgfs_sram_len) { 134 img = &mvm->fw->img[mvm->cur_ucode];
157 img = &mvm->fw->img[mvm->cur_ucode]; 135 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
158 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset; 136 len = img->sec[IWL_UCODE_SECTION_DATA].len;
159 len = img->sec[IWL_UCODE_SECTION_DATA].len; 137
160 } else { 138 if (mvm->dbgfs_sram_len) {
161 ofs = mvm->dbgfs_sram_offset; 139 ofs = mvm->dbgfs_sram_offset;
162 len = mvm->dbgfs_sram_len; 140 len = mvm->dbgfs_sram_len;
163 } 141 }
164 142
165 bufsz = len * 4 + 256;
166 buf = kzalloc(bufsz, GFP_KERNEL);
167 if (!buf)
168 return -ENOMEM;
169
170 ptr = kzalloc(len, GFP_KERNEL); 143 ptr = kzalloc(len, GFP_KERNEL);
171 if (!ptr) { 144 if (!ptr)
172 kfree(buf);
173 return -ENOMEM; 145 return -ENOMEM;
174 }
175
176 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", len);
177 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", ofs);
178 146
179 iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len); 147 iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len);
180 for (ofs = 0; ofs < len; ofs += 16) {
181 pos += scnprintf(buf + pos, bufsz - pos, "0x%.4x ", ofs);
182 hex_dump_to_buffer(ptr + ofs, 16, 16, 1, buf + pos,
183 bufsz - pos, false);
184 pos += strlen(buf + pos);
185 if (bufsz - pos > 0)
186 buf[pos++] = '\n';
187 }
188 148
189 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 149 ret = simple_read_from_buffer(user_buf, count, ppos, ptr, len);
190 150
191 kfree(buf);
192 kfree(ptr); 151 kfree(ptr);
193 152
194 return ret; 153 return ret;
195} 154}
196 155
197static ssize_t iwl_dbgfs_sram_write(struct file *file, 156static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf,
198 const char __user *user_buf, size_t count, 157 size_t count, loff_t *ppos)
199 loff_t *ppos)
200{ 158{
201 struct iwl_mvm *mvm = file->private_data; 159 const struct fw_img *img;
202 char buf[64];
203 int buf_size;
204 u32 offset, len; 160 u32 offset, len;
161 u32 img_offset, img_len;
162
163 if (!mvm->ucode_loaded)
164 return -EINVAL;
205 165
206 memset(buf, 0, sizeof(buf)); 166 img = &mvm->fw->img[mvm->cur_ucode];
207 buf_size = min(count, sizeof(buf) - 1); 167 img_offset = img->sec[IWL_UCODE_SECTION_DATA].offset;
208 if (copy_from_user(buf, user_buf, buf_size)) 168 img_len = img->sec[IWL_UCODE_SECTION_DATA].len;
209 return -EFAULT;
210 169
211 if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 170 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
212 if ((offset & 0x3) || (len & 0x3)) 171 if ((offset & 0x3) || (len & 0x3))
213 return -EINVAL; 172 return -EINVAL;
173
174 if (offset + len > img_offset + img_len)
175 return -EINVAL;
176
214 mvm->dbgfs_sram_offset = offset; 177 mvm->dbgfs_sram_offset = offset;
215 mvm->dbgfs_sram_len = len; 178 mvm->dbgfs_sram_len = len;
216 } else { 179 } else {
@@ -267,22 +230,14 @@ static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file,
267 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 230 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
268} 231}
269 232
270static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file, 233static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf,
271 const char __user *user_buf,
272 size_t count, loff_t *ppos) 234 size_t count, loff_t *ppos)
273{ 235{
274 struct iwl_mvm *mvm = file->private_data; 236 int ret, val;
275 char buf[64] = {};
276 int ret;
277 int val;
278 237
279 if (!mvm->ucode_loaded) 238 if (!mvm->ucode_loaded)
280 return -EIO; 239 return -EIO;
281 240
282 count = min_t(size_t, count, sizeof(buf) - 1);
283 if (copy_from_user(buf, user_buf, count))
284 return -EFAULT;
285
286 if (!strncmp("disable_power_off_d0=", buf, 21)) { 241 if (!strncmp("disable_power_off_d0=", buf, 21)) {
287 if (sscanf(buf + 21, "%d", &val) != 1) 242 if (sscanf(buf + 21, "%d", &val) != 1)
288 return -EINVAL; 243 return -EINVAL;
@@ -302,212 +257,6 @@ static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file,
302 return ret ?: count; 257 return ret ?: count;
303} 258}
304 259
305static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
306 struct ieee80211_vif *vif,
307 enum iwl_dbgfs_pm_mask param, int val)
308{
309 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
310 struct iwl_dbgfs_pm *dbgfs_pm = &mvmvif->dbgfs_pm;
311
312 dbgfs_pm->mask |= param;
313
314 switch (param) {
315 case MVM_DEBUGFS_PM_KEEP_ALIVE: {
316 struct ieee80211_hw *hw = mvm->hw;
317 int dtimper = hw->conf.ps_dtim_period ?: 1;
318 int dtimper_msec = dtimper * vif->bss_conf.beacon_int;
319
320 IWL_DEBUG_POWER(mvm, "debugfs: set keep_alive= %d sec\n", val);
321 if (val * MSEC_PER_SEC < 3 * dtimper_msec) {
322 IWL_WARN(mvm,
323 "debugfs: keep alive period (%ld msec) is less than minimum required (%d msec)\n",
324 val * MSEC_PER_SEC, 3 * dtimper_msec);
325 }
326 dbgfs_pm->keep_alive_seconds = val;
327 break;
328 }
329 case MVM_DEBUGFS_PM_SKIP_OVER_DTIM:
330 IWL_DEBUG_POWER(mvm, "skip_over_dtim %s\n",
331 val ? "enabled" : "disabled");
332 dbgfs_pm->skip_over_dtim = val;
333 break;
334 case MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS:
335 IWL_DEBUG_POWER(mvm, "skip_dtim_periods=%d\n", val);
336 dbgfs_pm->skip_dtim_periods = val;
337 break;
338 case MVM_DEBUGFS_PM_RX_DATA_TIMEOUT:
339 IWL_DEBUG_POWER(mvm, "rx_data_timeout=%d\n", val);
340 dbgfs_pm->rx_data_timeout = val;
341 break;
342 case MVM_DEBUGFS_PM_TX_DATA_TIMEOUT:
343 IWL_DEBUG_POWER(mvm, "tx_data_timeout=%d\n", val);
344 dbgfs_pm->tx_data_timeout = val;
345 break;
346 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
347 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
348 dbgfs_pm->disable_power_off = val;
349 break;
350 case MVM_DEBUGFS_PM_LPRX_ENA:
351 IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled");
352 dbgfs_pm->lprx_ena = val;
353 break;
354 case MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD:
355 IWL_DEBUG_POWER(mvm, "lprx_rssi_threshold=%d\n", val);
356 dbgfs_pm->lprx_rssi_threshold = val;
357 break;
358 case MVM_DEBUGFS_PM_SNOOZE_ENABLE:
359 IWL_DEBUG_POWER(mvm, "snooze_enable=%d\n", val);
360 dbgfs_pm->snooze_ena = val;
361 break;
362 }
363}
364
365static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
366 const char __user *user_buf,
367 size_t count, loff_t *ppos)
368{
369 struct ieee80211_vif *vif = file->private_data;
370 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
371 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
372 enum iwl_dbgfs_pm_mask param;
373 char buf[32] = {};
374 int val;
375 int ret;
376
377 count = min_t(size_t, count, sizeof(buf) - 1);
378 if (copy_from_user(buf, user_buf, count))
379 return -EFAULT;
380
381 if (!strncmp("keep_alive=", buf, 11)) {
382 if (sscanf(buf + 11, "%d", &val) != 1)
383 return -EINVAL;
384 param = MVM_DEBUGFS_PM_KEEP_ALIVE;
385 } else if (!strncmp("skip_over_dtim=", buf, 15)) {
386 if (sscanf(buf + 15, "%d", &val) != 1)
387 return -EINVAL;
388 param = MVM_DEBUGFS_PM_SKIP_OVER_DTIM;
389 } else if (!strncmp("skip_dtim_periods=", buf, 18)) {
390 if (sscanf(buf + 18, "%d", &val) != 1)
391 return -EINVAL;
392 param = MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS;
393 } else if (!strncmp("rx_data_timeout=", buf, 16)) {
394 if (sscanf(buf + 16, "%d", &val) != 1)
395 return -EINVAL;
396 param = MVM_DEBUGFS_PM_RX_DATA_TIMEOUT;
397 } else if (!strncmp("tx_data_timeout=", buf, 16)) {
398 if (sscanf(buf + 16, "%d", &val) != 1)
399 return -EINVAL;
400 param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
401 } else if (!strncmp("disable_power_off=", buf, 18) &&
402 !(mvm->fw->ucode_capa.flags &
403 IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) {
404 if (sscanf(buf + 18, "%d", &val) != 1)
405 return -EINVAL;
406 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
407 } else if (!strncmp("lprx=", buf, 5)) {
408 if (sscanf(buf + 5, "%d", &val) != 1)
409 return -EINVAL;
410 param = MVM_DEBUGFS_PM_LPRX_ENA;
411 } else if (!strncmp("lprx_rssi_threshold=", buf, 20)) {
412 if (sscanf(buf + 20, "%d", &val) != 1)
413 return -EINVAL;
414 if (val > POWER_LPRX_RSSI_THRESHOLD_MAX || val <
415 POWER_LPRX_RSSI_THRESHOLD_MIN)
416 return -EINVAL;
417 param = MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD;
418 } else if (!strncmp("snooze_enable=", buf, 14)) {
419 if (sscanf(buf + 14, "%d", &val) != 1)
420 return -EINVAL;
421 param = MVM_DEBUGFS_PM_SNOOZE_ENABLE;
422 } else {
423 return -EINVAL;
424 }
425
426 mutex_lock(&mvm->mutex);
427 iwl_dbgfs_update_pm(mvm, vif, param, val);
428 ret = iwl_mvm_power_update_mode(mvm, vif);
429 mutex_unlock(&mvm->mutex);
430
431 return ret ?: count;
432}
433
434static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
435 char __user *user_buf,
436 size_t count, loff_t *ppos)
437{
438 struct ieee80211_vif *vif = file->private_data;
439 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
440 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
441 char buf[512];
442 int bufsz = sizeof(buf);
443 int pos;
444
445 pos = iwl_mvm_power_dbgfs_read(mvm, vif, buf, bufsz);
446
447 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
448}
449
450static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
451 char __user *user_buf,
452 size_t count, loff_t *ppos)
453{
454 struct ieee80211_vif *vif = file->private_data;
455 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
456 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
457 u8 ap_sta_id;
458 struct ieee80211_chanctx_conf *chanctx_conf;
459 char buf[512];
460 int bufsz = sizeof(buf);
461 int pos = 0;
462 int i;
463
464 mutex_lock(&mvm->mutex);
465
466 ap_sta_id = mvmvif->ap_sta_id;
467
468 pos += scnprintf(buf+pos, bufsz-pos, "mac id/color: %d / %d\n",
469 mvmvif->id, mvmvif->color);
470 pos += scnprintf(buf+pos, bufsz-pos, "bssid: %pM\n",
471 vif->bss_conf.bssid);
472 pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n");
473 for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++) {
474 pos += scnprintf(buf+pos, bufsz-pos,
475 "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n",
476 i, mvmvif->queue_params[i].txop,
477 mvmvif->queue_params[i].cw_min,
478 mvmvif->queue_params[i].cw_max,
479 mvmvif->queue_params[i].aifs,
480 mvmvif->queue_params[i].uapsd);
481 }
482
483 if (vif->type == NL80211_IFTYPE_STATION &&
484 ap_sta_id != IWL_MVM_STATION_COUNT) {
485 struct ieee80211_sta *sta;
486 struct iwl_mvm_sta *mvm_sta;
487
488 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[ap_sta_id],
489 lockdep_is_held(&mvm->mutex));
490 mvm_sta = (void *)sta->drv_priv;
491 pos += scnprintf(buf+pos, bufsz-pos,
492 "ap_sta_id %d - reduced Tx power %d\n",
493 ap_sta_id, mvm_sta->bt_reduced_txpower);
494 }
495
496 rcu_read_lock();
497 chanctx_conf = rcu_dereference(vif->chanctx_conf);
498 if (chanctx_conf) {
499 pos += scnprintf(buf+pos, bufsz-pos,
500 "idle rx chains %d, active rx chains: %d\n",
501 chanctx_conf->rx_chains_static,
502 chanctx_conf->rx_chains_dynamic);
503 }
504 rcu_read_unlock();
505
506 mutex_unlock(&mvm->mutex);
507
508 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
509}
510
511#define BT_MBOX_MSG(_notif, _num, _field) \ 260#define BT_MBOX_MSG(_notif, _num, _field) \
512 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ 261 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
513 >> BT_MBOX##_num##_##_field##_POS) 262 >> BT_MBOX##_num##_##_field##_POS)
@@ -783,11 +532,9 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
783} 532}
784#undef PRINT_STAT_LE32 533#undef PRINT_STAT_LE32
785 534
786static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, 535static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf,
787 const char __user *user_buf,
788 size_t count, loff_t *ppos) 536 size_t count, loff_t *ppos)
789{ 537{
790 struct iwl_mvm *mvm = file->private_data;
791 int ret; 538 int ret;
792 539
793 mutex_lock(&mvm->mutex); 540 mutex_lock(&mvm->mutex);
@@ -804,6 +551,14 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
804 return count; 551 return count;
805} 552}
806 553
554static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
555 size_t count, loff_t *ppos)
556{
557 iwl_write_prph(mvm->trans, DEVICE_SET_NMI_REG, 1);
558
559 return count;
560}
561
807static ssize_t 562static ssize_t
808iwl_dbgfs_scan_ant_rxchain_read(struct file *file, 563iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
809 char __user *user_buf, 564 char __user *user_buf,
@@ -828,21 +583,11 @@ iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
828} 583}
829 584
830static ssize_t 585static ssize_t
831iwl_dbgfs_scan_ant_rxchain_write(struct file *file, 586iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
832 const char __user *user_buf,
833 size_t count, loff_t *ppos) 587 size_t count, loff_t *ppos)
834{ 588{
835 struct iwl_mvm *mvm = file->private_data;
836 char buf[8];
837 int buf_size;
838 u8 scan_rx_ant; 589 u8 scan_rx_ant;
839 590
840 memset(buf, 0, sizeof(buf));
841 buf_size = min(count, sizeof(buf) - 1);
842
843 /* get the argument from the user and check if it is valid */
844 if (copy_from_user(buf, user_buf, buf_size))
845 return -EFAULT;
846 if (sscanf(buf, "%hhx", &scan_rx_ant) != 1) 591 if (sscanf(buf, "%hhx", &scan_rx_ant) != 1)
847 return -EINVAL; 592 return -EINVAL;
848 if (scan_rx_ant > ANT_ABC) 593 if (scan_rx_ant > ANT_ABC)
@@ -850,228 +595,17 @@ iwl_dbgfs_scan_ant_rxchain_write(struct file *file,
850 if (scan_rx_ant & ~iwl_fw_valid_rx_ant(mvm->fw)) 595 if (scan_rx_ant & ~iwl_fw_valid_rx_ant(mvm->fw))
851 return -EINVAL; 596 return -EINVAL;
852 597
853 /* change the rx antennas for scan command */
854 mvm->scan_rx_ant = scan_rx_ant; 598 mvm->scan_rx_ant = scan_rx_ant;
855 599
856 return count; 600 return count;
857} 601}
858 602
859
860static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif,
861 enum iwl_dbgfs_bf_mask param, int value)
862{
863 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
864 struct iwl_dbgfs_bf *dbgfs_bf = &mvmvif->dbgfs_bf;
865
866 dbgfs_bf->mask |= param;
867
868 switch (param) {
869 case MVM_DEBUGFS_BF_ENERGY_DELTA:
870 dbgfs_bf->bf_energy_delta = value;
871 break;
872 case MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA:
873 dbgfs_bf->bf_roaming_energy_delta = value;
874 break;
875 case MVM_DEBUGFS_BF_ROAMING_STATE:
876 dbgfs_bf->bf_roaming_state = value;
877 break;
878 case MVM_DEBUGFS_BF_TEMP_THRESHOLD:
879 dbgfs_bf->bf_temp_threshold = value;
880 break;
881 case MVM_DEBUGFS_BF_TEMP_FAST_FILTER:
882 dbgfs_bf->bf_temp_fast_filter = value;
883 break;
884 case MVM_DEBUGFS_BF_TEMP_SLOW_FILTER:
885 dbgfs_bf->bf_temp_slow_filter = value;
886 break;
887 case MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER:
888 dbgfs_bf->bf_enable_beacon_filter = value;
889 break;
890 case MVM_DEBUGFS_BF_DEBUG_FLAG:
891 dbgfs_bf->bf_debug_flag = value;
892 break;
893 case MVM_DEBUGFS_BF_ESCAPE_TIMER:
894 dbgfs_bf->bf_escape_timer = value;
895 break;
896 case MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT:
897 dbgfs_bf->ba_enable_beacon_abort = value;
898 break;
899 case MVM_DEBUGFS_BA_ESCAPE_TIMER:
900 dbgfs_bf->ba_escape_timer = value;
901 break;
902 }
903}
904
905static ssize_t iwl_dbgfs_bf_params_write(struct file *file,
906 const char __user *user_buf,
907 size_t count, loff_t *ppos)
908{
909 struct ieee80211_vif *vif = file->private_data;
910 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
911 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
912 enum iwl_dbgfs_bf_mask param;
913 char buf[256];
914 int buf_size;
915 int value;
916 int ret = 0;
917
918 memset(buf, 0, sizeof(buf));
919 buf_size = min(count, sizeof(buf) - 1);
920 if (copy_from_user(buf, user_buf, buf_size))
921 return -EFAULT;
922
923 if (!strncmp("bf_energy_delta=", buf, 16)) {
924 if (sscanf(buf+16, "%d", &value) != 1)
925 return -EINVAL;
926 if (value < IWL_BF_ENERGY_DELTA_MIN ||
927 value > IWL_BF_ENERGY_DELTA_MAX)
928 return -EINVAL;
929 param = MVM_DEBUGFS_BF_ENERGY_DELTA;
930 } else if (!strncmp("bf_roaming_energy_delta=", buf, 24)) {
931 if (sscanf(buf+24, "%d", &value) != 1)
932 return -EINVAL;
933 if (value < IWL_BF_ROAMING_ENERGY_DELTA_MIN ||
934 value > IWL_BF_ROAMING_ENERGY_DELTA_MAX)
935 return -EINVAL;
936 param = MVM_DEBUGFS_BF_ROAMING_ENERGY_DELTA;
937 } else if (!strncmp("bf_roaming_state=", buf, 17)) {
938 if (sscanf(buf+17, "%d", &value) != 1)
939 return -EINVAL;
940 if (value < IWL_BF_ROAMING_STATE_MIN ||
941 value > IWL_BF_ROAMING_STATE_MAX)
942 return -EINVAL;
943 param = MVM_DEBUGFS_BF_ROAMING_STATE;
944 } else if (!strncmp("bf_temp_threshold=", buf, 18)) {
945 if (sscanf(buf+18, "%d", &value) != 1)
946 return -EINVAL;
947 if (value < IWL_BF_TEMP_THRESHOLD_MIN ||
948 value > IWL_BF_TEMP_THRESHOLD_MAX)
949 return -EINVAL;
950 param = MVM_DEBUGFS_BF_TEMP_THRESHOLD;
951 } else if (!strncmp("bf_temp_fast_filter=", buf, 20)) {
952 if (sscanf(buf+20, "%d", &value) != 1)
953 return -EINVAL;
954 if (value < IWL_BF_TEMP_FAST_FILTER_MIN ||
955 value > IWL_BF_TEMP_FAST_FILTER_MAX)
956 return -EINVAL;
957 param = MVM_DEBUGFS_BF_TEMP_FAST_FILTER;
958 } else if (!strncmp("bf_temp_slow_filter=", buf, 20)) {
959 if (sscanf(buf+20, "%d", &value) != 1)
960 return -EINVAL;
961 if (value < IWL_BF_TEMP_SLOW_FILTER_MIN ||
962 value > IWL_BF_TEMP_SLOW_FILTER_MAX)
963 return -EINVAL;
964 param = MVM_DEBUGFS_BF_TEMP_SLOW_FILTER;
965 } else if (!strncmp("bf_enable_beacon_filter=", buf, 24)) {
966 if (sscanf(buf+24, "%d", &value) != 1)
967 return -EINVAL;
968 if (value < 0 || value > 1)
969 return -EINVAL;
970 param = MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER;
971 } else if (!strncmp("bf_debug_flag=", buf, 14)) {
972 if (sscanf(buf+14, "%d", &value) != 1)
973 return -EINVAL;
974 if (value < 0 || value > 1)
975 return -EINVAL;
976 param = MVM_DEBUGFS_BF_DEBUG_FLAG;
977 } else if (!strncmp("bf_escape_timer=", buf, 16)) {
978 if (sscanf(buf+16, "%d", &value) != 1)
979 return -EINVAL;
980 if (value < IWL_BF_ESCAPE_TIMER_MIN ||
981 value > IWL_BF_ESCAPE_TIMER_MAX)
982 return -EINVAL;
983 param = MVM_DEBUGFS_BF_ESCAPE_TIMER;
984 } else if (!strncmp("ba_escape_timer=", buf, 16)) {
985 if (sscanf(buf+16, "%d", &value) != 1)
986 return -EINVAL;
987 if (value < IWL_BA_ESCAPE_TIMER_MIN ||
988 value > IWL_BA_ESCAPE_TIMER_MAX)
989 return -EINVAL;
990 param = MVM_DEBUGFS_BA_ESCAPE_TIMER;
991 } else if (!strncmp("ba_enable_beacon_abort=", buf, 23)) {
992 if (sscanf(buf+23, "%d", &value) != 1)
993 return -EINVAL;
994 if (value < 0 || value > 1)
995 return -EINVAL;
996 param = MVM_DEBUGFS_BA_ENABLE_BEACON_ABORT;
997 } else {
998 return -EINVAL;
999 }
1000
1001 mutex_lock(&mvm->mutex);
1002 iwl_dbgfs_update_bf(vif, param, value);
1003 if (param == MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value) {
1004 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
1005 } else {
1006 ret = iwl_mvm_enable_beacon_filter(mvm, vif);
1007 }
1008 mutex_unlock(&mvm->mutex);
1009
1010 return ret ?: count;
1011}
1012
1013static ssize_t iwl_dbgfs_bf_params_read(struct file *file,
1014 char __user *user_buf,
1015 size_t count, loff_t *ppos)
1016{
1017 struct ieee80211_vif *vif = file->private_data;
1018 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1019 char buf[256];
1020 int pos = 0;
1021 const size_t bufsz = sizeof(buf);
1022 struct iwl_beacon_filter_cmd cmd = {
1023 IWL_BF_CMD_CONFIG_DEFAULTS,
1024 .bf_enable_beacon_filter =
1025 cpu_to_le32(IWL_BF_ENABLE_BEACON_FILTER_DEFAULT),
1026 .ba_enable_beacon_abort =
1027 cpu_to_le32(IWL_BA_ENABLE_BEACON_ABORT_DEFAULT),
1028 };
1029
1030 iwl_mvm_beacon_filter_debugfs_parameters(vif, &cmd);
1031 if (mvmvif->bf_data.bf_enabled)
1032 cmd.bf_enable_beacon_filter = cpu_to_le32(1);
1033 else
1034 cmd.bf_enable_beacon_filter = 0;
1035
1036 pos += scnprintf(buf+pos, bufsz-pos, "bf_energy_delta = %d\n",
1037 le32_to_cpu(cmd.bf_energy_delta));
1038 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_energy_delta = %d\n",
1039 le32_to_cpu(cmd.bf_roaming_energy_delta));
1040 pos += scnprintf(buf+pos, bufsz-pos, "bf_roaming_state = %d\n",
1041 le32_to_cpu(cmd.bf_roaming_state));
1042 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_threshold = %d\n",
1043 le32_to_cpu(cmd.bf_temp_threshold));
1044 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_fast_filter = %d\n",
1045 le32_to_cpu(cmd.bf_temp_fast_filter));
1046 pos += scnprintf(buf+pos, bufsz-pos, "bf_temp_slow_filter = %d\n",
1047 le32_to_cpu(cmd.bf_temp_slow_filter));
1048 pos += scnprintf(buf+pos, bufsz-pos, "bf_enable_beacon_filter = %d\n",
1049 le32_to_cpu(cmd.bf_enable_beacon_filter));
1050 pos += scnprintf(buf+pos, bufsz-pos, "bf_debug_flag = %d\n",
1051 le32_to_cpu(cmd.bf_debug_flag));
1052 pos += scnprintf(buf+pos, bufsz-pos, "bf_escape_timer = %d\n",
1053 le32_to_cpu(cmd.bf_escape_timer));
1054 pos += scnprintf(buf+pos, bufsz-pos, "ba_escape_timer = %d\n",
1055 le32_to_cpu(cmd.ba_escape_timer));
1056 pos += scnprintf(buf+pos, bufsz-pos, "ba_enable_beacon_abort = %d\n",
1057 le32_to_cpu(cmd.ba_enable_beacon_abort));
1058
1059 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1060}
1061
1062#ifdef CONFIG_PM_SLEEP 603#ifdef CONFIG_PM_SLEEP
1063static ssize_t iwl_dbgfs_d3_sram_write(struct file *file, 604static ssize_t iwl_dbgfs_d3_sram_write(struct iwl_mvm *mvm, char *buf,
1064 const char __user *user_buf,
1065 size_t count, loff_t *ppos) 605 size_t count, loff_t *ppos)
1066{ 606{
1067 struct iwl_mvm *mvm = file->private_data;
1068 char buf[8] = {};
1069 int store; 607 int store;
1070 608
1071 count = min_t(size_t, count, sizeof(buf) - 1);
1072 if (copy_from_user(buf, user_buf, count))
1073 return -EFAULT;
1074
1075 if (sscanf(buf, "%d", &store) != 1) 609 if (sscanf(buf, "%d", &store) != 1)
1076 return -EINVAL; 610 return -EINVAL;
1077 611
@@ -1124,61 +658,33 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
1124} 658}
1125#endif 659#endif
1126 660
1127#define MVM_DEBUGFS_READ_FILE_OPS(name) \ 661#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
1128static const struct file_operations iwl_dbgfs_##name##_ops = { \ 662 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1129 .read = iwl_dbgfs_##name##_read, \ 663#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
1130 .open = simple_open, \ 664 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1131 .llseek = generic_file_llseek, \
1132}
1133
1134#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name) \
1135static const struct file_operations iwl_dbgfs_##name##_ops = { \
1136 .write = iwl_dbgfs_##name##_write, \
1137 .read = iwl_dbgfs_##name##_read, \
1138 .open = simple_open, \
1139 .llseek = generic_file_llseek, \
1140};
1141
1142#define MVM_DEBUGFS_WRITE_FILE_OPS(name) \
1143static const struct file_operations iwl_dbgfs_##name##_ops = { \
1144 .write = iwl_dbgfs_##name##_write, \
1145 .open = simple_open, \
1146 .llseek = generic_file_llseek, \
1147};
1148
1149#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) do { \ 665#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) do { \
1150 if (!debugfs_create_file(#name, mode, parent, mvm, \ 666 if (!debugfs_create_file(#name, mode, parent, mvm, \
1151 &iwl_dbgfs_##name##_ops)) \ 667 &iwl_dbgfs_##name##_ops)) \
1152 goto err; \ 668 goto err; \
1153 } while (0) 669 } while (0)
1154 670
1155#define MVM_DEBUGFS_ADD_FILE_VIF(name, parent, mode) do { \
1156 if (!debugfs_create_file(#name, mode, parent, vif, \
1157 &iwl_dbgfs_##name##_ops)) \
1158 goto err; \
1159 } while (0)
1160
1161/* Device wide debugfs entries */ 671/* Device wide debugfs entries */
1162MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush); 672MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
1163MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); 673MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
1164MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); 674MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64);
1165MVM_DEBUGFS_READ_FILE_OPS(stations); 675MVM_DEBUGFS_READ_FILE_OPS(stations);
1166MVM_DEBUGFS_READ_FILE_OPS(bt_notif); 676MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
1167MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); 677MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
1168MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off); 678MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64);
1169MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats); 679MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
1170MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); 680MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
1171MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain); 681MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
682MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
1172 683
1173#ifdef CONFIG_PM_SLEEP 684#ifdef CONFIG_PM_SLEEP
1174MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram); 685MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8);
1175#endif 686#endif
1176 687
1177/* Interface specific debugfs entries */
1178MVM_DEBUGFS_READ_FILE_OPS(mac_params);
1179MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params);
1180MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params);
1181
1182int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) 688int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1183{ 689{
1184 char buf[100]; 690 char buf[100];
@@ -1196,6 +702,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1196 S_IRUSR | S_IWUSR); 702 S_IRUSR | S_IWUSR);
1197 MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR); 703 MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR);
1198 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); 704 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
705 MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, S_IWUSR);
1199 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 706 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir,
1200 S_IWUSR | S_IRUSR); 707 S_IWUSR | S_IRUSR);
1201#ifdef CONFIG_PM_SLEEP 708#ifdef CONFIG_PM_SLEEP
@@ -1206,6 +713,19 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1206 goto err; 713 goto err;
1207#endif 714#endif
1208 715
716 if (!debugfs_create_blob("nvm_hw", S_IRUSR,
717 mvm->debugfs_dir, &mvm->nvm_hw_blob))
718 goto err;
719 if (!debugfs_create_blob("nvm_sw", S_IRUSR,
720 mvm->debugfs_dir, &mvm->nvm_sw_blob))
721 goto err;
722 if (!debugfs_create_blob("nvm_calib", S_IRUSR,
723 mvm->debugfs_dir, &mvm->nvm_calib_blob))
724 goto err;
725 if (!debugfs_create_blob("nvm_prod", S_IRUSR,
726 mvm->debugfs_dir, &mvm->nvm_prod_blob))
727 goto err;
728
1209 /* 729 /*
1210 * Create a symlink with mac80211. It will be removed when mac80211 730 * Create a symlink with mac80211. It will be removed when mac80211
1211 * exists (before the opmode exists which removes the target.) 731 * exists (before the opmode exists which removes the target.)
@@ -1221,72 +741,3 @@ err:
1221 IWL_ERR(mvm, "Can't create the mvm debugfs directory\n"); 741 IWL_ERR(mvm, "Can't create the mvm debugfs directory\n");
1222 return -ENOMEM; 742 return -ENOMEM;
1223} 743}
1224
1225void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1226{
1227 struct dentry *dbgfs_dir = vif->debugfs_dir;
1228 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1229 char buf[100];
1230
1231 /*
1232 * Check if debugfs directory already exist before creating it.
1233 * This may happen when, for example, resetting hw or suspend-resume
1234 */
1235 if (!dbgfs_dir || mvmvif->dbgfs_dir)
1236 return;
1237
1238 mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
1239 mvmvif->dbgfs_data = mvm;
1240
1241 if (!mvmvif->dbgfs_dir) {
1242 IWL_ERR(mvm, "Failed to create debugfs directory under %s\n",
1243 dbgfs_dir->d_name.name);
1244 return;
1245 }
1246
1247 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM &&
1248 vif->type == NL80211_IFTYPE_STATION && !vif->p2p)
1249 MVM_DEBUGFS_ADD_FILE_VIF(pm_params, mvmvif->dbgfs_dir, S_IWUSR |
1250 S_IRUSR);
1251
1252 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir,
1253 S_IRUSR);
1254
1255 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
1256 mvmvif == mvm->bf_allowed_vif)
1257 MVM_DEBUGFS_ADD_FILE_VIF(bf_params, mvmvif->dbgfs_dir,
1258 S_IRUSR | S_IWUSR);
1259
1260 /*
1261 * Create symlink for convenience pointing to interface specific
1262 * debugfs entries for the driver. For example, under
1263 * /sys/kernel/debug/iwlwifi/0000\:02\:00.0/iwlmvm/
1264 * find
1265 * netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/
1266 */
1267 snprintf(buf, 100, "../../../%s/%s/%s/%s",
1268 dbgfs_dir->d_parent->d_parent->d_name.name,
1269 dbgfs_dir->d_parent->d_name.name,
1270 dbgfs_dir->d_name.name,
1271 mvmvif->dbgfs_dir->d_name.name);
1272
1273 mvmvif->dbgfs_slink = debugfs_create_symlink(dbgfs_dir->d_name.name,
1274 mvm->debugfs_dir, buf);
1275 if (!mvmvif->dbgfs_slink)
1276 IWL_ERR(mvm, "Can't create debugfs symbolic link under %s\n",
1277 dbgfs_dir->d_name.name);
1278 return;
1279err:
1280 IWL_ERR(mvm, "Can't create debugfs entity\n");
1281}
1282
1283void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1284{
1285 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1286
1287 debugfs_remove(mvmvif->dbgfs_slink);
1288 mvmvif->dbgfs_slink = NULL;
1289
1290 debugfs_remove_recursive(mvmvif->dbgfs_dir);
1291 mvmvif->dbgfs_dir = NULL;
1292}
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.h b/drivers/net/wireless/iwlwifi/mvm/debugfs.h
new file mode 100644
index 000000000000..e3a9774af495
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.h
@@ -0,0 +1,101 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#define MVM_DEBUGFS_READ_FILE_OPS(name) \
65static const struct file_operations iwl_dbgfs_##name##_ops = { \
66 .read = iwl_dbgfs_##name##_read, \
67 .open = simple_open, \
68 .llseek = generic_file_llseek, \
69}
70
71#define MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \
72static ssize_t _iwl_dbgfs_##name##_write(struct file *file, \
73 const char __user *user_buf, \
74 size_t count, loff_t *ppos) \
75{ \
76 argtype *arg = file->private_data; \
77 char buf[buflen] = {}; \
78 size_t buf_size = min(count, sizeof(buf) - 1); \
79 \
80 if (copy_from_user(buf, user_buf, buf_size)) \
81 return -EFAULT; \
82 \
83 return iwl_dbgfs_##name##_write(arg, buf, buf_size, ppos); \
84} \
85
86#define _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, buflen, argtype) \
87MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \
88static const struct file_operations iwl_dbgfs_##name##_ops = { \
89 .write = _iwl_dbgfs_##name##_write, \
90 .read = iwl_dbgfs_##name##_read, \
91 .open = simple_open, \
92 .llseek = generic_file_llseek, \
93};
94
95#define _MVM_DEBUGFS_WRITE_FILE_OPS(name, buflen, argtype) \
96MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \
97static const struct file_operations iwl_dbgfs_##name##_ops = { \
98 .write = _iwl_dbgfs_##name##_write, \
99 .open = simple_open, \
100 .llseek = generic_file_llseek, \
101};
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
index 4ea5e24ca92d..1b4e54d416b0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -127,6 +127,7 @@ enum iwl_bt_coex_valid_bit_msk {
127 BT_VALID_ANT_ISOLATION_THRS = BIT(15), 127 BT_VALID_ANT_ISOLATION_THRS = BIT(15),
128 BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16), 128 BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16),
129 BT_VALID_TXRX_MAX_FREQ_0 = BIT(17), 129 BT_VALID_TXRX_MAX_FREQ_0 = BIT(17),
130 BT_VALID_SYNC_TO_SCO = BIT(18),
130}; 131};
131 132
132/** 133/**
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
index 4e7dd8cf87dc..8415ff312d0e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
index 39c3148bdfa8..c405cda1025f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index 5cb93ae5cd2f..884c08725308 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -85,6 +85,8 @@
85 * PBW Snoozing enabled 85 * PBW Snoozing enabled
86 * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask 86 * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask
87 * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable. 87 * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable.
88 * @POWER_FLAGS_AP_UAPSD_MISBEHAVING_ENA_MSK: AP/GO's uAPSD misbehaving
89 * detection enablement
88*/ 90*/
89enum iwl_power_flags { 91enum iwl_power_flags {
90 POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0), 92 POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0),
@@ -94,6 +96,7 @@ enum iwl_power_flags {
94 POWER_FLAGS_BT_SCO_ENA = BIT(8), 96 POWER_FLAGS_BT_SCO_ENA = BIT(8),
95 POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(9), 97 POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(9),
96 POWER_FLAGS_LPRX_ENA_MSK = BIT(11), 98 POWER_FLAGS_LPRX_ENA_MSK = BIT(11),
99 POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK = BIT(12),
97}; 100};
98 101
99#define IWL_POWER_VEC_SIZE 5 102#define IWL_POWER_VEC_SIZE 5
@@ -228,6 +231,19 @@ struct iwl_mac_power_cmd {
228 u8 reserved; 231 u8 reserved;
229} __packed; 232} __packed;
230 233
234/*
235 * struct iwl_uapsd_misbehaving_ap_notif - FW sends this notification when
236 * associated AP is identified as improperly implementing uAPSD protocol.
237 * PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION = 0x78
238 * @sta_id: index of station in uCode's station table - associated AP ID in
239 * this context.
240 */
241struct iwl_uapsd_misbehaving_ap_notif {
242 __le32 sta_id;
243 u8 mac_id;
244 u8 reserved[3];
245} __packed;
246
231/** 247/**
232 * struct iwl_beacon_filter_cmd 248 * struct iwl_beacon_filter_cmd
233 * REPLY_BEACON_FILTERING_CMD = 0xd2 (command) 249 * REPLY_BEACON_FILTERING_CMD = 0xd2 (command)
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
index 538f1c7a5966..85057219cc43 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -281,8 +281,31 @@ enum {
281/* # entries in rate scale table to support Tx retries */ 281/* # entries in rate scale table to support Tx retries */
282#define LQ_MAX_RETRY_NUM 16 282#define LQ_MAX_RETRY_NUM 16
283 283
284/* Link quality command flags, only this one is available */ 284/* Link quality command flags bit fields */
285#define LQ_FLAG_SET_STA_TLC_RTS_MSK BIT(0) 285
286/* Bit 0: (0) Don't use RTS (1) Use RTS */
287#define LQ_FLAG_USE_RTS_POS 0
288#define LQ_FLAG_USE_RTS_MSK (1 << LQ_FLAG_USE_RTS_POS)
289
290/* Bit 1-3: LQ command color. Used to match responses to LQ commands */
291#define LQ_FLAG_COLOR_POS 1
292#define LQ_FLAG_COLOR_MSK (7 << LQ_FLAG_COLOR_POS)
293
294/* Bit 4-5: Tx RTS BW Signalling
295 * (0) No RTS BW signalling
296 * (1) Static BW signalling
297 * (2) Dynamic BW signalling
298 */
299#define LQ_FLAG_RTS_BW_SIG_POS 4
300#define LQ_FLAG_RTS_BW_SIG_NONE (0 << LQ_FLAG_RTS_BW_SIG_POS)
301#define LQ_FLAG_RTS_BW_SIG_STATIC (1 << LQ_FLAG_RTS_BW_SIG_POS)
302#define LQ_FLAG_RTS_BW_SIG_DYNAMIC (2 << LQ_FLAG_RTS_BW_SIG_POS)
303
304/* Bit 6: (0) No dynamic BW selection (1) Allow dynamic BW selection
305 * Dyanmic BW selection allows Tx with narrower BW then requested in rates
306 */
307#define LQ_FLAG_DYNAMIC_BW_POS 6
308#define LQ_FLAG_DYNAMIC_BW_MSK (1 << LQ_FLAG_DYNAMIC_BW_POS)
286 309
287/** 310/**
288 * struct iwl_lq_cmd - link quality command 311 * struct iwl_lq_cmd - link quality command
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index c3782b48ded1..73cbba7424f2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -530,14 +530,13 @@ struct iwl_scan_offload_schedule {
530/* 530/*
531 * iwl_scan_offload_flags 531 * iwl_scan_offload_flags
532 * 532 *
533 * IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID: filter mode - upload every beacon or match 533 * IWL_SCAN_OFFLOAD_FLAG_PASS_ALL: pass all results - no filtering.
534 * ssid list.
535 * IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL: add cached channels to partial scan. 534 * IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL: add cached channels to partial scan.
536 * IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN: use energy based scan before partial scan 535 * IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN: use energy based scan before partial scan
537 * on A band. 536 * on A band.
538 */ 537 */
539enum iwl_scan_offload_flags { 538enum iwl_scan_offload_flags {
540 IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID = BIT(0), 539 IWL_SCAN_OFFLOAD_FLAG_PASS_ALL = BIT(0),
541 IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL = BIT(2), 540 IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL = BIT(2),
542 IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN = BIT(3), 541 IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN = BIT(3),
543}; 542};
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
index 4aca5933a65d..1b60fdff6a56 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -97,9 +97,6 @@ enum iwl_sta_flags {
97 STA_FLG_FLG_ANT_B), 97 STA_FLG_FLG_ANT_B),
98 98
99 STA_FLG_PS = BIT(8), 99 STA_FLG_PS = BIT(8),
100 STA_FLG_INVALID = BIT(9),
101 STA_FLG_DLP_EN = BIT(10),
102 STA_FLG_SET_ALL_KEYS = BIT(11),
103 STA_FLG_DRAIN_FLOW = BIT(12), 100 STA_FLG_DRAIN_FLOW = BIT(12),
104 STA_FLG_PAN = BIT(13), 101 STA_FLG_PAN = BIT(13),
105 STA_FLG_CLASS_AUTH = BIT(14), 102 STA_FLG_CLASS_AUTH = BIT(14),
@@ -138,7 +135,14 @@ enum iwl_sta_flags {
138 135
139/** 136/**
140 * enum iwl_sta_key_flag - key flags for the ADD_STA host command 137 * enum iwl_sta_key_flag - key flags for the ADD_STA host command
141 * @STA_KEY_FLG_EN_MSK: mask for encryption algorithm 138 * @STA_KEY_FLG_NO_ENC: no encryption
139 * @STA_KEY_FLG_WEP: WEP encryption algorithm
140 * @STA_KEY_FLG_CCM: CCMP encryption algorithm
141 * @STA_KEY_FLG_TKIP: TKIP encryption algorithm
142 * @STA_KEY_FLG_EXT: extended cipher algorithm (depends on the FW support)
143 * @STA_KEY_FLG_CMAC: CMAC encryption algorithm
144 * @STA_KEY_FLG_ENC_UNKNOWN: unknown encryption algorithm
145 * @STA_KEY_FLG_EN_MSK: mask for encryption algorithmi value
142 * @STA_KEY_FLG_WEP_KEY_MAP: wep is either a group key (0 - legacy WEP) or from 146 * @STA_KEY_FLG_WEP_KEY_MAP: wep is either a group key (0 - legacy WEP) or from
143 * station info array (1 - n 1X mode) 147 * station info array (1 - n 1X mode)
144 * @STA_KEY_FLG_KEYID_MSK: the index of the key 148 * @STA_KEY_FLG_KEYID_MSK: the index of the key
@@ -152,6 +156,7 @@ enum iwl_sta_key_flag {
152 STA_KEY_FLG_WEP = (1 << 0), 156 STA_KEY_FLG_WEP = (1 << 0),
153 STA_KEY_FLG_CCM = (2 << 0), 157 STA_KEY_FLG_CCM = (2 << 0),
154 STA_KEY_FLG_TKIP = (3 << 0), 158 STA_KEY_FLG_TKIP = (3 << 0),
159 STA_KEY_FLG_EXT = (4 << 0),
155 STA_KEY_FLG_CMAC = (6 << 0), 160 STA_KEY_FLG_CMAC = (6 << 0),
156 STA_KEY_FLG_ENC_UNKNOWN = (7 << 0), 161 STA_KEY_FLG_ENC_UNKNOWN = (7 << 0),
157 STA_KEY_FLG_EN_MSK = (7 << 0), 162 STA_KEY_FLG_EN_MSK = (7 << 0),
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index d606197bde8f..b674c2a2b51c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -132,6 +132,7 @@ enum iwl_tx_flags {
132#define TX_CMD_SEC_WEP 0x01 132#define TX_CMD_SEC_WEP 0x01
133#define TX_CMD_SEC_CCM 0x02 133#define TX_CMD_SEC_CCM 0x02
134#define TX_CMD_SEC_TKIP 0x03 134#define TX_CMD_SEC_TKIP 0x03
135#define TX_CMD_SEC_EXT 0x04
135#define TX_CMD_SEC_MSK 0x07 136#define TX_CMD_SEC_MSK 0x07
136#define TX_CMD_SEC_WEP_KEY_IDX_POS 6 137#define TX_CMD_SEC_WEP_KEY_IDX_POS 6
137#define TX_CMD_SEC_WEP_KEY_IDX_MSK 0xc0 138#define TX_CMD_SEC_WEP_KEY_IDX_MSK 0xc0
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index bad5a552dd8d..989d7dbdca6c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -141,6 +141,7 @@ enum {
141 141
142 /* Power - legacy power table command */ 142 /* Power - legacy power table command */
143 POWER_TABLE_CMD = 0x77, 143 POWER_TABLE_CMD = 0x77,
144 PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION = 0x78,
144 145
145 /* Thermal Throttling*/ 146 /* Thermal Throttling*/
146 REPLY_THERMAL_MNG_BACKOFF = 0x7e, 147 REPLY_THERMAL_MNG_BACKOFF = 0x7e,
@@ -183,6 +184,7 @@ enum {
183 BT_PROFILE_NOTIFICATION = 0xce, 184 BT_PROFILE_NOTIFICATION = 0xce,
184 BT_COEX_CI = 0x5d, 185 BT_COEX_CI = 0x5d,
185 186
187 REPLY_SF_CFG_CMD = 0xd1,
186 REPLY_BEACON_FILTERING_CMD = 0xd2, 188 REPLY_BEACON_FILTERING_CMD = 0xd2,
187 189
188 REPLY_DEBUG_CMD = 0xf0, 190 REPLY_DEBUG_CMD = 0xf0,
@@ -1052,6 +1054,7 @@ enum iwl_mvm_rx_status {
1052 RX_MPDU_RES_STATUS_SEC_WEP_ENC = (1 << 8), 1054 RX_MPDU_RES_STATUS_SEC_WEP_ENC = (1 << 8),
1053 RX_MPDU_RES_STATUS_SEC_CCM_ENC = (2 << 8), 1055 RX_MPDU_RES_STATUS_SEC_CCM_ENC = (2 << 8),
1054 RX_MPDU_RES_STATUS_SEC_TKIP_ENC = (3 << 8), 1056 RX_MPDU_RES_STATUS_SEC_TKIP_ENC = (3 << 8),
1057 RX_MPDU_RES_STATUS_SEC_EXT_ENC = (4 << 8),
1055 RX_MPDU_RES_STATUS_SEC_CCM_CMAC_ENC = (6 << 8), 1058 RX_MPDU_RES_STATUS_SEC_CCM_CMAC_ENC = (6 << 8),
1056 RX_MPDU_RES_STATUS_SEC_ENC_ERR = (7 << 8), 1059 RX_MPDU_RES_STATUS_SEC_ENC_ERR = (7 << 8),
1057 RX_MPDU_RES_STATUS_SEC_ENC_MSK = (7 << 8), 1060 RX_MPDU_RES_STATUS_SEC_ENC_MSK = (7 << 8),
@@ -1131,6 +1134,7 @@ struct iwl_set_calib_default_cmd {
1131} __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */ 1134} __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */
1132 1135
1133#define MAX_PORT_ID_NUM 2 1136#define MAX_PORT_ID_NUM 2
1137#define MAX_MCAST_FILTERING_ADDRESSES 256
1134 1138
1135/** 1139/**
1136 * struct iwl_mcast_filter_cmd - configure multicast filter. 1140 * struct iwl_mcast_filter_cmd - configure multicast filter.
@@ -1363,4 +1367,65 @@ struct iwl_notif_statistics { /* STATISTICS_NTFY_API_S_VER_8 */
1363 struct mvm_statistics_general general; 1367 struct mvm_statistics_general general;
1364} __packed; 1368} __packed;
1365 1369
1370/***********************************
1371 * Smart Fifo API
1372 ***********************************/
1373/* Smart Fifo state */
1374enum iwl_sf_state {
1375 SF_LONG_DELAY_ON = 0, /* should never be called by driver */
1376 SF_FULL_ON,
1377 SF_UNINIT,
1378 SF_INIT_OFF,
1379 SF_HW_NUM_STATES
1380};
1381
1382/* Smart Fifo possible scenario */
1383enum iwl_sf_scenario {
1384 SF_SCENARIO_SINGLE_UNICAST,
1385 SF_SCENARIO_AGG_UNICAST,
1386 SF_SCENARIO_MULTICAST,
1387 SF_SCENARIO_BA_RESP,
1388 SF_SCENARIO_TX_RESP,
1389 SF_NUM_SCENARIO
1390};
1391
1392#define SF_TRANSIENT_STATES_NUMBER 2 /* SF_LONG_DELAY_ON and SF_FULL_ON */
1393#define SF_NUM_TIMEOUT_TYPES 2 /* Aging timer and Idle timer */
1394
1395/* smart FIFO default values */
1396#define SF_W_MARK_SISO 4096
1397#define SF_W_MARK_MIMO2 8192
1398#define SF_W_MARK_MIMO3 6144
1399#define SF_W_MARK_LEGACY 4096
1400#define SF_W_MARK_SCAN 4096
1401
1402/* SF Scenarios timers for FULL_ON state (aligned to 32 uSec) */
1403#define SF_SINGLE_UNICAST_IDLE_TIMER 320 /* 300 uSec */
1404#define SF_SINGLE_UNICAST_AGING_TIMER 2016 /* 2 mSec */
1405#define SF_AGG_UNICAST_IDLE_TIMER 320 /* 300 uSec */
1406#define SF_AGG_UNICAST_AGING_TIMER 2016 /* 2 mSec */
1407#define SF_MCAST_IDLE_TIMER 2016 /* 2 mSec */
1408#define SF_MCAST_AGING_TIMER 10016 /* 10 mSec */
1409#define SF_BA_IDLE_TIMER 320 /* 300 uSec */
1410#define SF_BA_AGING_TIMER 2016 /* 2 mSec */
1411#define SF_TX_RE_IDLE_TIMER 320 /* 300 uSec */
1412#define SF_TX_RE_AGING_TIMER 2016 /* 2 mSec */
1413
1414#define SF_LONG_DELAY_AGING_TIMER 1000000 /* 1 Sec */
1415
1416/**
1417 * Smart Fifo configuration command.
1418 * @state: smart fifo state, types listed in iwl_sf_sate.
1419 * @watermark: Minimum allowed availabe free space in RXF for transient state.
1420 * @long_delay_timeouts: aging and idle timer values for each scenario
1421 * in long delay state.
1422 * @full_on_timeouts: timer values for each scenario in full on state.
1423 */
1424struct iwl_sf_cfg_cmd {
1425 enum iwl_sf_state state;
1426 __le32 watermark[SF_TRANSIENT_STATES_NUMBER];
1427 __le32 long_delay_timeouts[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES];
1428 __le32 full_on_timeouts[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES];
1429} __packed; /* SF_CFG_API_S_VER_2 */
1430
1366#endif /* __fw_api_h__ */ 1431#endif /* __fw_api_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index 70e5297646b2..c03d39541f9e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -241,7 +241,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
241 241
242 lockdep_assert_held(&mvm->mutex); 242 lockdep_assert_held(&mvm->mutex);
243 243
244 if (mvm->init_ucode_complete) 244 if (WARN_ON_ONCE(mvm->init_ucode_complete))
245 return 0; 245 return 0;
246 246
247 iwl_init_notification_wait(&mvm->notif_wait, 247 iwl_init_notification_wait(&mvm->notif_wait,
@@ -287,7 +287,8 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
287 IWL_DEBUG_RF_KILL(mvm, 287 IWL_DEBUG_RF_KILL(mvm,
288 "jump over all phy activities due to RF kill\n"); 288 "jump over all phy activities due to RF kill\n");
289 iwl_remove_notification(&mvm->notif_wait, &calib_wait); 289 iwl_remove_notification(&mvm->notif_wait, &calib_wait);
290 return 1; 290 ret = 1;
291 goto out;
291 } 292 }
292 293
293 /* Send TX valid antennas before triggering calibrations */ 294 /* Send TX valid antennas before triggering calibrations */
@@ -319,9 +320,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
319error: 320error:
320 iwl_remove_notification(&mvm->notif_wait, &calib_wait); 321 iwl_remove_notification(&mvm->notif_wait, &calib_wait);
321out: 322out:
322 if (!iwlmvm_mod_params.init_dbg) { 323 if (iwlmvm_mod_params.init_dbg && !mvm->nvm_data) {
323 iwl_trans_stop_device(mvm->trans);
324 } else if (!mvm->nvm_data) {
325 /* we want to debug INIT and we have no NVM - fake */ 324 /* we want to debug INIT and we have no NVM - fake */
326 mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) + 325 mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) +
327 sizeof(struct ieee80211_channel) + 326 sizeof(struct ieee80211_channel) +
@@ -370,11 +369,16 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
370 ret = -ERFKILL; 369 ret = -ERFKILL;
371 goto error; 370 goto error;
372 } 371 }
373 /* should stop & start HW since that INIT image just loaded */ 372 if (!iwlmvm_mod_params.init_dbg) {
374 iwl_trans_stop_hw(mvm->trans, false); 373 /*
375 ret = iwl_trans_start_hw(mvm->trans); 374 * should stop and start HW since that INIT
376 if (ret) 375 * image just loaded
377 return ret; 376 */
377 iwl_trans_stop_device(mvm->trans);
378 ret = iwl_trans_start_hw(mvm->trans);
379 if (ret)
380 return ret;
381 }
378 } 382 }
379 383
380 if (iwlmvm_mod_params.init_dbg) 384 if (iwlmvm_mod_params.init_dbg)
@@ -386,6 +390,10 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
386 goto error; 390 goto error;
387 } 391 }
388 392
393 ret = iwl_mvm_sf_update(mvm, NULL, false);
394 if (ret)
395 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
396
389 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw)); 397 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
390 if (ret) 398 if (ret)
391 goto error; 399 goto error;
diff --git a/drivers/net/wireless/iwlwifi/mvm/led.c b/drivers/net/wireless/iwlwifi/mvm/led.c
index 2269a9e5cc67..6b4ea6bf8ffe 100644
--- a/drivers/net/wireless/iwlwifi/mvm/led.c
+++ b/drivers/net/wireless/iwlwifi/mvm/led.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -103,7 +103,7 @@ int iwl_mvm_leds_init(struct iwl_mvm *mvm)
103 return 0; 103 return 0;
104 default: 104 default:
105 return -EINVAL; 105 return -EINVAL;
106 }; 106 }
107 107
108 mvm->led.name = kasprintf(GFP_KERNEL, "%s-led", 108 mvm->led.name = kasprintf(GFP_KERNEL, "%s-led",
109 wiphy_name(mvm->hw->wiphy)); 109 wiphy_name(mvm->hw->wiphy));
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index f41f9b079831..ba723d50939a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -69,10 +69,10 @@
69#include "mvm.h" 69#include "mvm.h"
70 70
71const u8 iwl_mvm_ac_to_tx_fifo[] = { 71const u8 iwl_mvm_ac_to_tx_fifo[] = {
72 IWL_MVM_TX_FIFO_BK,
73 IWL_MVM_TX_FIFO_BE,
74 IWL_MVM_TX_FIFO_VI,
75 IWL_MVM_TX_FIFO_VO, 72 IWL_MVM_TX_FIFO_VO,
73 IWL_MVM_TX_FIFO_VI,
74 IWL_MVM_TX_FIFO_BE,
75 IWL_MVM_TX_FIFO_BK,
76}; 76};
77 77
78struct iwl_mvm_mac_iface_iterator_data { 78struct iwl_mvm_mac_iface_iterator_data {
@@ -85,35 +85,15 @@ struct iwl_mvm_mac_iface_iterator_data {
85 bool found_vif; 85 bool found_vif;
86}; 86};
87 87
88static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac, 88static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac,
89 struct ieee80211_vif *vif) 89 struct ieee80211_vif *vif)
90{ 90{
91 struct iwl_mvm_mac_iface_iterator_data *data = _data; 91 struct iwl_mvm_mac_iface_iterator_data *data = _data;
92 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 92 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
93 u32 ac;
94 93
95 /* Iterator may already find the interface being added -- skip it */ 94 /* Skip the interface for which we are trying to assign a tsf_id */
96 if (vif == data->vif) { 95 if (vif == data->vif)
97 data->found_vif = true;
98 return; 96 return;
99 }
100
101 /* Mark the queues used by the vif */
102 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
103 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
104 __set_bit(vif->hw_queue[ac], data->used_hw_queues);
105
106 if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
107 __set_bit(vif->cab_queue, data->used_hw_queues);
108
109 /*
110 * Mark MAC IDs as used by clearing the available bit, and
111 * (below) mark TSFs as used if their existing use is not
112 * compatible with the new interface type.
113 * No locking or atomic bit operations are needed since the
114 * data is on the stack of the caller function.
115 */
116 __clear_bit(mvmvif->id, data->available_mac_ids);
117 97
118 /* 98 /*
119 * The TSF is a hardware/firmware resource, there are 4 and 99 * The TSF is a hardware/firmware resource, there are 4 and
@@ -135,21 +115,26 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
135 case NL80211_IFTYPE_STATION: 115 case NL80211_IFTYPE_STATION:
136 /* 116 /*
137 * The new interface is client, so if the existing one 117 * The new interface is client, so if the existing one
138 * we're iterating is an AP, the TSF should be used to 118 * we're iterating is an AP, and both interfaces have the
119 * same beacon interval, the same TSF should be used to
139 * avoid drift between the new client and existing AP, 120 * avoid drift between the new client and existing AP,
140 * the existing AP will get drift updates from the new 121 * the existing AP will get drift updates from the new
141 * client context in this case 122 * client context in this case
142 */ 123 */
143 if (vif->type == NL80211_IFTYPE_AP) { 124 if (vif->type == NL80211_IFTYPE_AP) {
144 if (data->preferred_tsf == NUM_TSF_IDS && 125 if (data->preferred_tsf == NUM_TSF_IDS &&
145 test_bit(mvmvif->tsf_id, data->available_tsf_ids)) 126 test_bit(mvmvif->tsf_id, data->available_tsf_ids) &&
127 (vif->bss_conf.beacon_int ==
128 data->vif->bss_conf.beacon_int)) {
146 data->preferred_tsf = mvmvif->tsf_id; 129 data->preferred_tsf = mvmvif->tsf_id;
147 return; 130 return;
131 }
148 } 132 }
149 break; 133 break;
150 case NL80211_IFTYPE_AP: 134 case NL80211_IFTYPE_AP:
151 /* 135 /*
152 * The new interface is AP/GO, so should get drift 136 * The new interface is AP/GO, so in case both interfaces
137 * have the same beacon interval, it should get drift
153 * updates from an existing client or use the same 138 * updates from an existing client or use the same
154 * TSF as an existing GO. There's no drift between 139 * TSF as an existing GO. There's no drift between
155 * TSFs internally but if they used different TSFs 140 * TSFs internally but if they used different TSFs
@@ -159,9 +144,12 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
159 if (vif->type == NL80211_IFTYPE_STATION || 144 if (vif->type == NL80211_IFTYPE_STATION ||
160 vif->type == NL80211_IFTYPE_AP) { 145 vif->type == NL80211_IFTYPE_AP) {
161 if (data->preferred_tsf == NUM_TSF_IDS && 146 if (data->preferred_tsf == NUM_TSF_IDS &&
162 test_bit(mvmvif->tsf_id, data->available_tsf_ids)) 147 test_bit(mvmvif->tsf_id, data->available_tsf_ids) &&
148 (vif->bss_conf.beacon_int ==
149 data->vif->bss_conf.beacon_int)) {
163 data->preferred_tsf = mvmvif->tsf_id; 150 data->preferred_tsf = mvmvif->tsf_id;
164 return; 151 return;
152 }
165 } 153 }
166 break; 154 break;
167 default: 155 default:
@@ -187,6 +175,39 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
187 data->preferred_tsf = NUM_TSF_IDS; 175 data->preferred_tsf = NUM_TSF_IDS;
188} 176}
189 177
178static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
179 struct ieee80211_vif *vif)
180{
181 struct iwl_mvm_mac_iface_iterator_data *data = _data;
182 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
183 u32 ac;
184
185 /* Iterator may already find the interface being added -- skip it */
186 if (vif == data->vif) {
187 data->found_vif = true;
188 return;
189 }
190
191 /* Mark the queues used by the vif */
192 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
193 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
194 __set_bit(vif->hw_queue[ac], data->used_hw_queues);
195
196 if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
197 __set_bit(vif->cab_queue, data->used_hw_queues);
198
199 /* Mark MAC IDs as used by clearing the available bit, and
200 * (below) mark TSFs as used if their existing use is not
201 * compatible with the new interface type.
202 * No locking or atomic bit operations are needed since the
203 * data is on the stack of the caller function.
204 */
205 __clear_bit(mvmvif->id, data->available_mac_ids);
206
207 /* find a suitable tsf_id */
208 iwl_mvm_mac_tsf_id_iter(_data, mac, vif);
209}
210
190/* 211/*
191 * Get the mask of the queus used by the vif 212 * Get the mask of the queus used by the vif
192 */ 213 */
@@ -205,6 +226,29 @@ u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
205 return qmask; 226 return qmask;
206} 227}
207 228
229void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
230 struct ieee80211_vif *vif)
231{
232 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
233 struct iwl_mvm_mac_iface_iterator_data data = {
234 .mvm = mvm,
235 .vif = vif,
236 .available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 },
237 /* no preference yet */
238 .preferred_tsf = NUM_TSF_IDS,
239 };
240
241 ieee80211_iterate_active_interfaces_atomic(
242 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
243 iwl_mvm_mac_tsf_id_iter, &data);
244
245 if (data.preferred_tsf != NUM_TSF_IDS)
246 mvmvif->tsf_id = data.preferred_tsf;
247 else if (!test_bit(mvmvif->tsf_id, data.available_tsf_ids))
248 mvmvif->tsf_id = find_first_bit(data.available_tsf_ids,
249 NUM_TSF_IDS);
250}
251
208static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, 252static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
209 struct ieee80211_vif *vif) 253 struct ieee80211_vif *vif)
210{ 254{
@@ -488,6 +532,40 @@ static void iwl_mvm_ack_rates(struct iwl_mvm *mvm,
488 *ofdm_rates = ofdm; 532 *ofdm_rates = ofdm;
489} 533}
490 534
535static void iwl_mvm_mac_ctxt_set_ht_flags(struct iwl_mvm *mvm,
536 struct ieee80211_vif *vif,
537 struct iwl_mac_ctx_cmd *cmd)
538{
539 /* for both sta and ap, ht_operation_mode hold the protection_mode */
540 u8 protection_mode = vif->bss_conf.ht_operation_mode &
541 IEEE80211_HT_OP_MODE_PROTECTION;
542 /* The fw does not distinguish between ht and fat */
543 u32 ht_flag = MAC_PROT_FLG_HT_PROT | MAC_PROT_FLG_FAT_PROT;
544
545 IWL_DEBUG_RATE(mvm, "protection mode set to %d\n", protection_mode);
546 /*
547 * See section 9.23.3.1 of IEEE 80211-2012.
548 * Nongreenfield HT STAs Present is not supported.
549 */
550 switch (protection_mode) {
551 case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
552 break;
553 case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
554 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
555 cmd->protection_flags |= cpu_to_le32(ht_flag);
556 break;
557 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
558 /* Protect when channel wider than 20MHz */
559 if (vif->bss_conf.chandef.width > NL80211_CHAN_WIDTH_20)
560 cmd->protection_flags |= cpu_to_le32(ht_flag);
561 break;
562 default:
563 IWL_ERR(mvm, "Illegal protection mode %d\n",
564 protection_mode);
565 break;
566 }
567}
568
491static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, 569static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
492 struct ieee80211_vif *vif, 570 struct ieee80211_vif *vif,
493 struct iwl_mac_ctx_cmd *cmd, 571 struct iwl_mac_ctx_cmd *cmd,
@@ -495,6 +573,8 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
495{ 573{
496 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 574 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
497 struct ieee80211_chanctx_conf *chanctx; 575 struct ieee80211_chanctx_conf *chanctx;
576 bool ht_enabled = !!(vif->bss_conf.ht_operation_mode &
577 IEEE80211_HT_OP_MODE_PROTECTION);
498 u8 cck_ack_rates, ofdm_ack_rates; 578 u8 cck_ack_rates, ofdm_ack_rates;
499 int i; 579 int i;
500 580
@@ -550,18 +630,23 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
550 cpu_to_le32(vif->bss_conf.use_short_slot ? 630 cpu_to_le32(vif->bss_conf.use_short_slot ?
551 MAC_FLG_SHORT_SLOT : 0); 631 MAC_FLG_SHORT_SLOT : 0);
552 632
553 for (i = 0; i < AC_NUM; i++) { 633 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
554 cmd->ac[i].cw_min = cpu_to_le16(mvmvif->queue_params[i].cw_min); 634 u8 txf = iwl_mvm_ac_to_tx_fifo[i];
555 cmd->ac[i].cw_max = cpu_to_le16(mvmvif->queue_params[i].cw_max); 635
556 cmd->ac[i].aifsn = mvmvif->queue_params[i].aifs; 636 cmd->ac[txf].cw_min =
557 cmd->ac[i].edca_txop = 637 cpu_to_le16(mvmvif->queue_params[i].cw_min);
638 cmd->ac[txf].cw_max =
639 cpu_to_le16(mvmvif->queue_params[i].cw_max);
640 cmd->ac[txf].edca_txop =
558 cpu_to_le16(mvmvif->queue_params[i].txop * 32); 641 cpu_to_le16(mvmvif->queue_params[i].txop * 32);
559 cmd->ac[i].fifos_mask = BIT(iwl_mvm_ac_to_tx_fifo[i]); 642 cmd->ac[txf].aifsn = mvmvif->queue_params[i].aifs;
643 cmd->ac[txf].fifos_mask = BIT(txf);
560 } 644 }
561 645
562 /* in AP mode, the MCAST FIFO takes the EDCA params from VO */ 646 /* in AP mode, the MCAST FIFO takes the EDCA params from VO */
563 if (vif->type == NL80211_IFTYPE_AP) 647 if (vif->type == NL80211_IFTYPE_AP)
564 cmd->ac[AC_VO].fifos_mask |= BIT(IWL_MVM_TX_FIFO_MCAST); 648 cmd->ac[IWL_MVM_TX_FIFO_VO].fifos_mask |=
649 BIT(IWL_MVM_TX_FIFO_MCAST);
565 650
566 if (vif->bss_conf.qos) 651 if (vif->bss_conf.qos)
567 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); 652 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);
@@ -573,16 +658,13 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
573 cmd->protection_flags |= 658 cmd->protection_flags |=
574 cpu_to_le32(MAC_PROT_FLG_SELF_CTS_EN); 659 cpu_to_le32(MAC_PROT_FLG_SELF_CTS_EN);
575 } 660 }
576 661 IWL_DEBUG_RATE(mvm, "use_cts_prot %d, ht_operation_mode %d\n",
577 /* 662 vif->bss_conf.use_cts_prot,
578 * I think that we should enable these 2 flags regardless the HT PROT 663 vif->bss_conf.ht_operation_mode);
579 * fields in the HT IE, but I am not sure. Someone knows whom to ask?... 664 if (vif->bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
580 */
581 if (vif->bss_conf.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) {
582 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_TGN); 665 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_TGN);
583 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_HT_PROT | 666 if (ht_enabled)
584 MAC_PROT_FLG_FAT_PROT); 667 iwl_mvm_mac_ctxt_set_ht_flags(mvm, vif, cmd);
585 }
586 668
587 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP); 669 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP);
588} 670}
@@ -974,7 +1056,7 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
974 iwl_mvm_mac_ap_iterator, &data); 1056 iwl_mvm_mac_ap_iterator, &data);
975 1057
976 if (data.beacon_device_ts) { 1058 if (data.beacon_device_ts) {
977 u32 rand = (prandom_u32() % (80 - 20)) + 20; 1059 u32 rand = (prandom_u32() % (64 - 36)) + 36;
978 mvmvif->ap_beacon_time = data.beacon_device_ts + 1060 mvmvif->ap_beacon_time = data.beacon_device_ts +
979 ieee80211_tu_to_usec(data.beacon_int * rand / 1061 ieee80211_tu_to_usec(data.beacon_int * rand /
980 100); 1062 100);
@@ -1153,10 +1235,18 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
1153static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac, 1235static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac,
1154 struct ieee80211_vif *vif) 1236 struct ieee80211_vif *vif)
1155{ 1237{
1156 u16 *id = _data; 1238 struct iwl_missed_beacons_notif *missed_beacons = _data;
1157 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 1239 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1158 1240
1159 if (mvmvif->id == *id) 1241 if (mvmvif->id != (u16)le32_to_cpu(missed_beacons->mac_id))
1242 return;
1243
1244 /*
1245 * TODO: the threshold should be adjusted based on latency conditions,
1246 * and/or in case of a CS flow on one of the other AP vifs.
1247 */
1248 if (le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx) >
1249 IWL_MVM_MISSED_BEACONS_THRESHOLD)
1160 ieee80211_beacon_loss(vif); 1250 ieee80211_beacon_loss(vif);
1161} 1251}
1162 1252
@@ -1165,12 +1255,19 @@ int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
1165 struct iwl_device_cmd *cmd) 1255 struct iwl_device_cmd *cmd)
1166{ 1256{
1167 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1257 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1168 struct iwl_missed_beacons_notif *missed_beacons = (void *)pkt->data; 1258 struct iwl_missed_beacons_notif *mb = (void *)pkt->data;
1169 u16 id = (u16)le32_to_cpu(missed_beacons->mac_id); 1259
1260 IWL_DEBUG_INFO(mvm,
1261 "missed bcn mac_id=%u, consecutive=%u (%u, %u, %u)\n",
1262 le32_to_cpu(mb->mac_id),
1263 le32_to_cpu(mb->consec_missed_beacons),
1264 le32_to_cpu(mb->consec_missed_beacons_since_last_rx),
1265 le32_to_cpu(mb->num_recvd_beacons),
1266 le32_to_cpu(mb->num_expected_beacons));
1170 1267
1171 ieee80211_iterate_active_interfaces_atomic(mvm->hw, 1268 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
1172 IEEE80211_IFACE_ITER_NORMAL, 1269 IEEE80211_IFACE_ITER_NORMAL,
1173 iwl_mvm_beacon_loss_iterator, 1270 iwl_mvm_beacon_loss_iterator,
1174 &id); 1271 mb);
1175 return 0; 1272 return 0;
1176} 1273}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 74bc2c8af06d..c49b5073c251 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -199,9 +199,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
199 if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8) 199 if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8)
200 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); 200 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
201 201
202 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 202 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
203 WIPHY_FLAG_DISABLE_BEACON_HINTS | 203 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
204 WIPHY_FLAG_IBSS_RSN; 204 REGULATORY_DISABLE_BEACON_HINTS;
205 205
206 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations; 206 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
207 hw->wiphy->n_iface_combinations = 207 hw->wiphy->n_iface_combinations =
@@ -256,10 +256,17 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
256 } 256 }
257 257
258 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN | 258 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
259 NL80211_FEATURE_P2P_GO_OPPPS; 259 NL80211_FEATURE_P2P_GO_OPPPS |
260 NL80211_FEATURE_LOW_PRIORITY_SCAN;
260 261
261 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 262 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
262 263
264 /* currently FW API supports only one optional cipher scheme */
265 if (mvm->fw->cs[0].cipher) {
266 mvm->hw->n_cipher_schemes = 1;
267 mvm->hw->cipher_schemes = &mvm->fw->cs[0];
268 }
269
263#ifdef CONFIG_PM_SLEEP 270#ifdef CONFIG_PM_SLEEP
264 if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len && 271 if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
265 mvm->trans->ops->d3_suspend && 272 mvm->trans->ops->d3_suspend &&
@@ -398,7 +405,6 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
398static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) 405static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
399{ 406{
400 iwl_trans_stop_device(mvm->trans); 407 iwl_trans_stop_device(mvm->trans);
401 iwl_trans_stop_hw(mvm->trans, false);
402 408
403 mvm->scan_status = IWL_MVM_SCAN_NONE; 409 mvm->scan_status = IWL_MVM_SCAN_NONE;
404 410
@@ -470,7 +476,6 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
470 cancel_work_sync(&mvm->roc_done_wk); 476 cancel_work_sync(&mvm->roc_done_wk);
471 477
472 iwl_trans_stop_device(mvm->trans); 478 iwl_trans_stop_device(mvm->trans);
473 iwl_trans_stop_hw(mvm->trans, false);
474 479
475 iwl_mvm_async_handlers_purge(mvm); 480 iwl_mvm_async_handlers_purge(mvm);
476 /* async_handlers_list is empty and will stay empty: HW is stopped */ 481 /* async_handlers_list is empty and will stay empty: HW is stopped */
@@ -487,17 +492,6 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
487 cancel_work_sync(&mvm->async_handlers_wk); 492 cancel_work_sync(&mvm->async_handlers_wk);
488} 493}
489 494
490static void iwl_mvm_pm_disable_iterator(void *data, u8 *mac,
491 struct ieee80211_vif *vif)
492{
493 struct iwl_mvm *mvm = data;
494 int ret;
495
496 ret = iwl_mvm_power_disable(mvm, vif);
497 if (ret)
498 IWL_ERR(mvm, "failed to disable power management\n");
499}
500
501static void iwl_mvm_power_update_iterator(void *data, u8 *mac, 495static void iwl_mvm_power_update_iterator(void *data, u8 *mac,
502 struct ieee80211_vif *vif) 496 struct ieee80211_vif *vif)
503{ 497{
@@ -520,6 +514,20 @@ static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
520 return NULL; 514 return NULL;
521} 515}
522 516
517static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
518 s8 tx_power)
519{
520 /* FW is in charge of regulatory enforcement */
521 struct iwl_reduce_tx_power_cmd reduce_txpwr_cmd = {
522 .mac_context_id = iwl_mvm_vif_from_mac80211(vif)->id,
523 .pwr_restriction = cpu_to_le16(tx_power),
524 };
525
526 return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, CMD_SYNC,
527 sizeof(reduce_txpwr_cmd),
528 &reduce_txpwr_cmd);
529}
530
523static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, 531static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
524 struct ieee80211_vif *vif) 532 struct ieee80211_vif *vif)
525{ 533{
@@ -540,26 +548,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
540 if (ret) 548 if (ret)
541 goto out_unlock; 549 goto out_unlock;
542 550
543 /* 551 /* Counting number of interfaces is needed for legacy PM */
544 * TODO: remove this temporary code.
545 * Currently MVM FW supports power management only on single MAC.
546 * If new interface added, disable PM on existing interface.
547 * P2P device is a special case, since it is handled by FW similary to
548 * scan. If P2P deviced is added, PM remains enabled on existing
549 * interface.
550 * Note: the method below does not count the new interface being added
551 * at this moment.
552 */
553 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) 552 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
554 mvm->vif_count++; 553 mvm->vif_count++;
555 if (mvm->vif_count > 1) {
556 IWL_DEBUG_MAC80211(mvm,
557 "Disable power on existing interfaces\n");
558 ieee80211_iterate_active_interfaces_atomic(
559 mvm->hw,
560 IEEE80211_IFACE_ITER_NORMAL,
561 iwl_mvm_pm_disable_iterator, mvm);
562 }
563 554
564 /* 555 /*
565 * The AP binding flow can be done only after the beacon 556 * The AP binding flow can be done only after the beacon
@@ -590,11 +581,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
590 if (ret) 581 if (ret)
591 goto out_release; 582 goto out_release;
592 583
593 /* 584 iwl_mvm_power_disable(mvm, vif);
594 * Update power state on the new interface. Admittedly, based on
595 * mac80211 logics this power update will disable power management
596 */
597 iwl_mvm_power_update_mode(mvm, vif);
598 585
599 /* beacon filtering */ 586 /* beacon filtering */
600 ret = iwl_mvm_disable_beacon_filter(mvm, vif); 587 ret = iwl_mvm_disable_beacon_filter(mvm, vif);
@@ -655,9 +642,12 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
655 out_release: 642 out_release:
656 if (vif->type != NL80211_IFTYPE_P2P_DEVICE) 643 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
657 mvm->vif_count--; 644 mvm->vif_count--;
645
646 /* TODO: remove this when legacy PM will be discarded */
658 ieee80211_iterate_active_interfaces( 647 ieee80211_iterate_active_interfaces(
659 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 648 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
660 iwl_mvm_power_update_iterator, mvm); 649 iwl_mvm_power_update_iterator, mvm);
650
661 iwl_mvm_mac_ctxt_release(mvm, vif); 651 iwl_mvm_mac_ctxt_release(mvm, vif);
662 out_unlock: 652 out_unlock:
663 mutex_unlock(&mvm->mutex); 653 mutex_unlock(&mvm->mutex);
@@ -743,21 +733,13 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
743 mvmvif->phy_ctxt = NULL; 733 mvmvif->phy_ctxt = NULL;
744 } 734 }
745 735
746 /*
747 * TODO: remove this temporary code.
748 * Currently MVM FW supports power management only on single MAC.
749 * Check if only one additional interface remains after removing
750 * current one. Update power mode on the remaining interface.
751 */
752 if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE) 736 if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE)
753 mvm->vif_count--; 737 mvm->vif_count--;
754 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", 738
755 mvm->vif_count); 739 /* TODO: remove this when legacy PM will be discarded */
756 if (mvm->vif_count == 1) { 740 ieee80211_iterate_active_interfaces(
757 ieee80211_iterate_active_interfaces( 741 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
758 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 742 iwl_mvm_power_update_iterator, mvm);
759 iwl_mvm_power_update_iterator, mvm);
760 }
761 743
762 iwl_mvm_mac_ctxt_remove(mvm, vif); 744 iwl_mvm_mac_ctxt_remove(mvm, vif);
763 745
@@ -766,23 +748,91 @@ out_release:
766 mutex_unlock(&mvm->mutex); 748 mutex_unlock(&mvm->mutex);
767} 749}
768 750
769static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 751static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed)
770 s8 tx_power)
771{ 752{
772 /* FW is in charge of regulatory enforcement */ 753 return 0;
773 struct iwl_reduce_tx_power_cmd reduce_txpwr_cmd = { 754}
774 .mac_context_id = iwl_mvm_vif_from_mac80211(vif)->id, 755
775 .pwr_restriction = cpu_to_le16(tx_power), 756struct iwl_mvm_mc_iter_data {
757 struct iwl_mvm *mvm;
758 int port_id;
759};
760
761static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac,
762 struct ieee80211_vif *vif)
763{
764 struct iwl_mvm_mc_iter_data *data = _data;
765 struct iwl_mvm *mvm = data->mvm;
766 struct iwl_mcast_filter_cmd *cmd = mvm->mcast_filter_cmd;
767 int ret, len;
768
769 /* if we don't have free ports, mcast frames will be dropped */
770 if (WARN_ON_ONCE(data->port_id >= MAX_PORT_ID_NUM))
771 return;
772
773 if (vif->type != NL80211_IFTYPE_STATION ||
774 !vif->bss_conf.assoc)
775 return;
776
777 cmd->port_id = data->port_id++;
778 memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
779 len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4);
780
781 ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC, len, cmd);
782 if (ret)
783 IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret);
784}
785
786static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm)
787{
788 struct iwl_mvm_mc_iter_data iter_data = {
789 .mvm = mvm,
776 }; 790 };
777 791
778 return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, CMD_SYNC, 792 lockdep_assert_held(&mvm->mutex);
779 sizeof(reduce_txpwr_cmd), 793
780 &reduce_txpwr_cmd); 794 if (WARN_ON_ONCE(!mvm->mcast_filter_cmd))
795 return;
796
797 ieee80211_iterate_active_interfaces(
798 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
799 iwl_mvm_mc_iface_iterator, &iter_data);
781} 800}
782 801
783static int iwl_mvm_mac_config(struct ieee80211_hw *hw, u32 changed) 802static u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw,
803 struct netdev_hw_addr_list *mc_list)
784{ 804{
785 return 0; 805 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
806 struct iwl_mcast_filter_cmd *cmd;
807 struct netdev_hw_addr *addr;
808 int addr_count = netdev_hw_addr_list_count(mc_list);
809 bool pass_all = false;
810 int len;
811
812 if (addr_count > MAX_MCAST_FILTERING_ADDRESSES) {
813 pass_all = true;
814 addr_count = 0;
815 }
816
817 len = roundup(sizeof(*cmd) + addr_count * ETH_ALEN, 4);
818 cmd = kzalloc(len, GFP_ATOMIC);
819 if (!cmd)
820 return 0;
821
822 if (pass_all) {
823 cmd->pass_all = 1;
824 return (u64)(unsigned long)cmd;
825 }
826
827 netdev_hw_addr_list_for_each(addr, mc_list) {
828 IWL_DEBUG_MAC80211(mvm, "mcast addr (%d): %pM\n",
829 cmd->count, addr->addr);
830 memcpy(&cmd->addr_list[cmd->count * ETH_ALEN],
831 addr->addr, ETH_ALEN);
832 cmd->count++;
833 }
834
835 return (u64)(unsigned long)cmd;
786} 836}
787 837
788static void iwl_mvm_configure_filter(struct ieee80211_hw *hw, 838static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
@@ -790,21 +840,22 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,
790 unsigned int *total_flags, 840 unsigned int *total_flags,
791 u64 multicast) 841 u64 multicast)
792{ 842{
793 *total_flags = 0; 843 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
794} 844 struct iwl_mcast_filter_cmd *cmd = (void *)(unsigned long)multicast;
795 845
796static int iwl_mvm_configure_mcast_filter(struct iwl_mvm *mvm, 846 mutex_lock(&mvm->mutex);
797 struct ieee80211_vif *vif)
798{
799 struct iwl_mcast_filter_cmd mcast_filter_cmd = {
800 .pass_all = 1,
801 };
802 847
803 memcpy(mcast_filter_cmd.bssid, vif->bss_conf.bssid, ETH_ALEN); 848 /* replace previous configuration */
849 kfree(mvm->mcast_filter_cmd);
850 mvm->mcast_filter_cmd = cmd;
804 851
805 return iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC, 852 if (!cmd)
806 sizeof(mcast_filter_cmd), 853 goto out;
807 &mcast_filter_cmd); 854
855 iwl_mvm_recalc_multicast(mvm);
856out:
857 mutex_unlock(&mvm->mutex);
858 *total_flags = 0;
808} 859}
809 860
810static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, 861static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
@@ -815,6 +866,14 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
815 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 866 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
816 int ret; 867 int ret;
817 868
869 /*
870 * Re-calculate the tsf id, as the master-slave relations depend on the
871 * beacon interval, which was not known when the station interface was
872 * added.
873 */
874 if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc)
875 iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
876
818 ret = iwl_mvm_mac_ctxt_changed(mvm, vif); 877 ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
819 if (ret) 878 if (ret)
820 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); 879 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
@@ -827,7 +886,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
827 IWL_ERR(mvm, "failed to update quotas\n"); 886 IWL_ERR(mvm, "failed to update quotas\n");
828 return; 887 return;
829 } 888 }
830 iwl_mvm_configure_mcast_filter(mvm, vif);
831 889
832 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, 890 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
833 &mvm->status)) { 891 &mvm->status)) {
@@ -849,7 +907,17 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
849 iwl_mvm_protect_session(mvm, vif, dur, dur, 907 iwl_mvm_protect_session(mvm, vif, dur, dur,
850 5 * dur); 908 5 * dur);
851 } 909 }
910
911 iwl_mvm_sf_update(mvm, vif, false);
912 iwl_mvm_power_vif_assoc(mvm, vif);
852 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { 913 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
914 /*
915 * If update fails - SF might be running in associated
916 * mode while disassociated - which is forbidden.
917 */
918 WARN_ONCE(iwl_mvm_sf_update(mvm, vif, false),
919 "Failed to update SF upon disassociation\n");
920
853 /* remove AP station now that the MAC is unassoc */ 921 /* remove AP station now that the MAC is unassoc */
854 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); 922 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
855 if (ret) 923 if (ret)
@@ -861,6 +929,8 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
861 IWL_ERR(mvm, "failed to update quotas\n"); 929 IWL_ERR(mvm, "failed to update quotas\n");
862 } 930 }
863 931
932 iwl_mvm_recalc_multicast(mvm);
933
864 /* reset rssi values */ 934 /* reset rssi values */
865 mvmvif->bf_data.ave_beacon_signal = 0; 935 mvmvif->bf_data.ave_beacon_signal = 0;
866 936
@@ -874,6 +944,8 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
874 IWL_ERR(mvm, "failed to update power mode\n"); 944 IWL_ERR(mvm, "failed to update power mode\n");
875 } 945 }
876 iwl_mvm_bt_coex_vif_change(mvm); 946 iwl_mvm_bt_coex_vif_change(mvm);
947 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT,
948 IEEE80211_SMPS_AUTOMATIC);
877 } else if (changes & BSS_CHANGED_BEACON_INFO) { 949 } else if (changes & BSS_CHANGED_BEACON_INFO) {
878 /* 950 /*
879 * We received a beacon _after_ association so 951 * We received a beacon _after_ association so
@@ -881,7 +953,8 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
881 */ 953 */
882 iwl_mvm_remove_time_event(mvm, mvmvif, 954 iwl_mvm_remove_time_event(mvm, mvmvif,
883 &mvmvif->time_event_data); 955 &mvmvif->time_event_data);
884 } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_QOS)) { 956 } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS |
957 BSS_CHANGED_QOS)) {
885 ret = iwl_mvm_power_update_mode(mvm, vif); 958 ret = iwl_mvm_power_update_mode(mvm, vif);
886 if (ret) 959 if (ret)
887 IWL_ERR(mvm, "failed to update power mode\n"); 960 IWL_ERR(mvm, "failed to update power mode\n");
@@ -916,6 +989,13 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
916 if (ret) 989 if (ret)
917 goto out_unlock; 990 goto out_unlock;
918 991
992 /*
993 * Re-calculate the tsf id, as the master-slave relations depend on the
994 * beacon interval, which was not known when the AP interface was added.
995 */
996 if (vif->type == NL80211_IFTYPE_AP)
997 iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
998
919 /* Add the mac context */ 999 /* Add the mac context */
920 ret = iwl_mvm_mac_ctxt_add(mvm, vif); 1000 ret = iwl_mvm_mac_ctxt_add(mvm, vif);
921 if (ret) 1001 if (ret)
@@ -934,9 +1014,16 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
934 if (ret) 1014 if (ret)
935 goto out_unbind; 1015 goto out_unbind;
936 1016
1017 /* must be set before quota calculations */
1018 mvmvif->ap_ibss_active = true;
1019
1020 /* power updated needs to be done before quotas */
1021 mvm->bound_vif_cnt++;
1022 iwl_mvm_power_update_binding(mvm, vif, true);
1023
937 ret = iwl_mvm_update_quotas(mvm, vif); 1024 ret = iwl_mvm_update_quotas(mvm, vif);
938 if (ret) 1025 if (ret)
939 goto out_rm_bcast; 1026 goto out_quota_failed;
940 1027
941 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ 1028 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
942 if (vif->p2p && mvm->p2p_device_vif) 1029 if (vif->p2p && mvm->p2p_device_vif)
@@ -947,7 +1034,10 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
947 mutex_unlock(&mvm->mutex); 1034 mutex_unlock(&mvm->mutex);
948 return 0; 1035 return 0;
949 1036
950out_rm_bcast: 1037out_quota_failed:
1038 mvm->bound_vif_cnt--;
1039 iwl_mvm_power_update_binding(mvm, vif, false);
1040 mvmvif->ap_ibss_active = false;
951 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta); 1041 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
952out_unbind: 1042out_unbind:
953 iwl_mvm_binding_remove_vif(mvm, vif); 1043 iwl_mvm_binding_remove_vif(mvm, vif);
@@ -979,6 +1069,10 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
979 iwl_mvm_update_quotas(mvm, NULL); 1069 iwl_mvm_update_quotas(mvm, NULL);
980 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta); 1070 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
981 iwl_mvm_binding_remove_vif(mvm, vif); 1071 iwl_mvm_binding_remove_vif(mvm, vif);
1072
1073 mvm->bound_vif_cnt--;
1074 iwl_mvm_power_update_binding(mvm, vif, false);
1075
982 iwl_mvm_mac_ctxt_remove(mvm, vif); 1076 iwl_mvm_mac_ctxt_remove(mvm, vif);
983 1077
984 mutex_unlock(&mvm->mutex); 1078 mutex_unlock(&mvm->mutex);
@@ -990,6 +1084,22 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
990 struct ieee80211_bss_conf *bss_conf, 1084 struct ieee80211_bss_conf *bss_conf,
991 u32 changes) 1085 u32 changes)
992{ 1086{
1087 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1088 enum ieee80211_bss_change ht_change = BSS_CHANGED_ERP_CTS_PROT |
1089 BSS_CHANGED_HT |
1090 BSS_CHANGED_BANDWIDTH;
1091 int ret;
1092
1093 /* Changes will be applied when the AP/IBSS is started */
1094 if (!mvmvif->ap_ibss_active)
1095 return;
1096
1097 if (changes & ht_change) {
1098 ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
1099 if (ret)
1100 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
1101 }
1102
993 /* Need to send a new beacon template to the FW */ 1103 /* Need to send a new beacon template to the FW */
994 if (changes & BSS_CHANGED_BEACON) { 1104 if (changes & BSS_CHANGED_BEACON) {
995 if (iwl_mvm_mac_ctxt_beacon_changed(mvm, vif)) 1105 if (iwl_mvm_mac_ctxt_beacon_changed(mvm, vif))
@@ -1080,7 +1190,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
1080 struct ieee80211_sta *sta) 1190 struct ieee80211_sta *sta)
1081{ 1191{
1082 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1192 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1083 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1193 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1084 1194
1085 switch (cmd) { 1195 switch (cmd) {
1086 case STA_NOTIFY_SLEEP: 1196 case STA_NOTIFY_SLEEP:
@@ -1102,6 +1212,28 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
1102 } 1212 }
1103} 1213}
1104 1214
1215static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
1216 struct ieee80211_vif *vif,
1217 struct ieee80211_sta *sta)
1218{
1219 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1220 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv;
1221
1222 /*
1223 * This is called before mac80211 does RCU synchronisation,
1224 * so here we already invalidate our internal RCU-protected
1225 * station pointer. The rest of the code will thus no longer
1226 * be able to find the station this way, and we don't rely
1227 * on further RCU synchronisation after the sta_state()
1228 * callback deleted the station.
1229 */
1230 mutex_lock(&mvm->mutex);
1231 if (sta == rcu_access_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id]))
1232 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
1233 ERR_PTR(-ENOENT));
1234 mutex_unlock(&mvm->mutex);
1235}
1236
1105static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, 1237static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
1106 struct ieee80211_vif *vif, 1238 struct ieee80211_vif *vif,
1107 struct ieee80211_sta *sta, 1239 struct ieee80211_sta *sta,
@@ -1149,7 +1281,8 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
1149 ret = iwl_mvm_update_sta(mvm, vif, sta); 1281 ret = iwl_mvm_update_sta(mvm, vif, sta);
1150 if (ret == 0) 1282 if (ret == 0)
1151 iwl_mvm_rs_rate_init(mvm, sta, 1283 iwl_mvm_rs_rate_init(mvm, sta,
1152 mvmvif->phy_ctxt->channel->band); 1284 mvmvif->phy_ctxt->channel->band,
1285 true);
1153 } else if (old_state == IEEE80211_STA_ASSOC && 1286 } else if (old_state == IEEE80211_STA_ASSOC &&
1154 new_state == IEEE80211_STA_AUTHORIZED) { 1287 new_state == IEEE80211_STA_AUTHORIZED) {
1155 /* enable beacon filtering */ 1288 /* enable beacon filtering */
@@ -1187,6 +1320,17 @@ static int iwl_mvm_mac_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1187 return 0; 1320 return 0;
1188} 1321}
1189 1322
1323static void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw,
1324 struct ieee80211_vif *vif,
1325 struct ieee80211_sta *sta, u32 changed)
1326{
1327 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1328
1329 if (vif->type == NL80211_IFTYPE_STATION &&
1330 changed & IEEE80211_RC_NSS_CHANGED)
1331 iwl_mvm_sf_update(mvm, vif, false);
1332}
1333
1190static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw, 1334static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,
1191 struct ieee80211_vif *vif, u16 ac, 1335 struct ieee80211_vif *vif, u16 ac,
1192 const struct ieee80211_tx_queue_params *params) 1336 const struct ieee80211_tx_queue_params *params)
@@ -1309,7 +1453,12 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1309 */ 1453 */
1310 return 0; 1454 return 0;
1311 default: 1455 default:
1312 return -EOPNOTSUPP; 1456 /* currently FW supports only one optional cipher scheme */
1457 if (hw->n_cipher_schemes &&
1458 hw->cipher_schemes->cipher == key->cipher)
1459 key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
1460 else
1461 return -EOPNOTSUPP;
1313 } 1462 }
1314 1463
1315 mutex_lock(&mvm->mutex); 1464 mutex_lock(&mvm->mutex);
@@ -1515,7 +1664,7 @@ static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
1515 goto out; 1664 goto out;
1516 } 1665 }
1517 1666
1518 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def, 1667 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->min_def,
1519 ctx->rx_chains_static, 1668 ctx->rx_chains_static,
1520 ctx->rx_chains_dynamic); 1669 ctx->rx_chains_dynamic);
1521 if (ret) { 1670 if (ret) {
@@ -1553,13 +1702,14 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
1553 if (WARN_ONCE((phy_ctxt->ref > 1) && 1702 if (WARN_ONCE((phy_ctxt->ref > 1) &&
1554 (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH | 1703 (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH |
1555 IEEE80211_CHANCTX_CHANGE_RX_CHAINS | 1704 IEEE80211_CHANCTX_CHANGE_RX_CHAINS |
1556 IEEE80211_CHANCTX_CHANGE_RADAR)), 1705 IEEE80211_CHANCTX_CHANGE_RADAR |
1706 IEEE80211_CHANCTX_CHANGE_MIN_WIDTH)),
1557 "Cannot change PHY. Ref=%d, changed=0x%X\n", 1707 "Cannot change PHY. Ref=%d, changed=0x%X\n",
1558 phy_ctxt->ref, changed)) 1708 phy_ctxt->ref, changed))
1559 return; 1709 return;
1560 1710
1561 mutex_lock(&mvm->mutex); 1711 mutex_lock(&mvm->mutex);
1562 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def, 1712 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->min_def,
1563 ctx->rx_chains_static, 1713 ctx->rx_chains_static,
1564 ctx->rx_chains_dynamic); 1714 ctx->rx_chains_dynamic);
1565 iwl_mvm_bt_coex_vif_change(mvm); 1715 iwl_mvm_bt_coex_vif_change(mvm);
@@ -1602,7 +1752,13 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1602 goto out_unlock; 1752 goto out_unlock;
1603 1753
1604 /* 1754 /*
1605 * Setting the quota at this stage is only required for monitor 1755 * Power state must be updated before quotas,
1756 * otherwise fw will complain.
1757 */
1758 mvm->bound_vif_cnt++;
1759 iwl_mvm_power_update_binding(mvm, vif, true);
1760
1761 /* Setting the quota at this stage is only required for monitor
1606 * interfaces. For the other types, the bss_info changed flow 1762 * interfaces. For the other types, the bss_info changed flow
1607 * will handle quota settings. 1763 * will handle quota settings.
1608 */ 1764 */
@@ -1617,6 +1773,8 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1617 1773
1618 out_remove_binding: 1774 out_remove_binding:
1619 iwl_mvm_binding_remove_vif(mvm, vif); 1775 iwl_mvm_binding_remove_vif(mvm, vif);
1776 mvm->bound_vif_cnt--;
1777 iwl_mvm_power_update_binding(mvm, vif, false);
1620 out_unlock: 1778 out_unlock:
1621 mutex_unlock(&mvm->mutex); 1779 mutex_unlock(&mvm->mutex);
1622 if (ret) 1780 if (ret)
@@ -1648,6 +1806,9 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
1648 } 1806 }
1649 1807
1650 iwl_mvm_binding_remove_vif(mvm, vif); 1808 iwl_mvm_binding_remove_vif(mvm, vif);
1809 mvm->bound_vif_cnt--;
1810 iwl_mvm_power_update_binding(mvm, vif, false);
1811
1651out_unlock: 1812out_unlock:
1652 mvmvif->phy_ctxt = NULL; 1813 mvmvif->phy_ctxt = NULL;
1653 mutex_unlock(&mvm->mutex); 1814 mutex_unlock(&mvm->mutex);
@@ -1744,14 +1905,17 @@ struct ieee80211_ops iwl_mvm_hw_ops = {
1744 .add_interface = iwl_mvm_mac_add_interface, 1905 .add_interface = iwl_mvm_mac_add_interface,
1745 .remove_interface = iwl_mvm_mac_remove_interface, 1906 .remove_interface = iwl_mvm_mac_remove_interface,
1746 .config = iwl_mvm_mac_config, 1907 .config = iwl_mvm_mac_config,
1908 .prepare_multicast = iwl_mvm_prepare_multicast,
1747 .configure_filter = iwl_mvm_configure_filter, 1909 .configure_filter = iwl_mvm_configure_filter,
1748 .bss_info_changed = iwl_mvm_bss_info_changed, 1910 .bss_info_changed = iwl_mvm_bss_info_changed,
1749 .hw_scan = iwl_mvm_mac_hw_scan, 1911 .hw_scan = iwl_mvm_mac_hw_scan,
1750 .cancel_hw_scan = iwl_mvm_mac_cancel_hw_scan, 1912 .cancel_hw_scan = iwl_mvm_mac_cancel_hw_scan,
1913 .sta_pre_rcu_remove = iwl_mvm_sta_pre_rcu_remove,
1751 .sta_state = iwl_mvm_mac_sta_state, 1914 .sta_state = iwl_mvm_mac_sta_state,
1752 .sta_notify = iwl_mvm_mac_sta_notify, 1915 .sta_notify = iwl_mvm_mac_sta_notify,
1753 .allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames, 1916 .allow_buffered_frames = iwl_mvm_mac_allow_buffered_frames,
1754 .set_rts_threshold = iwl_mvm_mac_set_rts_threshold, 1917 .set_rts_threshold = iwl_mvm_mac_set_rts_threshold,
1918 .sta_rc_update = iwl_mvm_sta_rc_update,
1755 .conf_tx = iwl_mvm_mac_conf_tx, 1919 .conf_tx = iwl_mvm_mac_conf_tx,
1756 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx, 1920 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
1757 .sched_scan_start = iwl_mvm_mac_sched_scan_start, 1921 .sched_scan_start = iwl_mvm_mac_sched_scan_start,
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index fed21ef4162d..e4ead86f06d6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -81,6 +81,7 @@
81#define IWL_MVM_MAX_ADDRESSES 5 81#define IWL_MVM_MAX_ADDRESSES 5
82/* RSSI offset for WkP */ 82/* RSSI offset for WkP */
83#define IWL_RSSI_OFFSET 50 83#define IWL_RSSI_OFFSET 50
84#define IWL_MVM_MISSED_BEACONS_THRESHOLD 8
84 85
85enum iwl_mvm_tx_fifo { 86enum iwl_mvm_tx_fifo {
86 IWL_MVM_TX_FIFO_BK = 0, 87 IWL_MVM_TX_FIFO_BK = 0,
@@ -163,6 +164,8 @@ struct iwl_mvm_power_ops {
163 struct ieee80211_vif *vif); 164 struct ieee80211_vif *vif);
164 int (*power_update_device_mode)(struct iwl_mvm *mvm); 165 int (*power_update_device_mode)(struct iwl_mvm *mvm);
165 int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 166 int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
167 void (*power_update_binding)(struct iwl_mvm *mvm,
168 struct ieee80211_vif *vif, bool assign);
166#ifdef CONFIG_IWLWIFI_DEBUGFS 169#ifdef CONFIG_IWLWIFI_DEBUGFS
167 int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 170 int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
168 char *buf, int bufsz); 171 char *buf, int bufsz);
@@ -181,6 +184,7 @@ enum iwl_dbgfs_pm_mask {
181 MVM_DEBUGFS_PM_LPRX_ENA = BIT(6), 184 MVM_DEBUGFS_PM_LPRX_ENA = BIT(6),
182 MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7), 185 MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7),
183 MVM_DEBUGFS_PM_SNOOZE_ENABLE = BIT(8), 186 MVM_DEBUGFS_PM_SNOOZE_ENABLE = BIT(8),
187 MVM_DEBUGFS_PM_UAPSD_MISBEHAVING = BIT(9),
184}; 188};
185 189
186struct iwl_dbgfs_pm { 190struct iwl_dbgfs_pm {
@@ -193,6 +197,7 @@ struct iwl_dbgfs_pm {
193 bool lprx_ena; 197 bool lprx_ena;
194 u32 lprx_rssi_threshold; 198 u32 lprx_rssi_threshold;
195 bool snooze_ena; 199 bool snooze_ena;
200 bool uapsd_misbehaving;
196 int mask; 201 int mask;
197}; 202};
198 203
@@ -269,8 +274,8 @@ struct iwl_mvm_vif_bf_data {
269 * @bcast_sta: station used for broadcast packets. Used by the following 274 * @bcast_sta: station used for broadcast packets. Used by the following
270 * vifs: P2P_DEVICE, GO and AP. 275 * vifs: P2P_DEVICE, GO and AP.
271 * @beacon_skb: the skb used to hold the AP/GO beacon template 276 * @beacon_skb: the skb used to hold the AP/GO beacon template
272 * @smps_requests: the requests of of differents parts of the driver, regard 277 * @smps_requests: the SMPS requests of differents parts of the driver,
273 the desired smps mode. 278 * combined on update to yield the overall request to mac80211.
274 */ 279 */
275struct iwl_mvm_vif { 280struct iwl_mvm_vif {
276 u16 id; 281 u16 id;
@@ -323,14 +328,19 @@ struct iwl_mvm_vif {
323#endif 328#endif
324 329
325#ifdef CONFIG_IWLWIFI_DEBUGFS 330#ifdef CONFIG_IWLWIFI_DEBUGFS
331 struct iwl_mvm *mvm;
326 struct dentry *dbgfs_dir; 332 struct dentry *dbgfs_dir;
327 struct dentry *dbgfs_slink; 333 struct dentry *dbgfs_slink;
328 void *dbgfs_data;
329 struct iwl_dbgfs_pm dbgfs_pm; 334 struct iwl_dbgfs_pm dbgfs_pm;
330 struct iwl_dbgfs_bf dbgfs_bf; 335 struct iwl_dbgfs_bf dbgfs_bf;
331#endif 336#endif
332 337
333 enum ieee80211_smps_mode smps_requests[NUM_IWL_MVM_SMPS_REQ]; 338 enum ieee80211_smps_mode smps_requests[NUM_IWL_MVM_SMPS_REQ];
339
340 /* FW identified misbehaving AP */
341 u8 uapsd_misbehaving_bssid[ETH_ALEN];
342
343 bool pm_prevented;
334}; 344};
335 345
336static inline struct iwl_mvm_vif * 346static inline struct iwl_mvm_vif *
@@ -479,6 +489,7 @@ struct iwl_mvm {
479 /* Scan status, cmd (pre-allocated) and auxiliary station */ 489 /* Scan status, cmd (pre-allocated) and auxiliary station */
480 enum iwl_scan_status scan_status; 490 enum iwl_scan_status scan_status;
481 struct iwl_scan_cmd *scan_cmd; 491 struct iwl_scan_cmd *scan_cmd;
492 struct iwl_mcast_filter_cmd *mcast_filter_cmd;
482 493
483 /* rx chain antennas set through debugfs for the scan command */ 494 /* rx chain antennas set through debugfs for the scan command */
484 u8 scan_rx_ant; 495 u8 scan_rx_ant;
@@ -489,11 +500,19 @@ struct iwl_mvm {
489 u8 scan_last_antenna_idx; /* to toggle TX between antennas */ 500 u8 scan_last_antenna_idx; /* to toggle TX between antennas */
490 u8 mgmt_last_antenna_idx; 501 u8 mgmt_last_antenna_idx;
491 502
503 /* last smart fifo state that was successfully sent to firmware */
504 enum iwl_sf_state sf_state;
505
492#ifdef CONFIG_IWLWIFI_DEBUGFS 506#ifdef CONFIG_IWLWIFI_DEBUGFS
493 struct dentry *debugfs_dir; 507 struct dentry *debugfs_dir;
494 u32 dbgfs_sram_offset, dbgfs_sram_len; 508 u32 dbgfs_sram_offset, dbgfs_sram_len;
495 bool disable_power_off; 509 bool disable_power_off;
496 bool disable_power_off_d3; 510 bool disable_power_off_d3;
511
512 struct debugfs_blob_wrapper nvm_hw_blob;
513 struct debugfs_blob_wrapper nvm_sw_blob;
514 struct debugfs_blob_wrapper nvm_calib_blob;
515 struct debugfs_blob_wrapper nvm_prod_blob;
497#endif 516#endif
498 517
499 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX]; 518 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
@@ -507,12 +526,6 @@ struct iwl_mvm {
507 */ 526 */
508 unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)]; 527 unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)];
509 528
510 /*
511 * This counter of created interfaces is referenced only in conjunction
512 * with FW limitation related to power management. Currently PM is
513 * supported only on a single interface.
514 * IMPORTANT: this variable counts all interfaces except P2P device.
515 */
516 u8 vif_count; 529 u8 vif_count;
517 530
518 /* -1 for always, 0 for never, >0 for that many times */ 531 /* -1 for always, 0 for never, >0 for that many times */
@@ -531,6 +544,7 @@ struct iwl_mvm {
531 bool store_d3_resume_sram; 544 bool store_d3_resume_sram;
532 void *d3_resume_sram; 545 void *d3_resume_sram;
533 u32 d3_test_pme_ptr; 546 u32 d3_test_pme_ptr;
547 struct ieee80211_vif *keep_vif;
534#endif 548#endif
535#endif 549#endif
536 550
@@ -554,6 +568,11 @@ struct iwl_mvm {
554 u8 aux_queue; 568 u8 aux_queue;
555 u8 first_agg_queue; 569 u8 first_agg_queue;
556 u8 last_agg_queue; 570 u8 last_agg_queue;
571
572 u8 bound_vif_cnt;
573
574 /* Indicate if device power save is allowed */
575 bool ps_prevented;
557}; 576};
558 577
559/* Extract MVM priv from op_mode and _hw */ 578/* Extract MVM priv from op_mode and _hw */
@@ -693,6 +712,8 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
693int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, 712int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
694 struct iwl_rx_cmd_buffer *rxb, 713 struct iwl_rx_cmd_buffer *rxb,
695 struct iwl_device_cmd *cmd); 714 struct iwl_device_cmd *cmd);
715void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
716 struct ieee80211_vif *vif);
696 717
697/* Bindings */ 718/* Bindings */
698int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 719int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -750,8 +771,7 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
750#endif /* CONFIG_IWLWIFI_DEBUGFS */ 771#endif /* CONFIG_IWLWIFI_DEBUGFS */
751 772
752/* rate scaling */ 773/* rate scaling */
753int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, 774int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init);
754 u8 flags, bool init);
755 775
756/* power managment */ 776/* power managment */
757static inline int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, 777static inline int iwl_mvm_power_update_mode(struct iwl_mvm *mvm,
@@ -773,6 +793,19 @@ static inline int iwl_mvm_power_update_device_mode(struct iwl_mvm *mvm)
773 return 0; 793 return 0;
774} 794}
775 795
796static inline void iwl_mvm_power_update_binding(struct iwl_mvm *mvm,
797 struct ieee80211_vif *vif,
798 bool assign)
799{
800 if (mvm->pm_ops->power_update_binding)
801 mvm->pm_ops->power_update_binding(mvm, vif, assign);
802}
803
804void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
805int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
806 struct iwl_rx_cmd_buffer *rxb,
807 struct iwl_device_cmd *cmd);
808
776#ifdef CONFIG_IWLWIFI_DEBUGFS 809#ifdef CONFIG_IWLWIFI_DEBUGFS
777static inline int iwl_mvm_power_dbgfs_read(struct iwl_mvm *mvm, 810static inline int iwl_mvm_power_dbgfs_read(struct iwl_mvm *mvm,
778 struct ieee80211_vif *vif, 811 struct ieee80211_vif *vif,
@@ -864,4 +897,8 @@ void iwl_mvm_tt_initialize(struct iwl_mvm *mvm);
864void iwl_mvm_tt_exit(struct iwl_mvm *mvm); 897void iwl_mvm_tt_exit(struct iwl_mvm *mvm);
865void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state); 898void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
866 899
900/* smart fifo */
901int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
902 bool added_vif);
903
867#endif /* __IWL_MVM_H__ */ 904#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 2beffd028b67..35b71af78d02 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -367,16 +367,17 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
367 break; 367 break;
368 } 368 }
369 369
370 if (WARN(section_id >= NVM_NUM_OF_SECTIONS,
371 "Invalid NVM section ID %d\n", section_id)) {
372 ret = -EINVAL;
373 break;
374 }
375
370 temp = kmemdup(file_sec->data, section_size, GFP_KERNEL); 376 temp = kmemdup(file_sec->data, section_size, GFP_KERNEL);
371 if (!temp) { 377 if (!temp) {
372 ret = -ENOMEM; 378 ret = -ENOMEM;
373 break; 379 break;
374 } 380 }
375 if (WARN_ON(section_id >= NVM_NUM_OF_SECTIONS)) {
376 IWL_ERR(mvm, "Invalid NVM section ID\n");
377 ret = -EINVAL;
378 break;
379 }
380 mvm->nvm_sections[section_id].data = temp; 381 mvm->nvm_sections[section_id].data = temp;
381 mvm->nvm_sections[section_id].length = section_size; 382 mvm->nvm_sections[section_id].length = section_size;
382 383
@@ -391,17 +392,16 @@ out:
391/* Loads the NVM data stored in mvm->nvm_sections into the NIC */ 392/* Loads the NVM data stored in mvm->nvm_sections into the NIC */
392int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm) 393int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
393{ 394{
394 int i, ret; 395 int i, ret = 0;
395 u16 section_id;
396 struct iwl_nvm_section *sections = mvm->nvm_sections; 396 struct iwl_nvm_section *sections = mvm->nvm_sections;
397 397
398 IWL_DEBUG_EEPROM(mvm->trans->dev, "'Write to NVM\n"); 398 IWL_DEBUG_EEPROM(mvm->trans->dev, "'Write to NVM\n");
399 399
400 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) { 400 for (i = 0; i < ARRAY_SIZE(mvm->nvm_sections); i++) {
401 section_id = nvm_to_read[i]; 401 if (!mvm->nvm_sections[i].data || !mvm->nvm_sections[i].length)
402 ret = iwl_nvm_write_section(mvm, section_id, 402 continue;
403 sections[section_id].data, 403 ret = iwl_nvm_write_section(mvm, i, sections[i].data,
404 sections[section_id].length); 404 sections[i].length);
405 if (ret < 0) { 405 if (ret < 0) {
406 IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret); 406 IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret);
407 break; 407 break;
@@ -443,6 +443,29 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
443 } 443 }
444 mvm->nvm_sections[section].data = temp; 444 mvm->nvm_sections[section].data = temp;
445 mvm->nvm_sections[section].length = ret; 445 mvm->nvm_sections[section].length = ret;
446
447#ifdef CONFIG_IWLWIFI_DEBUGFS
448 switch (section) {
449 case NVM_SECTION_TYPE_HW:
450 mvm->nvm_hw_blob.data = temp;
451 mvm->nvm_hw_blob.size = ret;
452 break;
453 case NVM_SECTION_TYPE_SW:
454 mvm->nvm_sw_blob.data = temp;
455 mvm->nvm_sw_blob.size = ret;
456 break;
457 case NVM_SECTION_TYPE_CALIBRATION:
458 mvm->nvm_calib_blob.data = temp;
459 mvm->nvm_calib_blob.size = ret;
460 break;
461 case NVM_SECTION_TYPE_PRODUCTION:
462 mvm->nvm_prod_blob.data = temp;
463 mvm->nvm_prod_blob.size = ret;
464 break;
465 default:
466 WARN(1, "section: %d", section);
467 }
468#endif
446 } 469 }
447 kfree(nvm_buffer); 470 kfree(nvm_buffer);
448 if (ret < 0) 471 if (ret < 0)
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index d86083c6f445..a3d43de342d7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -236,6 +236,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
236 false), 236 false),
237 237
238 RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false), 238 RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false),
239 RX_HANDLER(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION,
240 iwl_mvm_power_uapsd_misbehaving_ap_notif, false),
239}; 241};
240#undef RX_HANDLER 242#undef RX_HANDLER
241#define CMD(x) [x] = #x 243#define CMD(x) [x] = #x
@@ -307,10 +309,12 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
307 CMD(BT_PROFILE_NOTIFICATION), 309 CMD(BT_PROFILE_NOTIFICATION),
308 CMD(BT_CONFIG), 310 CMD(BT_CONFIG),
309 CMD(MCAST_FILTER_CMD), 311 CMD(MCAST_FILTER_CMD),
312 CMD(REPLY_SF_CFG_CMD),
310 CMD(REPLY_BEACON_FILTERING_CMD), 313 CMD(REPLY_BEACON_FILTERING_CMD),
311 CMD(REPLY_THERMAL_MNG_BACKOFF), 314 CMD(REPLY_THERMAL_MNG_BACKOFF),
312 CMD(MAC_PM_POWER_TABLE), 315 CMD(MAC_PM_POWER_TABLE),
313 CMD(BT_COEX_CI), 316 CMD(BT_COEX_CI),
317 CMD(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION),
314}; 318};
315#undef CMD 319#undef CMD
316 320
@@ -341,7 +345,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
341 345
342 op_mode = hw->priv; 346 op_mode = hw->priv;
343 op_mode->ops = &iwl_mvm_ops; 347 op_mode->ops = &iwl_mvm_ops;
344 op_mode->trans = trans;
345 348
346 mvm = IWL_OP_MODE_GET_MVM(op_mode); 349 mvm = IWL_OP_MODE_GET_MVM(op_mode);
347 mvm->dev = trans->dev; 350 mvm->dev = trans->dev;
@@ -359,6 +362,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
359 mvm->aux_queue = 11; 362 mvm->aux_queue = 11;
360 mvm->first_agg_queue = 12; 363 mvm->first_agg_queue = 12;
361 } 364 }
365 mvm->sf_state = SF_UNINIT;
362 366
363 mutex_init(&mvm->mutex); 367 mutex_init(&mvm->mutex);
364 spin_lock_init(&mvm->async_handlers_lock); 368 spin_lock_init(&mvm->async_handlers_lock);
@@ -424,7 +428,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
424 * there is no need to unnecessarily power up the NIC at driver load 428 * there is no need to unnecessarily power up the NIC at driver load
425 */ 429 */
426 if (iwlwifi_mod_params.nvm_file) { 430 if (iwlwifi_mod_params.nvm_file) {
427 iwl_nvm_init(mvm); 431 err = iwl_nvm_init(mvm);
432 if (err)
433 goto out_free;
428 } else { 434 } else {
429 err = iwl_trans_start_hw(mvm->trans); 435 err = iwl_trans_start_hw(mvm->trans);
430 if (err) 436 if (err)
@@ -432,16 +438,13 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
432 438
433 mutex_lock(&mvm->mutex); 439 mutex_lock(&mvm->mutex);
434 err = iwl_run_init_mvm_ucode(mvm, true); 440 err = iwl_run_init_mvm_ucode(mvm, true);
441 iwl_trans_stop_device(trans);
435 mutex_unlock(&mvm->mutex); 442 mutex_unlock(&mvm->mutex);
436 /* returns 0 if successful, 1 if success but in rfkill */ 443 /* returns 0 if successful, 1 if success but in rfkill */
437 if (err < 0 && !iwlmvm_mod_params.init_dbg) { 444 if (err < 0 && !iwlmvm_mod_params.init_dbg) {
438 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err); 445 IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err);
439 goto out_free; 446 goto out_free;
440 } 447 }
441
442 /* Stop the hw after the ALIVE and NVM has been read */
443 if (!iwlmvm_mod_params.init_dbg)
444 iwl_trans_stop_hw(mvm->trans, false);
445 } 448 }
446 449
447 scan_size = sizeof(struct iwl_scan_cmd) + 450 scan_size = sizeof(struct iwl_scan_cmd) +
@@ -470,11 +473,12 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
470 473
471 out_unregister: 474 out_unregister:
472 ieee80211_unregister_hw(mvm->hw); 475 ieee80211_unregister_hw(mvm->hw);
476 iwl_mvm_leds_exit(mvm);
473 out_free: 477 out_free:
474 iwl_phy_db_free(mvm->phy_db); 478 iwl_phy_db_free(mvm->phy_db);
475 kfree(mvm->scan_cmd); 479 kfree(mvm->scan_cmd);
476 if (!iwlwifi_mod_params.nvm_file) 480 if (!iwlwifi_mod_params.nvm_file)
477 iwl_trans_stop_hw(trans, true); 481 iwl_trans_op_mode_leave(trans);
478 ieee80211_free_hw(mvm->hw); 482 ieee80211_free_hw(mvm->hw);
479 return NULL; 483 return NULL;
480} 484}
@@ -491,12 +495,14 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
491 ieee80211_unregister_hw(mvm->hw); 495 ieee80211_unregister_hw(mvm->hw);
492 496
493 kfree(mvm->scan_cmd); 497 kfree(mvm->scan_cmd);
498 kfree(mvm->mcast_filter_cmd);
499 mvm->mcast_filter_cmd = NULL;
494 500
495#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS) 501#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS)
496 kfree(mvm->d3_resume_sram); 502 kfree(mvm->d3_resume_sram);
497#endif 503#endif
498 504
499 iwl_trans_stop_hw(mvm->trans, true); 505 iwl_trans_op_mode_leave(mvm->trans);
500 506
501 iwl_phy_db_free(mvm->phy_db); 507 iwl_phy_db_free(mvm->phy_db);
502 mvm->phy_db = NULL; 508 mvm->phy_db = NULL;
@@ -661,6 +667,8 @@ static void iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
661 else 667 else
662 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status); 668 clear_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
663 669
670 if (state && mvm->cur_ucode != IWL_UCODE_INIT)
671 iwl_trans_stop_device(mvm->trans);
664 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm)); 672 wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));
665} 673}
666 674
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index a8652ddd6bed..b7268c0b3333 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 550824aa84ea..d9eab3b7bb9f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -64,7 +64,6 @@
64#include <linux/kernel.h> 64#include <linux/kernel.h>
65#include <linux/module.h> 65#include <linux/module.h>
66#include <linux/slab.h> 66#include <linux/slab.h>
67#include <linux/init.h>
68 67
69#include <net/mac80211.h> 68#include <net/mac80211.h>
70 69
@@ -186,6 +185,92 @@ static void iwl_mvm_power_log(struct iwl_mvm *mvm,
186 } 185 }
187} 186}
188 187
188static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm,
189 struct ieee80211_vif *vif,
190 struct iwl_mac_power_cmd *cmd)
191{
192 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
193 enum ieee80211_ac_numbers ac;
194 bool tid_found = false;
195
196 for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_BK; ac++) {
197 if (!mvmvif->queue_params[ac].uapsd)
198 continue;
199
200 if (mvm->cur_ucode != IWL_UCODE_WOWLAN)
201 cmd->flags |=
202 cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK);
203
204 cmd->uapsd_ac_flags |= BIT(ac);
205
206 /* QNDP TID - the highest TID with no admission control */
207 if (!tid_found && !mvmvif->queue_params[ac].acm) {
208 tid_found = true;
209 switch (ac) {
210 case IEEE80211_AC_VO:
211 cmd->qndp_tid = 6;
212 break;
213 case IEEE80211_AC_VI:
214 cmd->qndp_tid = 5;
215 break;
216 case IEEE80211_AC_BE:
217 cmd->qndp_tid = 0;
218 break;
219 case IEEE80211_AC_BK:
220 cmd->qndp_tid = 1;
221 break;
222 }
223 }
224 }
225
226 if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)))
227 return;
228
229 cmd->flags |= cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK);
230
231 if (cmd->uapsd_ac_flags == (BIT(IEEE80211_AC_VO) |
232 BIT(IEEE80211_AC_VI) |
233 BIT(IEEE80211_AC_BE) |
234 BIT(IEEE80211_AC_BK))) {
235 cmd->flags |= cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK);
236 cmd->snooze_interval = cpu_to_le16(IWL_MVM_PS_SNOOZE_INTERVAL);
237 cmd->snooze_window = (mvm->cur_ucode == IWL_UCODE_WOWLAN) ?
238 cpu_to_le16(IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW) :
239 cpu_to_le16(IWL_MVM_PS_SNOOZE_WINDOW);
240 }
241
242 cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP;
243
244 if (mvm->cur_ucode == IWL_UCODE_WOWLAN || cmd->flags &
245 cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
246 cmd->rx_data_timeout_uapsd =
247 cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT);
248 cmd->tx_data_timeout_uapsd =
249 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
250 } else {
251 cmd->rx_data_timeout_uapsd =
252 cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT);
253 cmd->tx_data_timeout_uapsd =
254 cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT);
255 }
256
257 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
258 cmd->heavy_tx_thld_packets =
259 IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS;
260 cmd->heavy_rx_thld_packets =
261 IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS;
262 } else {
263 cmd->heavy_tx_thld_packets =
264 IWL_MVM_PS_HEAVY_TX_THLD_PACKETS;
265 cmd->heavy_rx_thld_packets =
266 IWL_MVM_PS_HEAVY_RX_THLD_PACKETS;
267 }
268 cmd->heavy_tx_thld_percentage =
269 IWL_MVM_PS_HEAVY_TX_THLD_PERCENT;
270 cmd->heavy_rx_thld_percentage =
271 IWL_MVM_PS_HEAVY_RX_THLD_PERCENT;
272}
273
189static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, 274static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
190 struct ieee80211_vif *vif, 275 struct ieee80211_vif *vif,
191 struct iwl_mac_power_cmd *cmd) 276 struct iwl_mac_power_cmd *cmd)
@@ -198,8 +283,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
198 bool radar_detect = false; 283 bool radar_detect = false;
199 struct iwl_mvm_vif *mvmvif __maybe_unused = 284 struct iwl_mvm_vif *mvmvif __maybe_unused =
200 iwl_mvm_vif_from_mac80211(vif); 285 iwl_mvm_vif_from_mac80211(vif);
201 enum ieee80211_ac_numbers ac; 286 bool allow_uapsd = true;
202 bool tid_found = false;
203 287
204 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, 288 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
205 mvmvif->color)); 289 mvmvif->color));
@@ -217,7 +301,8 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
217 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); 301 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
218 cmd->keep_alive_seconds = cpu_to_le16(keep_alive); 302 cmd->keep_alive_seconds = cpu_to_le16(keep_alive);
219 303
220 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) 304 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM ||
305 mvm->ps_prevented)
221 return; 306 return;
222 307
223 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); 308 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
@@ -227,7 +312,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
227 mvmvif->dbgfs_pm.disable_power_off) 312 mvmvif->dbgfs_pm.disable_power_off)
228 cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK); 313 cmd->flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
229#endif 314#endif
230 if (!vif->bss_conf.ps) 315 if (!vif->bss_conf.ps || mvmvif->pm_prevented)
231 return; 316 return;
232 317
233 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); 318 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
@@ -269,81 +354,24 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
269 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT); 354 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
270 } 355 }
271 356
272 for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_BK; ac++) { 357 if (!memcmp(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid,
273 if (!mvmvif->queue_params[ac].uapsd) 358 ETH_ALEN))
274 continue; 359 allow_uapsd = false;
275
276 if (mvm->cur_ucode != IWL_UCODE_WOWLAN)
277 cmd->flags |=
278 cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK);
279
280 cmd->uapsd_ac_flags |= BIT(ac);
281 360
282 /* QNDP TID - the highest TID with no admission control */ 361 if (vif->p2p &&
283 if (!tid_found && !mvmvif->queue_params[ac].acm) { 362 !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD))
284 tid_found = true; 363 allow_uapsd = false;
285 switch (ac) { 364 /*
286 case IEEE80211_AC_VO: 365 * Avoid using uAPSD if P2P client is associated to GO that uses
287 cmd->qndp_tid = 6; 366 * opportunistic power save. This is due to current FW limitation.
288 break; 367 */
289 case IEEE80211_AC_VI: 368 if (vif->p2p &&
290 cmd->qndp_tid = 5; 369 vif->bss_conf.p2p_noa_attr.oppps_ctwindow &
291 break; 370 IEEE80211_P2P_OPPPS_ENABLE_BIT)
292 case IEEE80211_AC_BE: 371 allow_uapsd = false;
293 cmd->qndp_tid = 0;
294 break;
295 case IEEE80211_AC_BK:
296 cmd->qndp_tid = 1;
297 break;
298 }
299 }
300 }
301
302 if (cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) {
303 if (cmd->uapsd_ac_flags == (BIT(IEEE80211_AC_VO) |
304 BIT(IEEE80211_AC_VI) |
305 BIT(IEEE80211_AC_BE) |
306 BIT(IEEE80211_AC_BK))) {
307 cmd->flags |= cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK);
308 cmd->snooze_interval =
309 cpu_to_le16(IWL_MVM_PS_SNOOZE_INTERVAL);
310 cmd->snooze_window =
311 (mvm->cur_ucode == IWL_UCODE_WOWLAN) ?
312 cpu_to_le16(IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW) :
313 cpu_to_le16(IWL_MVM_PS_SNOOZE_WINDOW);
314 }
315
316 cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP;
317
318 if (mvm->cur_ucode == IWL_UCODE_WOWLAN || cmd->flags &
319 cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
320 cmd->rx_data_timeout_uapsd =
321 cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT);
322 cmd->tx_data_timeout_uapsd =
323 cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
324 } else {
325 cmd->rx_data_timeout_uapsd =
326 cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT);
327 cmd->tx_data_timeout_uapsd =
328 cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT);
329 }
330 372
331 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { 373 if (allow_uapsd)
332 cmd->heavy_tx_thld_packets = 374 iwl_mvm_power_configure_uapsd(mvm, vif, cmd);
333 IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS;
334 cmd->heavy_rx_thld_packets =
335 IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS;
336 } else {
337 cmd->heavy_tx_thld_packets =
338 IWL_MVM_PS_HEAVY_TX_THLD_PACKETS;
339 cmd->heavy_rx_thld_packets =
340 IWL_MVM_PS_HEAVY_RX_THLD_PACKETS;
341 }
342 cmd->heavy_tx_thld_percentage =
343 IWL_MVM_PS_HEAVY_TX_THLD_PERCENT;
344 cmd->heavy_rx_thld_percentage =
345 IWL_MVM_PS_HEAVY_RX_THLD_PERCENT;
346 }
347 375
348#ifdef CONFIG_IWLWIFI_DEBUGFS 376#ifdef CONFIG_IWLWIFI_DEBUGFS
349 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE) 377 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_KEEP_ALIVE)
@@ -381,6 +409,13 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
381 cmd->flags &= 409 cmd->flags &=
382 cpu_to_le16(~POWER_FLAGS_SNOOZE_ENA_MSK); 410 cpu_to_le16(~POWER_FLAGS_SNOOZE_ENA_MSK);
383 } 411 }
412 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_UAPSD_MISBEHAVING) {
413 u16 flag = POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK;
414 if (mvmvif->dbgfs_pm.uapsd_misbehaving)
415 cmd->flags |= cpu_to_le16(flag);
416 else
417 cmd->flags &= cpu_to_le16(flag);
418 }
384#endif /* CONFIG_IWLWIFI_DEBUGFS */ 419#endif /* CONFIG_IWLWIFI_DEBUGFS */
385} 420}
386 421
@@ -391,18 +426,11 @@ static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm,
391 bool ba_enable; 426 bool ba_enable;
392 struct iwl_mac_power_cmd cmd = {}; 427 struct iwl_mac_power_cmd cmd = {};
393 428
394 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 429 if (vif->type != NL80211_IFTYPE_STATION)
395 return 0; 430 return 0;
396 431
397 /* 432 if (vif->p2p &&
398 * TODO: The following vif_count verification is temporary condition. 433 !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS))
399 * Avoid power mode update if more than one interface is currently
400 * active. Remove this condition when FW will support power management
401 * on multiple MACs.
402 */
403 IWL_DEBUG_POWER(mvm, "Currently %d interfaces active\n",
404 mvm->vif_count);
405 if (mvm->vif_count > 1)
406 return 0; 434 return 0;
407 435
408 iwl_mvm_power_build_cmd(mvm, vif, &cmd); 436 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
@@ -446,7 +474,7 @@ static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm,
446 sizeof(cmd), &cmd); 474 sizeof(cmd), &cmd);
447} 475}
448 476
449static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) 477static int _iwl_mvm_power_update_device(struct iwl_mvm *mvm, bool force_disable)
450{ 478{
451 struct iwl_device_power_cmd cmd = { 479 struct iwl_device_power_cmd cmd = {
452 .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK), 480 .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
@@ -455,7 +483,8 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
455 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) 483 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
456 return 0; 484 return 0;
457 485
458 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) 486 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM ||
487 force_disable)
459 cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK); 488 cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK);
460 489
461#ifdef CONFIG_IWLWIFI_DEBUGFS 490#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -472,6 +501,78 @@ static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
472 &cmd); 501 &cmd);
473} 502}
474 503
504static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
505{
506 return _iwl_mvm_power_update_device(mvm, false);
507}
508
509void iwl_mvm_power_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
510{
511 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
512
513 if (memcmp(vif->bss_conf.bssid, mvmvif->uapsd_misbehaving_bssid,
514 ETH_ALEN))
515 memset(mvmvif->uapsd_misbehaving_bssid, 0, ETH_ALEN);
516}
517
518static void iwl_mvm_power_uapsd_misbehav_ap_iterator(void *_data, u8 *mac,
519 struct ieee80211_vif *vif)
520{
521 u8 *ap_sta_id = _data;
522 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
523
524 /* The ap_sta_id is not expected to change during current association
525 * so no explicit protection is needed
526 */
527 if (mvmvif->ap_sta_id == *ap_sta_id)
528 memcpy(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid,
529 ETH_ALEN);
530}
531
532int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
533 struct iwl_rx_cmd_buffer *rxb,
534 struct iwl_device_cmd *cmd)
535{
536 struct iwl_rx_packet *pkt = rxb_addr(rxb);
537 struct iwl_uapsd_misbehaving_ap_notif *notif = (void *)pkt->data;
538 u8 ap_sta_id = le32_to_cpu(notif->sta_id);
539
540 ieee80211_iterate_active_interfaces_atomic(
541 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
542 iwl_mvm_power_uapsd_misbehav_ap_iterator, &ap_sta_id);
543
544 return 0;
545}
546
547static void iwl_mvm_power_binding_iterator(void *_data, u8 *mac,
548 struct ieee80211_vif *vif)
549{
550 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
551 struct iwl_mvm *mvm = _data;
552 int ret;
553
554 mvmvif->pm_prevented = (mvm->bound_vif_cnt <= 1) ? false : true;
555
556 ret = iwl_mvm_power_mac_update_mode(mvm, vif);
557 WARN_ONCE(ret, "Failed to update power parameters on a specific vif\n");
558}
559
560static void _iwl_mvm_power_update_binding(struct iwl_mvm *mvm,
561 struct ieee80211_vif *vif,
562 bool assign)
563{
564 if (vif->type == NL80211_IFTYPE_MONITOR) {
565 int ret = _iwl_mvm_power_update_device(mvm, assign);
566 mvm->ps_prevented = assign;
567 WARN_ONCE(ret, "Failed to update power device state\n");
568 }
569
570 ieee80211_iterate_active_interfaces(mvm->hw,
571 IEEE80211_IFACE_ITER_NORMAL,
572 iwl_mvm_power_binding_iterator,
573 mvm);
574}
575
475#ifdef CONFIG_IWLWIFI_DEBUGFS 576#ifdef CONFIG_IWLWIFI_DEBUGFS
476static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, 577static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm,
477 struct ieee80211_vif *vif, char *buf, 578 struct ieee80211_vif *vif, char *buf,
@@ -494,70 +595,58 @@ static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm,
494 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n", 595 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
495 le16_to_cpu(cmd.keep_alive_seconds)); 596 le16_to_cpu(cmd.keep_alive_seconds));
496 597
497 if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) { 598 if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)))
498 pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n", 599 return pos;
499 (cmd.flags & 600
500 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ? 601 pos += scnprintf(buf+pos, bufsz-pos, "skip_over_dtim = %d\n",
501 1 : 0); 602 (cmd.flags &
502 pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n", 603 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) ? 1 : 0);
503 cmd.skip_dtim_periods); 604 pos += scnprintf(buf+pos, bufsz-pos, "skip_dtim_periods = %d\n",
504 if (!(cmd.flags & 605 cmd.skip_dtim_periods);
505 cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) { 606 if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) {
506 pos += scnprintf(buf+pos, bufsz-pos, 607 pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout = %d\n",
507 "rx_data_timeout = %d\n", 608 le32_to_cpu(cmd.rx_data_timeout));
508 le32_to_cpu(cmd.rx_data_timeout)); 609 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
509 pos += scnprintf(buf+pos, bufsz-pos, 610 le32_to_cpu(cmd.tx_data_timeout));
510 "tx_data_timeout = %d\n",
511 le32_to_cpu(cmd.tx_data_timeout));
512 }
513 if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
514 pos += scnprintf(buf+pos, bufsz-pos,
515 "lprx_rssi_threshold = %d\n",
516 cmd.lprx_rssi_threshold);
517 if (cmd.flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) {
518 pos +=
519 scnprintf(buf+pos, bufsz-pos,
520 "rx_data_timeout_uapsd = %d\n",
521 le32_to_cpu(cmd.rx_data_timeout_uapsd));
522 pos +=
523 scnprintf(buf+pos, bufsz-pos,
524 "tx_data_timeout_uapsd = %d\n",
525 le32_to_cpu(cmd.tx_data_timeout_uapsd));
526 pos += scnprintf(buf+pos, bufsz-pos, "qndp_tid = %d\n",
527 cmd.qndp_tid);
528 pos += scnprintf(buf+pos, bufsz-pos,
529 "uapsd_ac_flags = 0x%x\n",
530 cmd.uapsd_ac_flags);
531 pos += scnprintf(buf+pos, bufsz-pos,
532 "uapsd_max_sp = %d\n",
533 cmd.uapsd_max_sp);
534 pos += scnprintf(buf+pos, bufsz-pos,
535 "heavy_tx_thld_packets = %d\n",
536 cmd.heavy_tx_thld_packets);
537 pos += scnprintf(buf+pos, bufsz-pos,
538 "heavy_rx_thld_packets = %d\n",
539 cmd.heavy_rx_thld_packets);
540 pos += scnprintf(buf+pos, bufsz-pos,
541 "heavy_tx_thld_percentage = %d\n",
542 cmd.heavy_tx_thld_percentage);
543 pos += scnprintf(buf+pos, bufsz-pos,
544 "heavy_rx_thld_percentage = %d\n",
545 cmd.heavy_rx_thld_percentage);
546 pos +=
547 scnprintf(buf+pos, bufsz-pos, "snooze_enable = %d\n",
548 (cmd.flags &
549 cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) ?
550 1 : 0);
551 }
552 if (cmd.flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
553 pos += scnprintf(buf+pos, bufsz-pos,
554 "snooze_interval = %d\n",
555 cmd.snooze_interval);
556 pos += scnprintf(buf+pos, bufsz-pos,
557 "snooze_window = %d\n",
558 cmd.snooze_window);
559 }
560 } 611 }
612 if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
613 pos += scnprintf(buf+pos, bufsz-pos,
614 "lprx_rssi_threshold = %d\n",
615 cmd.lprx_rssi_threshold);
616
617 if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)))
618 return pos;
619
620 pos += scnprintf(buf+pos, bufsz-pos, "rx_data_timeout_uapsd = %d\n",
621 le32_to_cpu(cmd.rx_data_timeout_uapsd));
622 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout_uapsd = %d\n",
623 le32_to_cpu(cmd.tx_data_timeout_uapsd));
624 pos += scnprintf(buf+pos, bufsz-pos, "qndp_tid = %d\n", cmd.qndp_tid);
625 pos += scnprintf(buf+pos, bufsz-pos, "uapsd_ac_flags = 0x%x\n",
626 cmd.uapsd_ac_flags);
627 pos += scnprintf(buf+pos, bufsz-pos, "uapsd_max_sp = %d\n",
628 cmd.uapsd_max_sp);
629 pos += scnprintf(buf+pos, bufsz-pos, "heavy_tx_thld_packets = %d\n",
630 cmd.heavy_tx_thld_packets);
631 pos += scnprintf(buf+pos, bufsz-pos, "heavy_rx_thld_packets = %d\n",
632 cmd.heavy_rx_thld_packets);
633 pos += scnprintf(buf+pos, bufsz-pos, "heavy_tx_thld_percentage = %d\n",
634 cmd.heavy_tx_thld_percentage);
635 pos += scnprintf(buf+pos, bufsz-pos, "heavy_rx_thld_percentage = %d\n",
636 cmd.heavy_rx_thld_percentage);
637 pos += scnprintf(buf+pos, bufsz-pos, "uapsd_misbehaving_enable = %d\n",
638 (cmd.flags &
639 cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK)) ?
640 1 : 0);
641
642 if (!(cmd.flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)))
643 return pos;
644
645 pos += scnprintf(buf+pos, bufsz-pos, "snooze_interval = %d\n",
646 cmd.snooze_interval);
647 pos += scnprintf(buf+pos, bufsz-pos, "snooze_window = %d\n",
648 cmd.snooze_window);
649
561 return pos; 650 return pos;
562} 651}
563 652
@@ -654,6 +743,7 @@ const struct iwl_mvm_power_ops pm_mac_ops = {
654 .power_update_mode = iwl_mvm_power_mac_update_mode, 743 .power_update_mode = iwl_mvm_power_mac_update_mode,
655 .power_update_device_mode = iwl_mvm_power_update_device, 744 .power_update_device_mode = iwl_mvm_power_update_device,
656 .power_disable = iwl_mvm_power_mac_disable, 745 .power_disable = iwl_mvm_power_mac_disable,
746 .power_update_binding = _iwl_mvm_power_update_binding,
657#ifdef CONFIG_IWLWIFI_DEBUGFS 747#ifdef CONFIG_IWLWIFI_DEBUGFS
658 .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read, 748 .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read,
659#endif 749#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/power_legacy.c b/drivers/net/wireless/iwlwifi/mvm/power_legacy.c
index 2ce79bad5845..ef712ae5bc62 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power_legacy.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power_legacy.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index 17e2bc827f9a..ce5db6c4ef7e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -217,8 +217,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
217 } else { 217 } else {
218 cmd.quotas[idx].quota = 218 cmd.quotas[idx].quota =
219 cpu_to_le32(quota * data.n_interfaces[i]); 219 cpu_to_le32(quota * data.n_interfaces[i]);
220 cmd.quotas[idx].max_duration = 220 cmd.quotas[idx].max_duration = cpu_to_le32(0);
221 cpu_to_le32(IWL_MVM_MAX_QUOTA);
222 } 221 }
223 idx++; 222 idx++;
224 } 223 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index a0b4cc8d9c3b..6abf74e1351f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -24,7 +24,6 @@
24 * 24 *
25 *****************************************************************************/ 25 *****************************************************************************/
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <linux/skbuff.h> 27#include <linux/skbuff.h>
29#include <linux/slab.h> 28#include <linux/slab.h>
30#include <net/mac80211.h> 29#include <net/mac80211.h>
@@ -42,33 +41,37 @@
42 41
43#define RS_NAME "iwl-mvm-rs" 42#define RS_NAME "iwl-mvm-rs"
44 43
45#define NUM_TRY_BEFORE_ANT_TOGGLE 1 44#define NUM_TRY_BEFORE_ANT_TOGGLE 1
46#define IWL_NUMBER_TRY 1 45#define RS_LEGACY_RETRIES_PER_RATE 1
47#define IWL_HT_NUMBER_TRY 3 46#define RS_HT_VHT_RETRIES_PER_RATE 2
47#define RS_HT_VHT_RETRIES_PER_RATE_TW 1
48#define RS_INITIAL_MIMO_NUM_RATES 3
49#define RS_INITIAL_SISO_NUM_RATES 3
50#define RS_INITIAL_LEGACY_NUM_RATES LINK_QUAL_MAX_RETRY_NUM
51#define RS_SECONDARY_LEGACY_NUM_RATES LINK_QUAL_MAX_RETRY_NUM
52#define RS_SECONDARY_SISO_NUM_RATES 3
53#define RS_SECONDARY_SISO_RETRIES 1
48 54
49#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */ 55#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */
50#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */ 56#define IWL_RATE_MIN_FAILURE_TH 3 /* min failures to calc tpt */
51#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */ 57#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */
52 58
53/* max allowed rate miss before sync LQ cmd */ 59/* max allowed rate miss before sync LQ cmd */
54#define IWL_MISSED_RATE_MAX 15 60#define IWL_MISSED_RATE_MAX 15
55/* max time to accum history 2 seconds */ 61#define RS_STAY_IN_COLUMN_TIMEOUT (5*HZ)
56#define IWL_RATE_SCALE_FLUSH_INTVL (3*HZ) 62
57 63
58static u8 rs_ht_to_legacy[] = { 64static u8 rs_ht_to_legacy[] = {
59 [IWL_RATE_1M_INDEX] = IWL_RATE_6M_INDEX, 65 [IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX,
60 [IWL_RATE_2M_INDEX] = IWL_RATE_6M_INDEX, 66 [IWL_RATE_MCS_1_INDEX] = IWL_RATE_9M_INDEX,
61 [IWL_RATE_5M_INDEX] = IWL_RATE_6M_INDEX, 67 [IWL_RATE_MCS_2_INDEX] = IWL_RATE_12M_INDEX,
62 [IWL_RATE_11M_INDEX] = IWL_RATE_6M_INDEX, 68 [IWL_RATE_MCS_3_INDEX] = IWL_RATE_18M_INDEX,
63 [IWL_RATE_6M_INDEX] = IWL_RATE_6M_INDEX, 69 [IWL_RATE_MCS_4_INDEX] = IWL_RATE_24M_INDEX,
64 [IWL_RATE_9M_INDEX] = IWL_RATE_6M_INDEX, 70 [IWL_RATE_MCS_5_INDEX] = IWL_RATE_36M_INDEX,
65 [IWL_RATE_12M_INDEX] = IWL_RATE_9M_INDEX, 71 [IWL_RATE_MCS_6_INDEX] = IWL_RATE_48M_INDEX,
66 [IWL_RATE_18M_INDEX] = IWL_RATE_12M_INDEX, 72 [IWL_RATE_MCS_7_INDEX] = IWL_RATE_54M_INDEX,
67 [IWL_RATE_24M_INDEX] = IWL_RATE_18M_INDEX, 73 [IWL_RATE_MCS_8_INDEX] = IWL_RATE_54M_INDEX,
68 [IWL_RATE_36M_INDEX] = IWL_RATE_24M_INDEX, 74 [IWL_RATE_MCS_9_INDEX] = IWL_RATE_54M_INDEX,
69 [IWL_RATE_48M_INDEX] = IWL_RATE_36M_INDEX,
70 [IWL_RATE_54M_INDEX] = IWL_RATE_48M_INDEX,
71 [IWL_RATE_60M_INDEX] = IWL_RATE_54M_INDEX,
72}; 75};
73 76
74static const u8 ant_toggle_lookup[] = { 77static const u8 ant_toggle_lookup[] = {
@@ -126,6 +129,196 @@ static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = {
126 IWL_DECLARE_MCS_RATE(9), /* MCS 9 */ 129 IWL_DECLARE_MCS_RATE(9), /* MCS 9 */
127}; 130};
128 131
132enum rs_action {
133 RS_ACTION_STAY = 0,
134 RS_ACTION_DOWNSCALE = -1,
135 RS_ACTION_UPSCALE = 1,
136};
137
138enum rs_column_mode {
139 RS_INVALID = 0,
140 RS_LEGACY,
141 RS_SISO,
142 RS_MIMO2,
143};
144
145#define MAX_NEXT_COLUMNS 5
146#define MAX_COLUMN_CHECKS 3
147
148typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm,
149 struct ieee80211_sta *sta,
150 struct iwl_scale_tbl_info *tbl);
151
152struct rs_tx_column {
153 enum rs_column_mode mode;
154 u8 ant;
155 bool sgi;
156 enum rs_column next_columns[MAX_NEXT_COLUMNS];
157 allow_column_func_t checks[MAX_COLUMN_CHECKS];
158};
159
160static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
161 struct iwl_scale_tbl_info *tbl)
162{
163 if (!sta->ht_cap.ht_supported)
164 return false;
165
166 if (sta->smps_mode == IEEE80211_SMPS_STATIC)
167 return false;
168
169 if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 2)
170 return false;
171
172 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
173 return false;
174
175 return true;
176}
177
178static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
179 struct iwl_scale_tbl_info *tbl)
180{
181 if (!sta->ht_cap.ht_supported)
182 return false;
183
184 return true;
185}
186
187static bool rs_sgi_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
188 struct iwl_scale_tbl_info *tbl)
189{
190 struct rs_rate *rate = &tbl->rate;
191 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
192 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
193
194 if (is_ht20(rate) && (ht_cap->cap &
195 IEEE80211_HT_CAP_SGI_20))
196 return true;
197 if (is_ht40(rate) && (ht_cap->cap &
198 IEEE80211_HT_CAP_SGI_40))
199 return true;
200 if (is_ht80(rate) && (vht_cap->cap &
201 IEEE80211_VHT_CAP_SHORT_GI_80))
202 return true;
203
204 return false;
205}
206
207static const struct rs_tx_column rs_tx_columns[] = {
208 [RS_COLUMN_LEGACY_ANT_A] = {
209 .mode = RS_LEGACY,
210 .ant = ANT_A,
211 .next_columns = {
212 RS_COLUMN_LEGACY_ANT_B,
213 RS_COLUMN_SISO_ANT_A,
214 RS_COLUMN_MIMO2,
215 RS_COLUMN_INVALID,
216 RS_COLUMN_INVALID,
217 },
218 },
219 [RS_COLUMN_LEGACY_ANT_B] = {
220 .mode = RS_LEGACY,
221 .ant = ANT_B,
222 .next_columns = {
223 RS_COLUMN_LEGACY_ANT_A,
224 RS_COLUMN_SISO_ANT_B,
225 RS_COLUMN_MIMO2,
226 RS_COLUMN_INVALID,
227 RS_COLUMN_INVALID,
228 },
229 },
230 [RS_COLUMN_SISO_ANT_A] = {
231 .mode = RS_SISO,
232 .ant = ANT_A,
233 .next_columns = {
234 RS_COLUMN_SISO_ANT_B,
235 RS_COLUMN_MIMO2,
236 RS_COLUMN_SISO_ANT_A_SGI,
237 RS_COLUMN_INVALID,
238 RS_COLUMN_INVALID,
239 },
240 .checks = {
241 rs_siso_allow,
242 },
243 },
244 [RS_COLUMN_SISO_ANT_B] = {
245 .mode = RS_SISO,
246 .ant = ANT_B,
247 .next_columns = {
248 RS_COLUMN_SISO_ANT_A,
249 RS_COLUMN_MIMO2,
250 RS_COLUMN_SISO_ANT_B_SGI,
251 RS_COLUMN_INVALID,
252 RS_COLUMN_INVALID,
253 },
254 .checks = {
255 rs_siso_allow,
256 },
257 },
258 [RS_COLUMN_SISO_ANT_A_SGI] = {
259 .mode = RS_SISO,
260 .ant = ANT_A,
261 .sgi = true,
262 .next_columns = {
263 RS_COLUMN_SISO_ANT_B_SGI,
264 RS_COLUMN_MIMO2_SGI,
265 RS_COLUMN_SISO_ANT_A,
266 RS_COLUMN_INVALID,
267 RS_COLUMN_INVALID,
268 },
269 .checks = {
270 rs_siso_allow,
271 rs_sgi_allow,
272 },
273 },
274 [RS_COLUMN_SISO_ANT_B_SGI] = {
275 .mode = RS_SISO,
276 .ant = ANT_B,
277 .sgi = true,
278 .next_columns = {
279 RS_COLUMN_SISO_ANT_A_SGI,
280 RS_COLUMN_MIMO2_SGI,
281 RS_COLUMN_SISO_ANT_B,
282 RS_COLUMN_INVALID,
283 RS_COLUMN_INVALID,
284 },
285 .checks = {
286 rs_siso_allow,
287 rs_sgi_allow,
288 },
289 },
290 [RS_COLUMN_MIMO2] = {
291 .mode = RS_MIMO2,
292 .ant = ANT_AB,
293 .next_columns = {
294 RS_COLUMN_SISO_ANT_A,
295 RS_COLUMN_MIMO2_SGI,
296 RS_COLUMN_INVALID,
297 RS_COLUMN_INVALID,
298 RS_COLUMN_INVALID,
299 },
300 .checks = {
301 rs_mimo_allow,
302 },
303 },
304 [RS_COLUMN_MIMO2_SGI] = {
305 .mode = RS_MIMO2,
306 .ant = ANT_AB,
307 .sgi = true,
308 .next_columns = {
309 RS_COLUMN_SISO_ANT_A_SGI,
310 RS_COLUMN_MIMO2,
311 RS_COLUMN_INVALID,
312 RS_COLUMN_INVALID,
313 RS_COLUMN_INVALID,
314 },
315 .checks = {
316 rs_mimo_allow,
317 rs_sgi_allow,
318 },
319 },
320};
321
129static inline u8 rs_extract_rate(u32 rate_n_flags) 322static inline u8 rs_extract_rate(u32 rate_n_flags)
130{ 323{
131 /* also works for HT because bits 7:6 are zero there */ 324 /* also works for HT because bits 7:6 are zero there */
@@ -163,28 +356,19 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
163 return idx; 356 return idx;
164 } 357 }
165 358
166 return -1; 359 return IWL_RATE_INVALID;
167} 360}
168 361
169static void rs_rate_scale_perform(struct iwl_mvm *mvm, 362static void rs_rate_scale_perform(struct iwl_mvm *mvm,
170 struct sk_buff *skb, 363 struct sk_buff *skb,
171 struct ieee80211_sta *sta, 364 struct ieee80211_sta *sta,
172 struct iwl_lq_sta *lq_sta); 365 struct iwl_lq_sta *lq_sta);
173static void rs_fill_link_cmd(struct iwl_mvm *mvm, 366static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
174 struct ieee80211_sta *sta, 367 struct ieee80211_sta *sta,
175 struct iwl_lq_sta *lq_sta, u32 rate_n_flags); 368 struct iwl_lq_sta *lq_sta,
369 const struct rs_rate *initial_rate);
176static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search); 370static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);
177 371
178
179#ifdef CONFIG_MAC80211_DEBUGFS
180static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
181 u32 *rate_n_flags);
182#else
183static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
184 u32 *rate_n_flags)
185{}
186#endif
187
188/** 372/**
189 * The following tables contain the expected throughput metrics for all rates 373 * The following tables contain the expected throughput metrics for all rates
190 * 374 *
@@ -264,6 +448,52 @@ static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
264 448
265#define MCS_INDEX_PER_STREAM (8) 449#define MCS_INDEX_PER_STREAM (8)
266 450
451static const char *rs_pretty_ant(u8 ant)
452{
453 static const char * const ant_name[] = {
454 [ANT_NONE] = "None",
455 [ANT_A] = "A",
456 [ANT_B] = "B",
457 [ANT_AB] = "AB",
458 [ANT_C] = "C",
459 [ANT_AC] = "AC",
460 [ANT_BC] = "BC",
461 [ANT_ABC] = "ABC",
462 };
463
464 if (ant > ANT_ABC)
465 return "UNKNOWN";
466
467 return ant_name[ant];
468}
469
470static const char *rs_pretty_lq_type(enum iwl_table_type type)
471{
472 static const char * const lq_types[] = {
473 [LQ_NONE] = "NONE",
474 [LQ_LEGACY_A] = "LEGACY_A",
475 [LQ_LEGACY_G] = "LEGACY_G",
476 [LQ_HT_SISO] = "HT SISO",
477 [LQ_HT_MIMO2] = "HT MIMO",
478 [LQ_VHT_SISO] = "VHT SISO",
479 [LQ_VHT_MIMO2] = "VHT MIMO",
480 };
481
482 if (type < LQ_NONE || type >= LQ_MAX)
483 return "UNKNOWN";
484
485 return lq_types[type];
486}
487
488static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate,
489 const char *prefix)
490{
491 IWL_DEBUG_RATE(mvm, "%s: (%s: %d) ANT: %s BW: %d SGI: %d\n",
492 prefix, rs_pretty_lq_type(rate->type),
493 rate->index, rs_pretty_ant(rate->ant),
494 rate->bw, rate->sgi);
495}
496
267static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) 497static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
268{ 498{
269 window->data = 0; 499 window->data = 0;
@@ -271,7 +501,6 @@ static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
271 window->success_ratio = IWL_INVALID_VALUE; 501 window->success_ratio = IWL_INVALID_VALUE;
272 window->counter = 0; 502 window->counter = 0;
273 window->average_tpt = IWL_INVALID_VALUE; 503 window->average_tpt = IWL_INVALID_VALUE;
274 window->stamp = 0;
275} 504}
276 505
277static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type) 506static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
@@ -279,30 +508,6 @@ static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
279 return (ant_type & valid_antenna) == ant_type; 508 return (ant_type & valid_antenna) == ant_type;
280} 509}
281 510
282#ifdef CONFIG_MAC80211_DEBUGFS
283/**
284 * Program the device to use fixed rate for frame transmit
285 * This is for debugging/testing only
286 * once the device start use fixed rate, we need to reload the module
287 * to being back the normal operation.
288 */
289static void rs_program_fix_rate(struct iwl_mvm *mvm,
290 struct iwl_lq_sta *lq_sta)
291{
292 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
293 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
294 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
295
296 IWL_DEBUG_RATE(mvm, "sta_id %d rate 0x%X\n",
297 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
298
299 if (lq_sta->dbg_fixed_rate) {
300 rs_fill_link_cmd(NULL, NULL, lq_sta, lq_sta->dbg_fixed_rate);
301 iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
302 }
303}
304#endif
305
306static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm, 511static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
307 struct iwl_lq_sta *lq_data, u8 tid, 512 struct iwl_lq_sta *lq_data, u8 tid,
308 struct ieee80211_sta *sta) 513 struct ieee80211_sta *sta)
@@ -428,192 +633,168 @@ static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
428 else 633 else
429 window->average_tpt = IWL_INVALID_VALUE; 634 window->average_tpt = IWL_INVALID_VALUE;
430 635
431 /* Tag this window as having been updated */
432 window->stamp = jiffies;
433
434 return 0; 636 return 0;
435} 637}
436 638
437/* 639/* Convert rs_rate object into ucode rate bitmask */
438 * Fill uCode API rate_n_flags field, based on "search" or "active" table. 640static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm,
439 */ 641 struct rs_rate *rate)
440/* FIXME:RS:remove this function and put the flags statically in the table */
441static u32 rate_n_flags_from_tbl(struct iwl_mvm *mvm,
442 struct iwl_scale_tbl_info *tbl, int index)
443{ 642{
444 u32 rate_n_flags = 0; 643 u32 ucode_rate = 0;
644 int index = rate->index;
445 645
446 rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) & 646 ucode_rate |= ((rate->ant << RATE_MCS_ANT_POS) &
447 RATE_MCS_ANT_ABC_MSK); 647 RATE_MCS_ANT_ABC_MSK);
448 648
449 if (is_legacy(tbl->lq_type)) { 649 if (is_legacy(rate)) {
450 rate_n_flags |= iwl_rates[index].plcp; 650 ucode_rate |= iwl_rates[index].plcp;
451 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) 651 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
452 rate_n_flags |= RATE_MCS_CCK_MSK; 652 ucode_rate |= RATE_MCS_CCK_MSK;
453 return rate_n_flags; 653 return ucode_rate;
454 } 654 }
455 655
456 if (is_ht(tbl->lq_type)) { 656 if (is_ht(rate)) {
457 if (index < IWL_FIRST_HT_RATE || index > IWL_LAST_HT_RATE) { 657 if (index < IWL_FIRST_HT_RATE || index > IWL_LAST_HT_RATE) {
458 IWL_ERR(mvm, "Invalid HT rate index %d\n", index); 658 IWL_ERR(mvm, "Invalid HT rate index %d\n", index);
459 index = IWL_LAST_HT_RATE; 659 index = IWL_LAST_HT_RATE;
460 } 660 }
461 rate_n_flags |= RATE_MCS_HT_MSK; 661 ucode_rate |= RATE_MCS_HT_MSK;
462 662
463 if (is_ht_siso(tbl->lq_type)) 663 if (is_ht_siso(rate))
464 rate_n_flags |= iwl_rates[index].plcp_ht_siso; 664 ucode_rate |= iwl_rates[index].plcp_ht_siso;
465 else if (is_ht_mimo2(tbl->lq_type)) 665 else if (is_ht_mimo2(rate))
466 rate_n_flags |= iwl_rates[index].plcp_ht_mimo2; 666 ucode_rate |= iwl_rates[index].plcp_ht_mimo2;
467 else 667 else
468 WARN_ON_ONCE(1); 668 WARN_ON_ONCE(1);
469 } else if (is_vht(tbl->lq_type)) { 669 } else if (is_vht(rate)) {
470 if (index < IWL_FIRST_VHT_RATE || index > IWL_LAST_VHT_RATE) { 670 if (index < IWL_FIRST_VHT_RATE || index > IWL_LAST_VHT_RATE) {
471 IWL_ERR(mvm, "Invalid VHT rate index %d\n", index); 671 IWL_ERR(mvm, "Invalid VHT rate index %d\n", index);
472 index = IWL_LAST_VHT_RATE; 672 index = IWL_LAST_VHT_RATE;
473 } 673 }
474 rate_n_flags |= RATE_MCS_VHT_MSK; 674 ucode_rate |= RATE_MCS_VHT_MSK;
475 if (is_vht_siso(tbl->lq_type)) 675 if (is_vht_siso(rate))
476 rate_n_flags |= iwl_rates[index].plcp_vht_siso; 676 ucode_rate |= iwl_rates[index].plcp_vht_siso;
477 else if (is_vht_mimo2(tbl->lq_type)) 677 else if (is_vht_mimo2(rate))
478 rate_n_flags |= iwl_rates[index].plcp_vht_mimo2; 678 ucode_rate |= iwl_rates[index].plcp_vht_mimo2;
479 else 679 else
480 WARN_ON_ONCE(1); 680 WARN_ON_ONCE(1);
481 681
482 } else { 682 } else {
483 IWL_ERR(mvm, "Invalid tbl->lq_type %d\n", tbl->lq_type); 683 IWL_ERR(mvm, "Invalid rate->type %d\n", rate->type);
484 } 684 }
485 685
486 rate_n_flags |= tbl->bw; 686 ucode_rate |= rate->bw;
487 if (tbl->is_SGI) 687 if (rate->sgi)
488 rate_n_flags |= RATE_MCS_SGI_MSK; 688 ucode_rate |= RATE_MCS_SGI_MSK;
489 689
490 return rate_n_flags; 690 return ucode_rate;
491} 691}
492 692
493/* 693/* Convert a ucode rate into an rs_rate object */
494 * Interpret uCode API's rate_n_flags format, 694static int rs_rate_from_ucode_rate(const u32 ucode_rate,
495 * fill "search" or "active" tx mode table. 695 enum ieee80211_band band,
496 */ 696 struct rs_rate *rate)
497static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
498 enum ieee80211_band band,
499 struct iwl_scale_tbl_info *tbl,
500 int *rate_idx)
501{ 697{
502 u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK); 698 u32 ant_msk = ucode_rate & RATE_MCS_ANT_ABC_MSK;
503 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags); 699 u8 num_of_ant = get_num_of_ant_from_rate(ucode_rate);
504 u8 nss; 700 u8 nss;
505 701
506 memset(tbl, 0, offsetof(struct iwl_scale_tbl_info, win)); 702 memset(rate, 0, sizeof(*rate));
507 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); 703 rate->index = iwl_hwrate_to_plcp_idx(ucode_rate);
508 704
509 if (*rate_idx == IWL_RATE_INVALID) { 705 if (rate->index == IWL_RATE_INVALID)
510 *rate_idx = -1;
511 return -EINVAL; 706 return -EINVAL;
512 } 707
513 tbl->is_SGI = 0; /* default legacy setup */ 708 rate->ant = (ant_msk >> RATE_MCS_ANT_POS);
514 tbl->bw = 0;
515 tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
516 tbl->lq_type = LQ_NONE;
517 tbl->max_search = IWL_MAX_SEARCH;
518 709
519 /* Legacy */ 710 /* Legacy */
520 if (!(rate_n_flags & RATE_MCS_HT_MSK) && 711 if (!(ucode_rate & RATE_MCS_HT_MSK) &&
521 !(rate_n_flags & RATE_MCS_VHT_MSK)) { 712 !(ucode_rate & RATE_MCS_VHT_MSK)) {
522 if (num_of_ant == 1) { 713 if (num_of_ant == 1) {
523 if (band == IEEE80211_BAND_5GHZ) 714 if (band == IEEE80211_BAND_5GHZ)
524 tbl->lq_type = LQ_LEGACY_A; 715 rate->type = LQ_LEGACY_A;
525 else 716 else
526 tbl->lq_type = LQ_LEGACY_G; 717 rate->type = LQ_LEGACY_G;
527 } 718 }
528 719
529 return 0; 720 return 0;
530 } 721 }
531 722
532 /* HT or VHT */ 723 /* HT or VHT */
533 if (rate_n_flags & RATE_MCS_SGI_MSK) 724 if (ucode_rate & RATE_MCS_SGI_MSK)
534 tbl->is_SGI = 1; 725 rate->sgi = true;
535 726
536 tbl->bw = rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK; 727 rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK;
537 728
538 if (rate_n_flags & RATE_MCS_HT_MSK) { 729 if (ucode_rate & RATE_MCS_HT_MSK) {
539 nss = ((rate_n_flags & RATE_HT_MCS_NSS_MSK) >> 730 nss = ((ucode_rate & RATE_HT_MCS_NSS_MSK) >>
540 RATE_HT_MCS_NSS_POS) + 1; 731 RATE_HT_MCS_NSS_POS) + 1;
541 732
542 if (nss == 1) { 733 if (nss == 1) {
543 tbl->lq_type = LQ_HT_SISO; 734 rate->type = LQ_HT_SISO;
544 WARN_ON_ONCE(num_of_ant != 1); 735 WARN_ON_ONCE(num_of_ant != 1);
545 } else if (nss == 2) { 736 } else if (nss == 2) {
546 tbl->lq_type = LQ_HT_MIMO2; 737 rate->type = LQ_HT_MIMO2;
547 WARN_ON_ONCE(num_of_ant != 2); 738 WARN_ON_ONCE(num_of_ant != 2);
548 } else { 739 } else {
549 WARN_ON_ONCE(1); 740 WARN_ON_ONCE(1);
550 } 741 }
551 } else if (rate_n_flags & RATE_MCS_VHT_MSK) { 742 } else if (ucode_rate & RATE_MCS_VHT_MSK) {
552 nss = ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> 743 nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >>
553 RATE_VHT_MCS_NSS_POS) + 1; 744 RATE_VHT_MCS_NSS_POS) + 1;
554 745
555 if (nss == 1) { 746 if (nss == 1) {
556 tbl->lq_type = LQ_VHT_SISO; 747 rate->type = LQ_VHT_SISO;
557 WARN_ON_ONCE(num_of_ant != 1); 748 WARN_ON_ONCE(num_of_ant != 1);
558 } else if (nss == 2) { 749 } else if (nss == 2) {
559 tbl->lq_type = LQ_VHT_MIMO2; 750 rate->type = LQ_VHT_MIMO2;
560 WARN_ON_ONCE(num_of_ant != 2); 751 WARN_ON_ONCE(num_of_ant != 2);
561 } else { 752 } else {
562 WARN_ON_ONCE(1); 753 WARN_ON_ONCE(1);
563 } 754 }
564 } 755 }
565 756
566 WARN_ON_ONCE(tbl->bw == RATE_MCS_CHAN_WIDTH_160); 757 WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_160);
567 WARN_ON_ONCE(tbl->bw == RATE_MCS_CHAN_WIDTH_80 && 758 WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_80 &&
568 !is_vht(tbl->lq_type)); 759 !is_vht(rate));
569 760
570 return 0; 761 return 0;
571} 762}
572 763
573/* switch to another antenna/antennas and return 1 */ 764/* switch to another antenna/antennas and return 1 */
574/* if no other valid antenna found, return 0 */ 765/* if no other valid antenna found, return 0 */
575static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, 766static int rs_toggle_antenna(u32 valid_ant, struct rs_rate *rate)
576 struct iwl_scale_tbl_info *tbl)
577{ 767{
578 u8 new_ant_type; 768 u8 new_ant_type;
579 769
580 if (!tbl->ant_type || tbl->ant_type > ANT_ABC) 770 if (!rate->ant || rate->ant > ANT_ABC)
581 return 0; 771 return 0;
582 772
583 if (!rs_is_valid_ant(valid_ant, tbl->ant_type)) 773 if (!rs_is_valid_ant(valid_ant, rate->ant))
584 return 0; 774 return 0;
585 775
586 new_ant_type = ant_toggle_lookup[tbl->ant_type]; 776 new_ant_type = ant_toggle_lookup[rate->ant];
587 777
588 while ((new_ant_type != tbl->ant_type) && 778 while ((new_ant_type != rate->ant) &&
589 !rs_is_valid_ant(valid_ant, new_ant_type)) 779 !rs_is_valid_ant(valid_ant, new_ant_type))
590 new_ant_type = ant_toggle_lookup[new_ant_type]; 780 new_ant_type = ant_toggle_lookup[new_ant_type];
591 781
592 if (new_ant_type == tbl->ant_type) 782 if (new_ant_type == rate->ant)
593 return 0; 783 return 0;
594 784
595 tbl->ant_type = new_ant_type; 785 rate->ant = new_ant_type;
596 *rate_n_flags &= ~RATE_MCS_ANT_ABC_MSK; 786
597 *rate_n_flags |= new_ant_type << RATE_MCS_ANT_POS;
598 return 1; 787 return 1;
599} 788}
600 789
601/**
602 * rs_get_supported_rates - get the available rates
603 *
604 * if management frame or broadcast frame only return
605 * basic available rates.
606 *
607 */
608static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta, 790static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
609 struct ieee80211_hdr *hdr, 791 struct rs_rate *rate)
610 enum iwl_table_type rate_type)
611{ 792{
612 if (is_legacy(rate_type)) 793 if (is_legacy(rate))
613 return lq_sta->active_legacy_rate; 794 return lq_sta->active_legacy_rate;
614 else if (is_siso(rate_type)) 795 else if (is_siso(rate))
615 return lq_sta->active_siso_rate; 796 return lq_sta->active_siso_rate;
616 else if (is_mimo2(rate_type)) 797 else if (is_mimo2(rate))
617 return lq_sta->active_mimo2_rate; 798 return lq_sta->active_mimo2_rate;
618 799
619 WARN_ON_ONCE(1); 800 WARN_ON_ONCE(1);
@@ -628,7 +809,7 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
628 809
629 /* 802.11A or ht walks to the next literal adjacent rate in 810 /* 802.11A or ht walks to the next literal adjacent rate in
630 * the rate table */ 811 * the rate table */
631 if (is_a_band(rate_type) || !is_legacy(rate_type)) { 812 if (is_type_a_band(rate_type) || !is_type_legacy(rate_type)) {
632 int i; 813 int i;
633 u32 mask; 814 u32 mask;
634 815
@@ -676,73 +857,80 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
676 return (high << 8) | low; 857 return (high << 8) | low;
677} 858}
678 859
679static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, 860static inline bool rs_rate_supported(struct iwl_lq_sta *lq_sta,
680 struct iwl_scale_tbl_info *tbl, 861 struct rs_rate *rate)
681 u8 scale_index, u8 ht_possible)
682{ 862{
683 s32 low; 863 return BIT(rate->index) & rs_get_supported_rates(lq_sta, rate);
684 u16 rate_mask; 864}
865
866/* Get the next supported lower rate in the current column.
867 * Return true if bottom rate in the current column was reached
868 */
869static bool rs_get_lower_rate_in_column(struct iwl_lq_sta *lq_sta,
870 struct rs_rate *rate)
871{
872 u8 low;
685 u16 high_low; 873 u16 high_low;
686 u8 switch_to_legacy = 0; 874 u16 rate_mask;
687 struct iwl_mvm *mvm = lq_sta->drv; 875 struct iwl_mvm *mvm = lq_sta->drv;
688 876
689 /* check if we need to switch from HT to legacy rates. 877 rate_mask = rs_get_supported_rates(lq_sta, rate);
690 * assumption is that mandatory rates (1Mbps or 6Mbps) 878 high_low = rs_get_adjacent_rate(mvm, rate->index, rate_mask,
691 * are always supported (spec demand) */ 879 rate->type);
692 if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) { 880 low = high_low & 0xff;
693 switch_to_legacy = 1;
694 scale_index = rs_ht_to_legacy[scale_index];
695 if (lq_sta->band == IEEE80211_BAND_5GHZ)
696 tbl->lq_type = LQ_LEGACY_A;
697 else
698 tbl->lq_type = LQ_LEGACY_G;
699 881
700 if (num_of_ant(tbl->ant_type) > 1) 882 /* Bottom rate of column reached */
701 tbl->ant_type = 883 if (low == IWL_RATE_INVALID)
702 first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); 884 return true;
703 885
704 tbl->bw = 0; 886 rate->index = low;
705 tbl->is_SGI = 0; 887 return false;
706 tbl->max_search = IWL_MAX_SEARCH; 888}
707 }
708 889
709 rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type); 890/* Get the next rate to use following a column downgrade */
891static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
892 struct rs_rate *rate)
893{
894 struct iwl_mvm *mvm = lq_sta->drv;
710 895
711 /* Mask with station rate restriction */ 896 if (is_legacy(rate)) {
712 if (is_legacy(tbl->lq_type)) { 897 /* No column to downgrade from Legacy */
713 /* supp_rates has no CCK bits in A mode */ 898 return;
899 } else if (is_siso(rate)) {
900 /* Downgrade to Legacy if we were in SISO */
714 if (lq_sta->band == IEEE80211_BAND_5GHZ) 901 if (lq_sta->band == IEEE80211_BAND_5GHZ)
715 rate_mask = (u16)(rate_mask & 902 rate->type = LQ_LEGACY_A;
716 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
717 else 903 else
718 rate_mask = (u16)(rate_mask & lq_sta->supp_rates); 904 rate->type = LQ_LEGACY_G;
719 }
720 905
721 /* If we switched from HT to legacy, check current rate */ 906 rate->bw = RATE_MCS_CHAN_WIDTH_20;
722 if (switch_to_legacy && (rate_mask & (1 << scale_index))) { 907
723 low = scale_index; 908 WARN_ON_ONCE(rate->index < IWL_RATE_MCS_0_INDEX &&
724 goto out; 909 rate->index > IWL_RATE_MCS_9_INDEX);
910
911 rate->index = rs_ht_to_legacy[rate->index];
912 } else {
913 /* Downgrade to SISO with same MCS if in MIMO */
914 rate->type = is_vht_mimo2(rate) ?
915 LQ_VHT_SISO : LQ_HT_SISO;
725 } 916 }
726 917
727 high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask,
728 tbl->lq_type);
729 low = high_low & 0xff;
730 918
731 if (low == IWL_RATE_INVALID) 919 if (num_of_ant(rate->ant) > 1)
732 low = scale_index; 920 rate->ant = first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
733 921
734out: 922 /* Relevant in both switching to SISO or Legacy */
735 return rate_n_flags_from_tbl(lq_sta->drv, tbl, low); 923 rate->sgi = false;
924
925 if (!rs_rate_supported(lq_sta, rate))
926 rs_get_lower_rate_in_column(lq_sta, rate);
736} 927}
737 928
738/* 929/* Simple function to compare two rate scale table types */
739 * Simple function to compare two rate scale table types 930static inline bool rs_rate_match(struct rs_rate *a,
740 */ 931 struct rs_rate *b)
741static bool table_type_matches(struct iwl_scale_tbl_info *a,
742 struct iwl_scale_tbl_info *b)
743{ 932{
744 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && 933 return (a->type == b->type) && (a->ant == b->ant) && (a->sgi == b->sgi);
745 (a->is_SGI == b->is_SGI);
746} 934}
747 935
748static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags) 936static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags)
@@ -766,7 +954,7 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
766{ 954{
767 int legacy_success; 955 int legacy_success;
768 int retries; 956 int retries;
769 int rs_index, mac_index, i; 957 int mac_index, i;
770 struct iwl_lq_sta *lq_sta = priv_sta; 958 struct iwl_lq_sta *lq_sta = priv_sta;
771 struct iwl_lq_cmd *table; 959 struct iwl_lq_cmd *table;
772 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 960 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
@@ -774,13 +962,10 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
774 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 962 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
775 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 963 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
776 enum mac80211_rate_control_flags mac_flags; 964 enum mac80211_rate_control_flags mac_flags;
777 u32 tx_rate; 965 u32 ucode_rate;
778 struct iwl_scale_tbl_info tbl_type; 966 struct rs_rate rate;
779 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; 967 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
780 968
781 IWL_DEBUG_RATE_LIMIT(mvm,
782 "get frame ack response, update rate scale window\n");
783
784 /* Treat uninitialized rate scaling data same as non-existing. */ 969 /* Treat uninitialized rate scaling data same as non-existing. */
785 if (!lq_sta) { 970 if (!lq_sta) {
786 IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n"); 971 IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n");
@@ -808,10 +993,10 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
808 * to a new "search" mode (which might become the new "active" mode). 993 * to a new "search" mode (which might become the new "active" mode).
809 */ 994 */
810 table = &lq_sta->lq; 995 table = &lq_sta->lq;
811 tx_rate = le32_to_cpu(table->rs_table[0]); 996 ucode_rate = le32_to_cpu(table->rs_table[0]);
812 rs_get_tbl_info_from_mcs(tx_rate, info->band, &tbl_type, &rs_index); 997 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
813 if (info->band == IEEE80211_BAND_5GHZ) 998 if (info->band == IEEE80211_BAND_5GHZ)
814 rs_index -= IWL_FIRST_OFDM_RATE; 999 rate.index -= IWL_FIRST_OFDM_RATE;
815 mac_flags = info->status.rates[0].flags; 1000 mac_flags = info->status.rates[0].flags;
816 mac_index = info->status.rates[0].idx; 1001 mac_index = info->status.rates[0].idx;
817 /* For HT packets, map MCS to PLCP */ 1002 /* For HT packets, map MCS to PLCP */
@@ -834,19 +1019,19 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
834 1019
835 /* Here we actually compare this rate to the latest LQ command */ 1020 /* Here we actually compare this rate to the latest LQ command */
836 if ((mac_index < 0) || 1021 if ((mac_index < 0) ||
837 (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) || 1022 (rate.sgi != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
838 (tbl_type.bw != rs_ch_width_from_mac_flags(mac_flags)) || 1023 (rate.bw != rs_ch_width_from_mac_flags(mac_flags)) ||
839 (tbl_type.ant_type != info->status.antenna) || 1024 (rate.ant != info->status.antenna) ||
840 (!!(tx_rate & RATE_MCS_HT_MSK) != 1025 (!!(ucode_rate & RATE_MCS_HT_MSK) !=
841 !!(mac_flags & IEEE80211_TX_RC_MCS)) || 1026 !!(mac_flags & IEEE80211_TX_RC_MCS)) ||
842 (!!(tx_rate & RATE_MCS_VHT_MSK) != 1027 (!!(ucode_rate & RATE_MCS_VHT_MSK) !=
843 !!(mac_flags & IEEE80211_TX_RC_VHT_MCS)) || 1028 !!(mac_flags & IEEE80211_TX_RC_VHT_MCS)) ||
844 (!!(tx_rate & RATE_HT_MCS_GF_MSK) != 1029 (!!(ucode_rate & RATE_HT_MCS_GF_MSK) !=
845 !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) || 1030 !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
846 (rs_index != mac_index)) { 1031 (rate.index != mac_index)) {
847 IWL_DEBUG_RATE(mvm, 1032 IWL_DEBUG_RATE(mvm,
848 "initial rate %d does not match %d (0x%x)\n", 1033 "initial rate %d does not match %d (0x%x)\n",
849 mac_index, rs_index, tx_rate); 1034 mac_index, rate.index, ucode_rate);
850 /* 1035 /*
851 * Since rates mis-match, the last LQ command may have failed. 1036 * Since rates mis-match, the last LQ command may have failed.
852 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with 1037 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
@@ -855,7 +1040,10 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
855 lq_sta->missed_rate_counter++; 1040 lq_sta->missed_rate_counter++;
856 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { 1041 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
857 lq_sta->missed_rate_counter = 0; 1042 lq_sta->missed_rate_counter = 0;
858 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false); 1043 IWL_DEBUG_RATE(mvm,
1044 "Too many rates mismatch. Send sync LQ. rs_state %d\n",
1045 lq_sta->rs_state);
1046 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
859 } 1047 }
860 /* Regardless, ignore this status info for outdated rate */ 1048 /* Regardless, ignore this status info for outdated rate */
861 return; 1049 return;
@@ -864,28 +1052,23 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
864 lq_sta->missed_rate_counter = 0; 1052 lq_sta->missed_rate_counter = 0;
865 1053
866 /* Figure out if rate scale algorithm is in active or search table */ 1054 /* Figure out if rate scale algorithm is in active or search table */
867 if (table_type_matches(&tbl_type, 1055 if (rs_rate_match(&rate,
868 &(lq_sta->lq_info[lq_sta->active_tbl]))) { 1056 &(lq_sta->lq_info[lq_sta->active_tbl].rate))) {
869 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1057 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
870 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); 1058 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
871 } else if (table_type_matches( 1059 } else if (rs_rate_match(&rate,
872 &tbl_type, &lq_sta->lq_info[1 - lq_sta->active_tbl])) { 1060 &lq_sta->lq_info[1 - lq_sta->active_tbl].rate)) {
873 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); 1061 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
874 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1062 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
875 } else { 1063 } else {
876 IWL_DEBUG_RATE(mvm, 1064 IWL_DEBUG_RATE(mvm,
877 "Neither active nor search matches tx rate\n"); 1065 "Neither active nor search matches tx rate\n");
878 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1066 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
879 IWL_DEBUG_RATE(mvm, "active- lq:%x, ant:%x, SGI:%d\n", 1067 rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE");
880 tmp_tbl->lq_type, tmp_tbl->ant_type,
881 tmp_tbl->is_SGI);
882 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); 1068 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
883 IWL_DEBUG_RATE(mvm, "search- lq:%x, ant:%x, SGI:%d\n", 1069 rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH");
884 tmp_tbl->lq_type, tmp_tbl->ant_type, 1070 rs_dump_rate(mvm, &rate, "ACTUAL");
885 tmp_tbl->is_SGI); 1071
886 IWL_DEBUG_RATE(mvm, "actual- lq:%x, ant:%x, SGI:%d\n",
887 tbl_type.lq_type, tbl_type.ant_type,
888 tbl_type.is_SGI);
889 /* 1072 /*
890 * no matching table found, let's by-pass the data collection 1073 * no matching table found, let's by-pass the data collection
891 * and continue to perform rate scale to find the rate table 1074 * and continue to perform rate scale to find the rate table
@@ -902,15 +1085,14 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
902 * first index into rate scale table. 1085 * first index into rate scale table.
903 */ 1086 */
904 if (info->flags & IEEE80211_TX_STAT_AMPDU) { 1087 if (info->flags & IEEE80211_TX_STAT_AMPDU) {
905 tx_rate = le32_to_cpu(table->rs_table[0]); 1088 ucode_rate = le32_to_cpu(table->rs_table[0]);
906 rs_get_tbl_info_from_mcs(tx_rate, info->band, &tbl_type, 1089 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
907 &rs_index); 1090 rs_collect_tx_data(curr_tbl, rate.index,
908 rs_collect_tx_data(curr_tbl, rs_index,
909 info->status.ampdu_len, 1091 info->status.ampdu_len,
910 info->status.ampdu_ack_len); 1092 info->status.ampdu_ack_len);
911 1093
912 /* Update success/fail counts if not searching for new mode */ 1094 /* Update success/fail counts if not searching for new mode */
913 if (lq_sta->stay_in_tbl) { 1095 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
914 lq_sta->total_success += info->status.ampdu_ack_len; 1096 lq_sta->total_success += info->status.ampdu_ack_len;
915 lq_sta->total_failed += (info->status.ampdu_len - 1097 lq_sta->total_failed += (info->status.ampdu_len -
916 info->status.ampdu_ack_len); 1098 info->status.ampdu_ack_len);
@@ -927,31 +1109,31 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
927 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK); 1109 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
928 /* Collect data for each rate used during failed TX attempts */ 1110 /* Collect data for each rate used during failed TX attempts */
929 for (i = 0; i <= retries; ++i) { 1111 for (i = 0; i <= retries; ++i) {
930 tx_rate = le32_to_cpu(table->rs_table[i]); 1112 ucode_rate = le32_to_cpu(table->rs_table[i]);
931 rs_get_tbl_info_from_mcs(tx_rate, info->band, 1113 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
932 &tbl_type, &rs_index);
933 /* 1114 /*
934 * Only collect stats if retried rate is in the same RS 1115 * Only collect stats if retried rate is in the same RS
935 * table as active/search. 1116 * table as active/search.
936 */ 1117 */
937 if (table_type_matches(&tbl_type, curr_tbl)) 1118 if (rs_rate_match(&rate, &curr_tbl->rate))
938 tmp_tbl = curr_tbl; 1119 tmp_tbl = curr_tbl;
939 else if (table_type_matches(&tbl_type, other_tbl)) 1120 else if (rs_rate_match(&rate, &other_tbl->rate))
940 tmp_tbl = other_tbl; 1121 tmp_tbl = other_tbl;
941 else 1122 else
942 continue; 1123 continue;
943 rs_collect_tx_data(tmp_tbl, rs_index, 1, 1124
1125 rs_collect_tx_data(tmp_tbl, rate.index, 1,
944 i < retries ? 0 : legacy_success); 1126 i < retries ? 0 : legacy_success);
945 } 1127 }
946 1128
947 /* Update success/fail counts if not searching for new mode */ 1129 /* Update success/fail counts if not searching for new mode */
948 if (lq_sta->stay_in_tbl) { 1130 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
949 lq_sta->total_success += legacy_success; 1131 lq_sta->total_success += legacy_success;
950 lq_sta->total_failed += retries + (1 - legacy_success); 1132 lq_sta->total_failed += retries + (1 - legacy_success);
951 } 1133 }
952 } 1134 }
953 /* The last TX rate is cached in lq_sta; it's set in if/else above */ 1135 /* The last TX rate is cached in lq_sta; it's set in if/else above */
954 lq_sta->last_rate_n_flags = tx_rate; 1136 lq_sta->last_rate_n_flags = ucode_rate;
955done: 1137done:
956 /* See if there's a better rate or modulation mode to try. */ 1138 /* See if there's a better rate or modulation mode to try. */
957 if (sta && sta->supp_rates[sband->band]) 1139 if (sta && sta->supp_rates[sband->band])
@@ -969,8 +1151,8 @@ done:
969static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy, 1151static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
970 struct iwl_lq_sta *lq_sta) 1152 struct iwl_lq_sta *lq_sta)
971{ 1153{
972 IWL_DEBUG_RATE(mvm, "we are staying in the same table\n"); 1154 IWL_DEBUG_RATE(mvm, "Moving to RS_STATE_STAY_IN_COLUMN\n");
973 lq_sta->stay_in_tbl = 1; /* only place this gets set */ 1155 lq_sta->rs_state = RS_STATE_STAY_IN_COLUMN;
974 if (is_legacy) { 1156 if (is_legacy) {
975 lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT; 1157 lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT;
976 lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT; 1158 lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT;
@@ -984,37 +1166,31 @@ static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
984 lq_sta->total_failed = 0; 1166 lq_sta->total_failed = 0;
985 lq_sta->total_success = 0; 1167 lq_sta->total_success = 0;
986 lq_sta->flush_timer = jiffies; 1168 lq_sta->flush_timer = jiffies;
987 lq_sta->action_counter = 0; 1169 lq_sta->visited_columns = 0;
988} 1170}
989 1171
990/* 1172static s32 *rs_get_expected_tpt_table(struct iwl_lq_sta *lq_sta,
991 * Find correct throughput table for given mode of modulation 1173 const struct rs_tx_column *column,
992 */ 1174 u32 bw)
993static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
994 struct iwl_scale_tbl_info *tbl)
995{ 1175{
996 /* Used to choose among HT tables */ 1176 /* Used to choose among HT tables */
997 s32 (*ht_tbl_pointer)[IWL_RATE_COUNT]; 1177 s32 (*ht_tbl_pointer)[IWL_RATE_COUNT];
998 1178
999 /* Check for invalid LQ type */ 1179 if (WARN_ON_ONCE(column->mode != RS_LEGACY &&
1000 if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_ht(tbl->lq_type) && 1180 column->mode != RS_SISO &&
1001 !(is_vht(tbl->lq_type)))) { 1181 column->mode != RS_MIMO2))
1002 tbl->expected_tpt = expected_tpt_legacy; 1182 return expected_tpt_legacy;
1003 return;
1004 }
1005 1183
1006 /* Legacy rates have only one table */ 1184 /* Legacy rates have only one table */
1007 if (is_legacy(tbl->lq_type)) { 1185 if (column->mode == RS_LEGACY)
1008 tbl->expected_tpt = expected_tpt_legacy; 1186 return expected_tpt_legacy;
1009 return;
1010 }
1011 1187
1012 ht_tbl_pointer = expected_tpt_mimo2_20MHz; 1188 ht_tbl_pointer = expected_tpt_mimo2_20MHz;
1013 /* Choose among many HT tables depending on number of streams 1189 /* Choose among many HT tables depending on number of streams
1014 * (SISO/MIMO2), channel width (20/40/80), SGI, and aggregation 1190 * (SISO/MIMO2), channel width (20/40/80), SGI, and aggregation
1015 * status */ 1191 * status */
1016 if (is_siso(tbl->lq_type)) { 1192 if (column->mode == RS_SISO) {
1017 switch (tbl->bw) { 1193 switch (bw) {
1018 case RATE_MCS_CHAN_WIDTH_20: 1194 case RATE_MCS_CHAN_WIDTH_20:
1019 ht_tbl_pointer = expected_tpt_siso_20MHz; 1195 ht_tbl_pointer = expected_tpt_siso_20MHz;
1020 break; 1196 break;
@@ -1027,8 +1203,8 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1027 default: 1203 default:
1028 WARN_ON_ONCE(1); 1204 WARN_ON_ONCE(1);
1029 } 1205 }
1030 } else if (is_mimo2(tbl->lq_type)) { 1206 } else if (column->mode == RS_MIMO2) {
1031 switch (tbl->bw) { 1207 switch (bw) {
1032 case RATE_MCS_CHAN_WIDTH_20: 1208 case RATE_MCS_CHAN_WIDTH_20:
1033 ht_tbl_pointer = expected_tpt_mimo2_20MHz; 1209 ht_tbl_pointer = expected_tpt_mimo2_20MHz;
1034 break; 1210 break;
@@ -1045,14 +1221,23 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1045 WARN_ON_ONCE(1); 1221 WARN_ON_ONCE(1);
1046 } 1222 }
1047 1223
1048 if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */ 1224 if (!column->sgi && !lq_sta->is_agg) /* Normal */
1049 tbl->expected_tpt = ht_tbl_pointer[0]; 1225 return ht_tbl_pointer[0];
1050 else if (tbl->is_SGI && !lq_sta->is_agg) /* SGI */ 1226 else if (column->sgi && !lq_sta->is_agg) /* SGI */
1051 tbl->expected_tpt = ht_tbl_pointer[1]; 1227 return ht_tbl_pointer[1];
1052 else if (!tbl->is_SGI && lq_sta->is_agg) /* AGG */ 1228 else if (!column->sgi && lq_sta->is_agg) /* AGG */
1053 tbl->expected_tpt = ht_tbl_pointer[2]; 1229 return ht_tbl_pointer[2];
1054 else /* AGG+SGI */ 1230 else /* AGG+SGI */
1055 tbl->expected_tpt = ht_tbl_pointer[3]; 1231 return ht_tbl_pointer[3];
1232}
1233
1234static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1235 struct iwl_scale_tbl_info *tbl)
1236{
1237 struct rs_rate *rate = &tbl->rate;
1238 const struct rs_tx_column *column = &rs_tx_columns[tbl->column];
1239
1240 tbl->expected_tpt = rs_get_expected_tpt_table(lq_sta, column, rate->bw);
1056} 1241}
1057 1242
1058/* 1243/*
@@ -1089,7 +1274,7 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1089 1274
1090 while (1) { 1275 while (1) {
1091 high_low = rs_get_adjacent_rate(mvm, rate, rate_mask, 1276 high_low = rs_get_adjacent_rate(mvm, rate, rate_mask,
1092 tbl->lq_type); 1277 tbl->rate.type);
1093 1278
1094 low = high_low & 0xff; 1279 low = high_low & 0xff;
1095 high = (high_low >> 8) & 0xff; 1280 high = (high_low >> 8) & 0xff;
@@ -1110,7 +1295,7 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1110 * "active" throughput (under perfect conditions). 1295 * "active" throughput (under perfect conditions).
1111 */ 1296 */
1112 if ((((100 * tpt_tbl[rate]) > lq_sta->last_tpt) && 1297 if ((((100 * tpt_tbl[rate]) > lq_sta->last_tpt) &&
1113 ((active_sr > IWL_RATE_DECREASE_TH) && 1298 ((active_sr > RS_SR_FORCE_DECREASE) &&
1114 (active_sr <= IWL_RATE_HIGH_TH) && 1299 (active_sr <= IWL_RATE_HIGH_TH) &&
1115 (tpt_tbl[rate] <= active_tpt))) || 1300 (tpt_tbl[rate] <= active_tpt))) ||
1116 ((active_sr >= IWL_RATE_SCALE_SWITCH) && 1301 ((active_sr >= IWL_RATE_SCALE_SWITCH) &&
@@ -1157,417 +1342,14 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1157 return new_rate; 1342 return new_rate;
1158} 1343}
1159 1344
1160/* Move to the next action and wrap around to the first action in case 1345static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta)
1161 * we're at the last action. Assumes actions start at 0.
1162 */
1163static inline void rs_move_next_action(struct iwl_scale_tbl_info *tbl,
1164 u8 last_action)
1165{
1166 BUILD_BUG_ON(IWL_LEGACY_FIRST_ACTION != 0);
1167 BUILD_BUG_ON(IWL_SISO_FIRST_ACTION != 0);
1168 BUILD_BUG_ON(IWL_MIMO2_FIRST_ACTION != 0);
1169
1170 tbl->action = (tbl->action + 1) % (last_action + 1);
1171}
1172
1173static void rs_set_bw_from_sta(struct iwl_scale_tbl_info *tbl,
1174 struct ieee80211_sta *sta)
1175{ 1346{
1176 if (sta->bandwidth >= IEEE80211_STA_RX_BW_80) 1347 if (sta->bandwidth >= IEEE80211_STA_RX_BW_80)
1177 tbl->bw = RATE_MCS_CHAN_WIDTH_80; 1348 return RATE_MCS_CHAN_WIDTH_80;
1178 else if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) 1349 else if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
1179 tbl->bw = RATE_MCS_CHAN_WIDTH_40; 1350 return RATE_MCS_CHAN_WIDTH_40;
1180 else
1181 tbl->bw = RATE_MCS_CHAN_WIDTH_20;
1182}
1183
1184static bool rs_sgi_allowed(struct iwl_scale_tbl_info *tbl,
1185 struct ieee80211_sta *sta)
1186{
1187 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1188 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
1189
1190 if (is_ht20(tbl) && (ht_cap->cap &
1191 IEEE80211_HT_CAP_SGI_20))
1192 return true;
1193 if (is_ht40(tbl) && (ht_cap->cap &
1194 IEEE80211_HT_CAP_SGI_40))
1195 return true;
1196 if (is_ht80(tbl) && (vht_cap->cap &
1197 IEEE80211_VHT_CAP_SHORT_GI_80))
1198 return true;
1199
1200 return false;
1201}
1202
1203/*
1204 * Set up search table for MIMO2
1205 */
1206static int rs_switch_to_mimo2(struct iwl_mvm *mvm,
1207 struct iwl_lq_sta *lq_sta,
1208 struct ieee80211_sta *sta,
1209 struct iwl_scale_tbl_info *tbl, int index)
1210{
1211 u16 rate_mask;
1212 s32 rate;
1213
1214 if (!sta->ht_cap.ht_supported)
1215 return -1;
1216
1217 if (sta->smps_mode == IEEE80211_SMPS_STATIC)
1218 return -1;
1219
1220 /* Need both Tx chains/antennas to support MIMO */
1221 if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 2)
1222 return -1;
1223
1224 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n");
1225
1226 tbl->lq_type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2;
1227 tbl->action = 0;
1228 tbl->max_search = IWL_MAX_SEARCH;
1229 rate_mask = lq_sta->active_mimo2_rate;
1230
1231 rs_set_bw_from_sta(tbl, sta);
1232 rs_set_expected_tpt_table(lq_sta, tbl);
1233
1234 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
1235
1236 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 best rate %d mask %X\n",
1237 rate, rate_mask);
1238 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
1239 IWL_DEBUG_RATE(mvm, "Can't switch with index %d rate mask %x\n",
1240 rate, rate_mask);
1241 return -1;
1242 }
1243 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate);
1244
1245 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index\n",
1246 tbl->current_rate);
1247 return 0;
1248}
1249
1250/*
1251 * Set up search table for SISO
1252 */
1253static int rs_switch_to_siso(struct iwl_mvm *mvm,
1254 struct iwl_lq_sta *lq_sta,
1255 struct ieee80211_sta *sta,
1256 struct iwl_scale_tbl_info *tbl, int index)
1257{
1258 u16 rate_mask;
1259 s32 rate;
1260
1261 if (!sta->ht_cap.ht_supported)
1262 return -1;
1263
1264 IWL_DEBUG_RATE(mvm, "LQ: try to switch to SISO\n");
1265
1266 tbl->lq_type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO;
1267 tbl->action = 0;
1268 tbl->max_search = IWL_MAX_SEARCH;
1269 rate_mask = lq_sta->active_siso_rate;
1270
1271 rs_set_bw_from_sta(tbl, sta);
1272 rs_set_expected_tpt_table(lq_sta, tbl);
1273 rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index);
1274
1275 IWL_DEBUG_RATE(mvm, "LQ: get best rate %d mask %X\n", rate, rate_mask);
1276 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
1277 IWL_DEBUG_RATE(mvm,
1278 "can not switch with index %d rate mask %x\n",
1279 rate, rate_mask);
1280 return -1;
1281 }
1282 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate);
1283 IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index\n",
1284 tbl->current_rate);
1285 return 0;
1286}
1287
1288/*
1289 * Try to switch to new modulation mode from legacy
1290 */
1291static int rs_move_legacy_other(struct iwl_mvm *mvm,
1292 struct iwl_lq_sta *lq_sta,
1293 struct ieee80211_sta *sta,
1294 int index)
1295{
1296 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1297 struct iwl_scale_tbl_info *search_tbl =
1298 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1299 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1300 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1301 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1302 u8 start_action;
1303 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1304 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1305 int ret;
1306 u8 update_search_tbl_counter = 0;
1307
1308 start_action = tbl->action;
1309 while (1) {
1310 lq_sta->action_counter++;
1311 switch (tbl->action) {
1312 case IWL_LEGACY_SWITCH_ANTENNA:
1313 IWL_DEBUG_RATE(mvm, "LQ: Legacy toggle Antenna\n");
1314
1315 if (tx_chains_num <= 1)
1316 break;
1317
1318 /* Don't change antenna if success has been great */
1319 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1320 break;
1321
1322 /* Set up search table to try other antenna */
1323 memcpy(search_tbl, tbl, sz);
1324
1325 if (rs_toggle_antenna(valid_tx_ant,
1326 &search_tbl->current_rate,
1327 search_tbl)) {
1328 update_search_tbl_counter = 1;
1329 rs_set_expected_tpt_table(lq_sta, search_tbl);
1330 goto out;
1331 }
1332 break;
1333 case IWL_LEGACY_SWITCH_SISO:
1334 IWL_DEBUG_RATE(mvm, "LQ: Legacy switch to SISO\n");
1335
1336 /* Set up search table to try SISO */
1337 memcpy(search_tbl, tbl, sz);
1338 search_tbl->is_SGI = 0;
1339 ret = rs_switch_to_siso(mvm, lq_sta, sta,
1340 search_tbl, index);
1341 if (!ret) {
1342 lq_sta->action_counter = 0;
1343 goto out;
1344 }
1345
1346 break;
1347 case IWL_LEGACY_SWITCH_MIMO2:
1348 IWL_DEBUG_RATE(mvm, "LQ: Legacy switch to MIMO2\n");
1349
1350 /* Set up search table to try MIMO */
1351 memcpy(search_tbl, tbl, sz);
1352 search_tbl->is_SGI = 0;
1353
1354 search_tbl->ant_type = ANT_AB;
1355
1356 if (!rs_is_valid_ant(valid_tx_ant,
1357 search_tbl->ant_type))
1358 break;
1359
1360 ret = rs_switch_to_mimo2(mvm, lq_sta, sta,
1361 search_tbl, index);
1362 if (!ret) {
1363 lq_sta->action_counter = 0;
1364 goto out;
1365 }
1366 break;
1367 default:
1368 WARN_ON_ONCE(1);
1369 }
1370 rs_move_next_action(tbl, IWL_LEGACY_LAST_ACTION);
1371
1372 if (tbl->action == start_action)
1373 break;
1374 }
1375 search_tbl->lq_type = LQ_NONE;
1376 return 0;
1377
1378out:
1379 lq_sta->search_better_tbl = 1;
1380 rs_move_next_action(tbl, IWL_LEGACY_LAST_ACTION);
1381 if (update_search_tbl_counter)
1382 search_tbl->action = tbl->action;
1383 return 0;
1384}
1385
1386/*
1387 * Try to switch to new modulation mode from SISO
1388 */
1389static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1390 struct iwl_lq_sta *lq_sta,
1391 struct ieee80211_sta *sta, int index)
1392{
1393 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1394 struct iwl_scale_tbl_info *search_tbl =
1395 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1396 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1397 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1398 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1399 u8 start_action;
1400 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1401 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1402 u8 update_search_tbl_counter = 0;
1403 int ret;
1404
1405 if (tbl->action == IWL_SISO_SWITCH_MIMO2 &&
1406 !iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
1407 tbl->action = IWL_SISO_SWITCH_ANTENNA;
1408
1409 start_action = tbl->action;
1410 while (1) {
1411 lq_sta->action_counter++;
1412 switch (tbl->action) {
1413 case IWL_SISO_SWITCH_ANTENNA:
1414 IWL_DEBUG_RATE(mvm, "LQ: SISO toggle Antenna\n");
1415 if (tx_chains_num <= 1)
1416 break;
1417
1418 if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
1419 BT_MBOX_MSG(&mvm->last_bt_notif, 3,
1420 TRAFFIC_LOAD) == 0)
1421 break;
1422
1423 memcpy(search_tbl, tbl, sz);
1424 if (rs_toggle_antenna(valid_tx_ant,
1425 &search_tbl->current_rate,
1426 search_tbl)) {
1427 update_search_tbl_counter = 1;
1428 goto out;
1429 }
1430 break;
1431 case IWL_SISO_SWITCH_MIMO2:
1432 IWL_DEBUG_RATE(mvm, "LQ: SISO switch to MIMO2\n");
1433 memcpy(search_tbl, tbl, sz);
1434 search_tbl->is_SGI = 0;
1435
1436 search_tbl->ant_type = ANT_AB;
1437
1438 if (!rs_is_valid_ant(valid_tx_ant,
1439 search_tbl->ant_type))
1440 break;
1441
1442 ret = rs_switch_to_mimo2(mvm, lq_sta, sta,
1443 search_tbl, index);
1444 if (!ret)
1445 goto out;
1446 break;
1447 case IWL_SISO_SWITCH_GI:
1448 if (!rs_sgi_allowed(tbl, sta))
1449 break;
1450
1451 IWL_DEBUG_RATE(mvm, "LQ: SISO toggle SGI/NGI\n");
1452
1453 memcpy(search_tbl, tbl, sz);
1454 search_tbl->is_SGI = !tbl->is_SGI;
1455 rs_set_expected_tpt_table(lq_sta, search_tbl);
1456 if (tbl->is_SGI) {
1457 s32 tpt = lq_sta->last_tpt / 100;
1458 if (tpt >= search_tbl->expected_tpt[index])
1459 break;
1460 }
1461 search_tbl->current_rate =
1462 rate_n_flags_from_tbl(mvm, search_tbl, index);
1463 update_search_tbl_counter = 1;
1464 goto out;
1465 default:
1466 WARN_ON_ONCE(1);
1467 }
1468 rs_move_next_action(tbl, IWL_SISO_LAST_ACTION);
1469
1470 if (tbl->action == start_action)
1471 break;
1472 }
1473 search_tbl->lq_type = LQ_NONE;
1474 return 0;
1475
1476 out:
1477 lq_sta->search_better_tbl = 1;
1478 rs_move_next_action(tbl, IWL_SISO_LAST_ACTION);
1479 if (update_search_tbl_counter)
1480 search_tbl->action = tbl->action;
1481
1482 return 0;
1483}
1484
1485/*
1486 * Try to switch to new modulation mode from MIMO2
1487 */
1488static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1489 struct iwl_lq_sta *lq_sta,
1490 struct ieee80211_sta *sta, int index)
1491{
1492 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1493 struct iwl_scale_tbl_info *search_tbl =
1494 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1495 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1496 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1497 u8 start_action;
1498 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1499 u8 update_search_tbl_counter = 0;
1500 int ret;
1501
1502 start_action = tbl->action;
1503 while (1) {
1504 lq_sta->action_counter++;
1505 switch (tbl->action) {
1506 case IWL_MIMO2_SWITCH_SISO_A:
1507 case IWL_MIMO2_SWITCH_SISO_B:
1508 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 switch to SISO\n");
1509
1510 /* Set up new search table for SISO */
1511 memcpy(search_tbl, tbl, sz);
1512
1513 if (tbl->action == IWL_MIMO2_SWITCH_SISO_A)
1514 search_tbl->ant_type = ANT_A;
1515 else /* tbl->action == IWL_MIMO2_SWITCH_SISO_B */
1516 search_tbl->ant_type = ANT_B;
1517
1518 if (!rs_is_valid_ant(valid_tx_ant,
1519 search_tbl->ant_type))
1520 break;
1521
1522 ret = rs_switch_to_siso(mvm, lq_sta, sta,
1523 search_tbl, index);
1524 if (!ret)
1525 goto out;
1526
1527 break;
1528
1529 case IWL_MIMO2_SWITCH_GI:
1530 if (!rs_sgi_allowed(tbl, sta))
1531 break;
1532
1533 IWL_DEBUG_RATE(mvm, "LQ: MIMO2 toggle SGI/NGI\n");
1534
1535 /* Set up new search table for MIMO2 */
1536 memcpy(search_tbl, tbl, sz);
1537 search_tbl->is_SGI = !tbl->is_SGI;
1538 rs_set_expected_tpt_table(lq_sta, search_tbl);
1539 /*
1540 * If active table already uses the fastest possible
1541 * modulation (dual stream with short guard interval),
1542 * and it's working well, there's no need to look
1543 * for a better type of modulation!
1544 */
1545 if (tbl->is_SGI) {
1546 s32 tpt = lq_sta->last_tpt / 100;
1547 if (tpt >= search_tbl->expected_tpt[index])
1548 break;
1549 }
1550 search_tbl->current_rate =
1551 rate_n_flags_from_tbl(mvm, search_tbl, index);
1552 update_search_tbl_counter = 1;
1553 goto out;
1554 default:
1555 WARN_ON_ONCE(1);
1556 }
1557 rs_move_next_action(tbl, IWL_MIMO2_LAST_ACTION);
1558
1559 if (tbl->action == start_action)
1560 break;
1561 }
1562 search_tbl->lq_type = LQ_NONE;
1563 return 0;
1564 out:
1565 lq_sta->search_better_tbl = 1;
1566 rs_move_next_action(tbl, IWL_MIMO2_LAST_ACTION);
1567 if (update_search_tbl_counter)
1568 search_tbl->action = tbl->action;
1569 1351
1570 return 0; 1352 return RATE_MCS_CHAN_WIDTH_20;
1571} 1353}
1572 1354
1573/* 1355/*
@@ -1591,13 +1373,13 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1591 tbl = &(lq_sta->lq_info[active_tbl]); 1373 tbl = &(lq_sta->lq_info[active_tbl]);
1592 1374
1593 /* If we've been disallowing search, see if we should now allow it */ 1375 /* If we've been disallowing search, see if we should now allow it */
1594 if (lq_sta->stay_in_tbl) { 1376 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
1595 /* Elapsed time using current modulation mode */ 1377 /* Elapsed time using current modulation mode */
1596 if (lq_sta->flush_timer) 1378 if (lq_sta->flush_timer)
1597 flush_interval_passed = 1379 flush_interval_passed =
1598 time_after(jiffies, 1380 time_after(jiffies,
1599 (unsigned long)(lq_sta->flush_timer + 1381 (unsigned long)(lq_sta->flush_timer +
1600 IWL_RATE_SCALE_FLUSH_INTVL)); 1382 RS_STAY_IN_COLUMN_TIMEOUT));
1601 1383
1602 /* 1384 /*
1603 * Check if we should allow search for new modulation mode. 1385 * Check if we should allow search for new modulation mode.
@@ -1619,10 +1401,14 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1619 flush_interval_passed); 1401 flush_interval_passed);
1620 1402
1621 /* Allow search for new mode */ 1403 /* Allow search for new mode */
1622 lq_sta->stay_in_tbl = 0; /* only place reset */ 1404 lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_STARTED;
1405 IWL_DEBUG_RATE(mvm,
1406 "Moving to RS_STATE_SEARCH_CYCLE_STARTED\n");
1623 lq_sta->total_failed = 0; 1407 lq_sta->total_failed = 0;
1624 lq_sta->total_success = 0; 1408 lq_sta->total_success = 0;
1625 lq_sta->flush_timer = 0; 1409 lq_sta->flush_timer = 0;
1410 /* mark the current column as visited */
1411 lq_sta->visited_columns = BIT(tbl->column);
1626 /* 1412 /*
1627 * Else if we've used this modulation mode enough repetitions 1413 * Else if we've used this modulation mode enough repetitions
1628 * (regardless of elapsed time or success/failure), reset 1414 * (regardless of elapsed time or success/failure), reset
@@ -1646,7 +1432,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1646 /* If transitioning to allow "search", reset all history 1432 /* If transitioning to allow "search", reset all history
1647 * bitmaps and stats in active table (this will become the new 1433 * bitmaps and stats in active table (this will become the new
1648 * "search" table). */ 1434 * "search" table). */
1649 if (!lq_sta->stay_in_tbl) { 1435 if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) {
1436 IWL_DEBUG_RATE(mvm, "Clearing up window stats\n");
1650 for (i = 0; i < IWL_RATE_COUNT; i++) 1437 for (i = 0; i < IWL_RATE_COUNT; i++)
1651 rs_rate_scale_clear_window(&(tbl->win[i])); 1438 rs_rate_scale_clear_window(&(tbl->win[i]));
1652 } 1439 }
@@ -1659,15 +1446,10 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1659static void rs_update_rate_tbl(struct iwl_mvm *mvm, 1446static void rs_update_rate_tbl(struct iwl_mvm *mvm,
1660 struct ieee80211_sta *sta, 1447 struct ieee80211_sta *sta,
1661 struct iwl_lq_sta *lq_sta, 1448 struct iwl_lq_sta *lq_sta,
1662 struct iwl_scale_tbl_info *tbl, 1449 struct rs_rate *rate)
1663 int index)
1664{ 1450{
1665 u32 rate; 1451 rs_fill_lq_cmd(mvm, sta, lq_sta, rate);
1666 1452 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
1667 /* Update uCode's rate table. */
1668 rate = rate_n_flags_from_tbl(mvm, tbl, index);
1669 rs_fill_link_cmd(mvm, sta, lq_sta, rate);
1670 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
1671} 1453}
1672 1454
1673static u8 rs_get_tid(struct iwl_lq_sta *lq_data, 1455static u8 rs_get_tid(struct iwl_lq_sta *lq_data,
@@ -1686,6 +1468,250 @@ static u8 rs_get_tid(struct iwl_lq_sta *lq_data,
1686 return tid; 1468 return tid;
1687} 1469}
1688 1470
1471static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
1472 struct iwl_lq_sta *lq_sta,
1473 struct ieee80211_sta *sta,
1474 struct iwl_scale_tbl_info *tbl)
1475{
1476 int i, j, n;
1477 enum rs_column next_col_id;
1478 const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column];
1479 const struct rs_tx_column *next_col;
1480 allow_column_func_t allow_func;
1481 u8 valid_ants = iwl_fw_valid_tx_ant(mvm->fw);
1482 s32 *expected_tpt_tbl;
1483 s32 tpt, max_expected_tpt;
1484
1485 for (i = 0; i < MAX_NEXT_COLUMNS; i++) {
1486 next_col_id = curr_col->next_columns[i];
1487
1488 if (next_col_id == RS_COLUMN_INVALID)
1489 continue;
1490
1491 if (lq_sta->visited_columns & BIT(next_col_id)) {
1492 IWL_DEBUG_RATE(mvm, "Skip already visited column %d\n",
1493 next_col_id);
1494 continue;
1495 }
1496
1497 next_col = &rs_tx_columns[next_col_id];
1498
1499 if (!rs_is_valid_ant(valid_ants, next_col->ant)) {
1500 IWL_DEBUG_RATE(mvm,
1501 "Skip column %d as ANT config isn't supported by chip. valid_ants 0x%x column ant 0x%x\n",
1502 next_col_id, valid_ants, next_col->ant);
1503 continue;
1504 }
1505
1506 for (j = 0; j < MAX_COLUMN_CHECKS; j++) {
1507 allow_func = next_col->checks[j];
1508 if (allow_func && !allow_func(mvm, sta, tbl))
1509 break;
1510 }
1511
1512 if (j != MAX_COLUMN_CHECKS) {
1513 IWL_DEBUG_RATE(mvm,
1514 "Skip column %d: not allowed (check %d failed)\n",
1515 next_col_id, j);
1516
1517 continue;
1518 }
1519
1520 tpt = lq_sta->last_tpt / 100;
1521 expected_tpt_tbl = rs_get_expected_tpt_table(lq_sta, next_col,
1522 tbl->rate.bw);
1523 if (WARN_ON_ONCE(!expected_tpt_tbl))
1524 continue;
1525
1526 max_expected_tpt = 0;
1527 for (n = 0; n < IWL_RATE_COUNT; n++)
1528 if (expected_tpt_tbl[n] > max_expected_tpt)
1529 max_expected_tpt = expected_tpt_tbl[n];
1530
1531 if (tpt >= max_expected_tpt) {
1532 IWL_DEBUG_RATE(mvm,
1533 "Skip column %d: can't beat current TPT. Max expected %d current %d\n",
1534 next_col_id, max_expected_tpt, tpt);
1535 continue;
1536 }
1537
1538 break;
1539 }
1540
1541 if (i == MAX_NEXT_COLUMNS)
1542 return RS_COLUMN_INVALID;
1543
1544 IWL_DEBUG_RATE(mvm, "Found potential column %d\n", next_col_id);
1545
1546 return next_col_id;
1547}
1548
1549static int rs_switch_to_column(struct iwl_mvm *mvm,
1550 struct iwl_lq_sta *lq_sta,
1551 struct ieee80211_sta *sta,
1552 enum rs_column col_id)
1553{
1554 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1555 struct iwl_scale_tbl_info *search_tbl =
1556 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1557 struct rs_rate *rate = &search_tbl->rate;
1558 const struct rs_tx_column *column = &rs_tx_columns[col_id];
1559 const struct rs_tx_column *curr_column = &rs_tx_columns[tbl->column];
1560 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1561 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1562 u16 rate_mask = 0;
1563 u32 rate_idx = 0;
1564
1565 memcpy(search_tbl, tbl, sz);
1566
1567 rate->sgi = column->sgi;
1568 rate->ant = column->ant;
1569
1570 if (column->mode == RS_LEGACY) {
1571 if (lq_sta->band == IEEE80211_BAND_5GHZ)
1572 rate->type = LQ_LEGACY_A;
1573 else
1574 rate->type = LQ_LEGACY_G;
1575
1576 rate_mask = lq_sta->active_legacy_rate;
1577 } else if (column->mode == RS_SISO) {
1578 rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO;
1579 rate_mask = lq_sta->active_siso_rate;
1580 } else if (column->mode == RS_MIMO2) {
1581 rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2;
1582 rate_mask = lq_sta->active_mimo2_rate;
1583 } else {
1584 WARN_ON_ONCE("Bad column mode");
1585 }
1586
1587 rate->bw = rs_bw_from_sta_bw(sta);
1588 search_tbl->column = col_id;
1589 rs_set_expected_tpt_table(lq_sta, search_tbl);
1590
1591 lq_sta->visited_columns |= BIT(col_id);
1592
1593 /* Get the best matching rate if we're changing modes. e.g.
1594 * SISO->MIMO, LEGACY->SISO, MIMO->SISO
1595 */
1596 if (curr_column->mode != column->mode) {
1597 rate_idx = rs_get_best_rate(mvm, lq_sta, search_tbl,
1598 rate_mask, rate->index);
1599
1600 if ((rate_idx == IWL_RATE_INVALID) ||
1601 !(BIT(rate_idx) & rate_mask)) {
1602 IWL_DEBUG_RATE(mvm,
1603 "can not switch with index %d"
1604 " rate mask %x\n",
1605 rate_idx, rate_mask);
1606
1607 goto err;
1608 }
1609
1610 rate->index = rate_idx;
1611 }
1612
1613 IWL_DEBUG_RATE(mvm, "Switched to column %d: Index %d\n",
1614 col_id, rate->index);
1615
1616 return 0;
1617
1618err:
1619 rate->type = LQ_NONE;
1620 return -1;
1621}
1622
1623static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm,
1624 struct iwl_scale_tbl_info *tbl,
1625 s32 sr, int low, int high,
1626 int current_tpt,
1627 int low_tpt, int high_tpt)
1628{
1629 enum rs_action action = RS_ACTION_STAY;
1630
1631 /* Too many failures, decrease rate */
1632 if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) {
1633 IWL_DEBUG_RATE(mvm,
1634 "decrease rate because of low SR\n");
1635 action = RS_ACTION_DOWNSCALE;
1636 /* No throughput measured yet for adjacent rates; try increase. */
1637 } else if ((low_tpt == IWL_INVALID_VALUE) &&
1638 (high_tpt == IWL_INVALID_VALUE)) {
1639 if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) {
1640 IWL_DEBUG_RATE(mvm,
1641 "Good SR and no high rate measurement. "
1642 "Increase rate\n");
1643 action = RS_ACTION_UPSCALE;
1644 } else if (low != IWL_RATE_INVALID) {
1645 IWL_DEBUG_RATE(mvm,
1646 "Remain in current rate\n");
1647 action = RS_ACTION_STAY;
1648 }
1649 }
1650
1651 /* Both adjacent throughputs are measured, but neither one has better
1652 * throughput; we're using the best rate, don't change it!
1653 */
1654 else if ((low_tpt != IWL_INVALID_VALUE) &&
1655 (high_tpt != IWL_INVALID_VALUE) &&
1656 (low_tpt < current_tpt) &&
1657 (high_tpt < current_tpt)) {
1658 IWL_DEBUG_RATE(mvm,
1659 "Both high and low are worse. "
1660 "Maintain rate\n");
1661 action = RS_ACTION_STAY;
1662 }
1663
1664 /* At least one adjacent rate's throughput is measured,
1665 * and may have better performance.
1666 */
1667 else {
1668 /* Higher adjacent rate's throughput is measured */
1669 if (high_tpt != IWL_INVALID_VALUE) {
1670 /* Higher rate has better throughput */
1671 if (high_tpt > current_tpt &&
1672 sr >= IWL_RATE_INCREASE_TH) {
1673 IWL_DEBUG_RATE(mvm,
1674 "Higher rate is better and good "
1675 "SR. Increate rate\n");
1676 action = RS_ACTION_UPSCALE;
1677 } else {
1678 IWL_DEBUG_RATE(mvm,
1679 "Higher rate isn't better OR "
1680 "no good SR. Maintain rate\n");
1681 action = RS_ACTION_STAY;
1682 }
1683
1684 /* Lower adjacent rate's throughput is measured */
1685 } else if (low_tpt != IWL_INVALID_VALUE) {
1686 /* Lower rate has better throughput */
1687 if (low_tpt > current_tpt) {
1688 IWL_DEBUG_RATE(mvm,
1689 "Lower rate is better. "
1690 "Decrease rate\n");
1691 action = RS_ACTION_DOWNSCALE;
1692 } else if (sr >= IWL_RATE_INCREASE_TH) {
1693 IWL_DEBUG_RATE(mvm,
1694 "Lower rate isn't better and "
1695 "good SR. Increase rate\n");
1696 action = RS_ACTION_UPSCALE;
1697 }
1698 }
1699 }
1700
1701 /* Sanity check; asked for decrease, but success rate or throughput
1702 * has been good at old rate. Don't change it.
1703 */
1704 if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID) &&
1705 ((sr > IWL_RATE_HIGH_TH) ||
1706 (current_tpt > (100 * tbl->expected_tpt[low])))) {
1707 IWL_DEBUG_RATE(mvm,
1708 "Sanity check failed. Maintain rate\n");
1709 action = RS_ACTION_STAY;
1710 }
1711
1712 return action;
1713}
1714
1689/* 1715/*
1690 * Do rate scaling and search for new modulation mode. 1716 * Do rate scaling and search for new modulation mode.
1691 */ 1717 */
@@ -1705,20 +1731,19 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1705 int low_tpt = IWL_INVALID_VALUE; 1731 int low_tpt = IWL_INVALID_VALUE;
1706 int high_tpt = IWL_INVALID_VALUE; 1732 int high_tpt = IWL_INVALID_VALUE;
1707 u32 fail_count; 1733 u32 fail_count;
1708 s8 scale_action = 0; 1734 enum rs_action scale_action = RS_ACTION_STAY;
1709 u16 rate_mask; 1735 u16 rate_mask;
1710 u8 update_lq = 0; 1736 u8 update_lq = 0;
1711 struct iwl_scale_tbl_info *tbl, *tbl1; 1737 struct iwl_scale_tbl_info *tbl, *tbl1;
1712 u16 rate_scale_index_msk = 0;
1713 u8 active_tbl = 0; 1738 u8 active_tbl = 0;
1714 u8 done_search = 0; 1739 u8 done_search = 0;
1715 u16 high_low; 1740 u16 high_low;
1716 s32 sr; 1741 s32 sr;
1717 u8 tid = IWL_MAX_TID_COUNT; 1742 u8 tid = IWL_MAX_TID_COUNT;
1743 u8 prev_agg = lq_sta->is_agg;
1718 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv; 1744 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv;
1719 struct iwl_mvm_tid_data *tid_data; 1745 struct iwl_mvm_tid_data *tid_data;
1720 1746 struct rs_rate *rate;
1721 IWL_DEBUG_RATE(mvm, "rate scale calculate new rate for skb\n");
1722 1747
1723 /* Send management frames and NO_ACK data using lowest rate. */ 1748 /* Send management frames and NO_ACK data using lowest rate. */
1724 /* TODO: this could probably be improved.. */ 1749 /* TODO: this could probably be improved.. */
@@ -1726,8 +1751,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1726 info->flags & IEEE80211_TX_CTL_NO_ACK) 1751 info->flags & IEEE80211_TX_CTL_NO_ACK)
1727 return; 1752 return;
1728 1753
1729 lq_sta->supp_rates = sta->supp_rates[lq_sta->band];
1730
1731 tid = rs_get_tid(lq_sta, hdr); 1754 tid = rs_get_tid(lq_sta, hdr);
1732 if ((tid != IWL_MAX_TID_COUNT) && 1755 if ((tid != IWL_MAX_TID_COUNT) &&
1733 (lq_sta->tx_agg_tid_en & (1 << tid))) { 1756 (lq_sta->tx_agg_tid_en & (1 << tid))) {
@@ -1751,45 +1774,29 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1751 active_tbl = 1 - lq_sta->active_tbl; 1774 active_tbl = 1 - lq_sta->active_tbl;
1752 1775
1753 tbl = &(lq_sta->lq_info[active_tbl]); 1776 tbl = &(lq_sta->lq_info[active_tbl]);
1777 rate = &tbl->rate;
1778
1779 if (prev_agg != lq_sta->is_agg) {
1780 IWL_DEBUG_RATE(mvm,
1781 "Aggregation changed: prev %d current %d. Update expected TPT table\n",
1782 prev_agg, lq_sta->is_agg);
1783 rs_set_expected_tpt_table(lq_sta, tbl);
1784 }
1754 1785
1755 /* current tx rate */ 1786 /* current tx rate */
1756 index = lq_sta->last_txrate_idx; 1787 index = lq_sta->last_txrate_idx;
1757 1788
1758 IWL_DEBUG_RATE(mvm, "Rate scale index %d for type %d\n", index,
1759 tbl->lq_type);
1760
1761 /* rates available for this association, and for modulation mode */ 1789 /* rates available for this association, and for modulation mode */
1762 rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type); 1790 rate_mask = rs_get_supported_rates(lq_sta, rate);
1763 1791
1764 IWL_DEBUG_RATE(mvm, "mask 0x%04X\n", rate_mask); 1792 if (!(BIT(index) & rate_mask)) {
1765
1766 /* mask with station rate restriction */
1767 if (is_legacy(tbl->lq_type)) {
1768 if (lq_sta->band == IEEE80211_BAND_5GHZ)
1769 /* supp_rates has no CCK bits in A mode */
1770 rate_scale_index_msk = (u16) (rate_mask &
1771 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
1772 else
1773 rate_scale_index_msk = (u16) (rate_mask &
1774 lq_sta->supp_rates);
1775
1776 } else {
1777 rate_scale_index_msk = rate_mask;
1778 }
1779
1780 if (!rate_scale_index_msk)
1781 rate_scale_index_msk = rate_mask;
1782
1783 if (!((1 << index) & rate_scale_index_msk)) {
1784 IWL_ERR(mvm, "Current Rate is not valid\n"); 1793 IWL_ERR(mvm, "Current Rate is not valid\n");
1785 if (lq_sta->search_better_tbl) { 1794 if (lq_sta->search_better_tbl) {
1786 /* revert to active table if search table is not valid*/ 1795 /* revert to active table if search table is not valid*/
1787 tbl->lq_type = LQ_NONE; 1796 rate->type = LQ_NONE;
1788 lq_sta->search_better_tbl = 0; 1797 lq_sta->search_better_tbl = 0;
1789 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1798 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1790 /* get "active" rate info */ 1799 rs_update_rate_tbl(mvm, sta, lq_sta, &tbl->rate);
1791 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
1792 rs_update_rate_tbl(mvm, sta, lq_sta, tbl, index);
1793 } 1800 }
1794 return; 1801 return;
1795 } 1802 }
@@ -1806,6 +1813,9 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1806 index = lq_sta->max_rate_idx; 1813 index = lq_sta->max_rate_idx;
1807 update_lq = 1; 1814 update_lq = 1;
1808 window = &(tbl->win[index]); 1815 window = &(tbl->win[index]);
1816 IWL_DEBUG_RATE(mvm,
1817 "Forcing user max rate %d\n",
1818 index);
1809 goto lq_update; 1819 goto lq_update;
1810 } 1820 }
1811 1821
@@ -1822,8 +1832,9 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1822 if ((fail_count < IWL_RATE_MIN_FAILURE_TH) && 1832 if ((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
1823 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) { 1833 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) {
1824 IWL_DEBUG_RATE(mvm, 1834 IWL_DEBUG_RATE(mvm,
1825 "LQ: still below TH. succ=%d total=%d for index %d\n", 1835 "(%s: %d): Test Window: succ %d total %d\n",
1826 window->success_counter, window->counter, index); 1836 rs_pretty_lq_type(rate->type),
1837 index, window->success_counter, window->counter);
1827 1838
1828 /* Can't calculate this yet; not enough history */ 1839 /* Can't calculate this yet; not enough history */
1829 window->average_tpt = IWL_INVALID_VALUE; 1840 window->average_tpt = IWL_INVALID_VALUE;
@@ -1838,8 +1849,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1838 * actual average throughput */ 1849 * actual average throughput */
1839 if (window->average_tpt != ((window->success_ratio * 1850 if (window->average_tpt != ((window->success_ratio *
1840 tbl->expected_tpt[index] + 64) / 128)) { 1851 tbl->expected_tpt[index] + 64) / 128)) {
1841 IWL_ERR(mvm,
1842 "expected_tpt should have been calculated by now\n");
1843 window->average_tpt = ((window->success_ratio * 1852 window->average_tpt = ((window->success_ratio *
1844 tbl->expected_tpt[index] + 64) / 128); 1853 tbl->expected_tpt[index] + 64) / 128);
1845 } 1854 }
@@ -1851,34 +1860,33 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1851 * continuing to use the setup that we've been trying. */ 1860 * continuing to use the setup that we've been trying. */
1852 if (window->average_tpt > lq_sta->last_tpt) { 1861 if (window->average_tpt > lq_sta->last_tpt) {
1853 IWL_DEBUG_RATE(mvm, 1862 IWL_DEBUG_RATE(mvm,
1854 "LQ: SWITCHING TO NEW TABLE suc=%d cur-tpt=%d old-tpt=%d\n", 1863 "SWITCHING TO NEW TABLE SR: %d "
1864 "cur-tpt %d old-tpt %d\n",
1855 window->success_ratio, 1865 window->success_ratio,
1856 window->average_tpt, 1866 window->average_tpt,
1857 lq_sta->last_tpt); 1867 lq_sta->last_tpt);
1858 1868
1859 if (!is_legacy(tbl->lq_type))
1860 lq_sta->enable_counter = 1;
1861
1862 /* Swap tables; "search" becomes "active" */ 1869 /* Swap tables; "search" becomes "active" */
1863 lq_sta->active_tbl = active_tbl; 1870 lq_sta->active_tbl = active_tbl;
1864 current_tpt = window->average_tpt; 1871 current_tpt = window->average_tpt;
1865 /* Else poor success; go back to mode in "active" table */ 1872 /* Else poor success; go back to mode in "active" table */
1866 } else { 1873 } else {
1867 IWL_DEBUG_RATE(mvm, 1874 IWL_DEBUG_RATE(mvm,
1868 "LQ: GOING BACK TO THE OLD TABLE suc=%d cur-tpt=%d old-tpt=%d\n", 1875 "GOING BACK TO THE OLD TABLE: SR %d "
1876 "cur-tpt %d old-tpt %d\n",
1869 window->success_ratio, 1877 window->success_ratio,
1870 window->average_tpt, 1878 window->average_tpt,
1871 lq_sta->last_tpt); 1879 lq_sta->last_tpt);
1872 1880
1873 /* Nullify "search" table */ 1881 /* Nullify "search" table */
1874 tbl->lq_type = LQ_NONE; 1882 rate->type = LQ_NONE;
1875 1883
1876 /* Revert to "active" table */ 1884 /* Revert to "active" table */
1877 active_tbl = lq_sta->active_tbl; 1885 active_tbl = lq_sta->active_tbl;
1878 tbl = &(lq_sta->lq_info[active_tbl]); 1886 tbl = &(lq_sta->lq_info[active_tbl]);
1879 1887
1880 /* Revert to "active" rate and throughput info */ 1888 /* Revert to "active" rate and throughput info */
1881 index = iwl_hwrate_to_plcp_idx(tbl->current_rate); 1889 index = tbl->rate.index;
1882 current_tpt = lq_sta->last_tpt; 1890 current_tpt = lq_sta->last_tpt;
1883 1891
1884 /* Need to set up a new rate table in uCode */ 1892 /* Need to set up a new rate table in uCode */
@@ -1894,8 +1902,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1894 1902
1895 /* (Else) not in search of better modulation mode, try for better 1903 /* (Else) not in search of better modulation mode, try for better
1896 * starting rate, while staying in this mode. */ 1904 * starting rate, while staying in this mode. */
1897 high_low = rs_get_adjacent_rate(mvm, index, rate_scale_index_msk, 1905 high_low = rs_get_adjacent_rate(mvm, index, rate_mask, rate->type);
1898 tbl->lq_type);
1899 low = high_low & 0xff; 1906 low = high_low & 0xff;
1900 high = (high_low >> 8) & 0xff; 1907 high = (high_low >> 8) & 0xff;
1901 1908
@@ -1913,118 +1920,58 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1913 if (high != IWL_RATE_INVALID) 1920 if (high != IWL_RATE_INVALID)
1914 high_tpt = tbl->win[high].average_tpt; 1921 high_tpt = tbl->win[high].average_tpt;
1915 1922
1916 scale_action = 0; 1923 IWL_DEBUG_RATE(mvm,
1917 1924 "(%s: %d): cur_tpt %d SR %d low %d high %d low_tpt %d high_tpt %d\n",
1918 /* Too many failures, decrease rate */ 1925 rs_pretty_lq_type(rate->type), index, current_tpt, sr,
1919 if ((sr <= IWL_RATE_DECREASE_TH) || (current_tpt == 0)) { 1926 low, high, low_tpt, high_tpt);
1920 IWL_DEBUG_RATE(mvm,
1921 "decrease rate because of low success_ratio\n");
1922 scale_action = -1;
1923 /* No throughput measured yet for adjacent rates; try increase. */
1924 } else if ((low_tpt == IWL_INVALID_VALUE) &&
1925 (high_tpt == IWL_INVALID_VALUE)) {
1926 if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH)
1927 scale_action = 1;
1928 else if (low != IWL_RATE_INVALID)
1929 scale_action = 0;
1930 }
1931
1932 /* Both adjacent throughputs are measured, but neither one has better
1933 * throughput; we're using the best rate, don't change it! */
1934 else if ((low_tpt != IWL_INVALID_VALUE) &&
1935 (high_tpt != IWL_INVALID_VALUE) &&
1936 (low_tpt < current_tpt) &&
1937 (high_tpt < current_tpt))
1938 scale_action = 0;
1939
1940 /* At least one adjacent rate's throughput is measured,
1941 * and may have better performance. */
1942 else {
1943 /* Higher adjacent rate's throughput is measured */
1944 if (high_tpt != IWL_INVALID_VALUE) {
1945 /* Higher rate has better throughput */
1946 if (high_tpt > current_tpt &&
1947 sr >= IWL_RATE_INCREASE_TH) {
1948 scale_action = 1;
1949 } else {
1950 scale_action = 0;
1951 }
1952
1953 /* Lower adjacent rate's throughput is measured */
1954 } else if (low_tpt != IWL_INVALID_VALUE) {
1955 /* Lower rate has better throughput */
1956 if (low_tpt > current_tpt) {
1957 IWL_DEBUG_RATE(mvm,
1958 "decrease rate because of low tpt\n");
1959 scale_action = -1;
1960 } else if (sr >= IWL_RATE_INCREASE_TH) {
1961 scale_action = 1;
1962 }
1963 }
1964 }
1965
1966 /* Sanity check; asked for decrease, but success rate or throughput
1967 * has been good at old rate. Don't change it. */
1968 if ((scale_action == -1) && (low != IWL_RATE_INVALID) &&
1969 ((sr > IWL_RATE_HIGH_TH) ||
1970 (current_tpt > (100 * tbl->expected_tpt[low]))))
1971 scale_action = 0;
1972 1927
1973 if ((le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >= 1928 scale_action = rs_get_rate_action(mvm, tbl, sr, low, high,
1974 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && (is_mimo(tbl->lq_type))) { 1929 current_tpt, low_tpt, high_tpt);
1975 if (lq_sta->last_bt_traffic >
1976 le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)) {
1977 /*
1978 * don't set scale_action, don't want to scale up if
1979 * the rate scale doesn't otherwise think that is a
1980 * good idea.
1981 */
1982 } else if (lq_sta->last_bt_traffic <=
1983 le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)) {
1984 scale_action = -1;
1985 }
1986 }
1987 lq_sta->last_bt_traffic =
1988 le32_to_cpu(mvm->last_bt_notif.bt_activity_grading);
1989 1930
1990 if ((le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >= 1931 /* Force a search in case BT doesn't like us being in MIMO */
1991 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && is_mimo(tbl->lq_type)) { 1932 if (is_mimo(rate) &&
1992 /* search for a new modulation */ 1933 !iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) {
1934 IWL_DEBUG_RATE(mvm,
1935 "BT Coex forbids MIMO. Search for new config\n");
1993 rs_stay_in_table(lq_sta, true); 1936 rs_stay_in_table(lq_sta, true);
1994 goto lq_update; 1937 goto lq_update;
1995 } 1938 }
1996 1939
1997 switch (scale_action) { 1940 switch (scale_action) {
1998 case -1: 1941 case RS_ACTION_DOWNSCALE:
1999 /* Decrease starting rate, update uCode's rate table */ 1942 /* Decrease starting rate, update uCode's rate table */
2000 if (low != IWL_RATE_INVALID) { 1943 if (low != IWL_RATE_INVALID) {
2001 update_lq = 1; 1944 update_lq = 1;
2002 index = low; 1945 index = low;
1946 } else {
1947 IWL_DEBUG_RATE(mvm,
1948 "At the bottom rate. Can't decrease\n");
2003 } 1949 }
2004 1950
2005 break; 1951 break;
2006 case 1: 1952 case RS_ACTION_UPSCALE:
2007 /* Increase starting rate, update uCode's rate table */ 1953 /* Increase starting rate, update uCode's rate table */
2008 if (high != IWL_RATE_INVALID) { 1954 if (high != IWL_RATE_INVALID) {
2009 update_lq = 1; 1955 update_lq = 1;
2010 index = high; 1956 index = high;
1957 } else {
1958 IWL_DEBUG_RATE(mvm,
1959 "At the top rate. Can't increase\n");
2011 } 1960 }
2012 1961
2013 break; 1962 break;
2014 case 0: 1963 case RS_ACTION_STAY:
2015 /* No change */ 1964 /* No change */
2016 default: 1965 default:
2017 break; 1966 break;
2018 } 1967 }
2019 1968
2020 IWL_DEBUG_RATE(mvm,
2021 "choose rate scale index %d action %d low %d high %d type %d\n",
2022 index, scale_action, low, high, tbl->lq_type);
2023
2024lq_update: 1969lq_update:
2025 /* Replace uCode's rate table for the destination station. */ 1970 /* Replace uCode's rate table for the destination station. */
2026 if (update_lq) 1971 if (update_lq) {
2027 rs_update_rate_tbl(mvm, sta, lq_sta, tbl, index); 1972 tbl->rate.index = index;
1973 rs_update_rate_tbl(mvm, sta, lq_sta, &tbl->rate);
1974 }
2028 1975
2029 rs_stay_in_table(lq_sta, false); 1976 rs_stay_in_table(lq_sta, false);
2030 1977
@@ -2035,20 +1982,29 @@ lq_update:
2035 * 3) Allowing a new search 1982 * 3) Allowing a new search
2036 */ 1983 */
2037 if (!update_lq && !done_search && 1984 if (!update_lq && !done_search &&
2038 !lq_sta->stay_in_tbl && window->counter) { 1985 lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED
1986 && window->counter) {
1987 enum rs_column next_column;
1988
2039 /* Save current throughput to compare with "search" throughput*/ 1989 /* Save current throughput to compare with "search" throughput*/
2040 lq_sta->last_tpt = current_tpt; 1990 lq_sta->last_tpt = current_tpt;
2041 1991
2042 /* Select a new "search" modulation mode to try. 1992 IWL_DEBUG_RATE(mvm,
2043 * If one is found, set up the new "search" table. */ 1993 "Start Search: update_lq %d done_search %d rs_state %d win->counter %d\n",
2044 if (is_legacy(tbl->lq_type)) 1994 update_lq, done_search, lq_sta->rs_state,
2045 rs_move_legacy_other(mvm, lq_sta, sta, index); 1995 window->counter);
2046 else if (is_siso(tbl->lq_type)) 1996
2047 rs_move_siso_to_other(mvm, lq_sta, sta, index); 1997 next_column = rs_get_next_column(mvm, lq_sta, sta, tbl);
2048 else if (is_mimo2(tbl->lq_type)) 1998 if (next_column != RS_COLUMN_INVALID) {
2049 rs_move_mimo2_to_other(mvm, lq_sta, sta, index); 1999 int ret = rs_switch_to_column(mvm, lq_sta, sta,
2050 else 2000 next_column);
2051 WARN_ON_ONCE(1); 2001 if (!ret)
2002 lq_sta->search_better_tbl = 1;
2003 } else {
2004 IWL_DEBUG_RATE(mvm,
2005 "No more columns to explore in search cycle. Go to RS_STATE_SEARCH_CYCLE_ENDED\n");
2006 lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_ENDED;
2007 }
2052 2008
2053 /* If new "search" mode was selected, set up in uCode table */ 2009 /* If new "search" mode was selected, set up in uCode table */
2054 if (lq_sta->search_better_tbl) { 2010 if (lq_sta->search_better_tbl) {
@@ -2058,36 +2014,31 @@ lq_update:
2058 rs_rate_scale_clear_window(&(tbl->win[i])); 2014 rs_rate_scale_clear_window(&(tbl->win[i]));
2059 2015
2060 /* Use new "search" start rate */ 2016 /* Use new "search" start rate */
2061 index = iwl_hwrate_to_plcp_idx(tbl->current_rate); 2017 index = tbl->rate.index;
2062 2018
2063 IWL_DEBUG_RATE(mvm, 2019 rs_dump_rate(mvm, &tbl->rate,
2064 "Switch current mcs: %X index: %d\n", 2020 "Switch to SEARCH TABLE:");
2065 tbl->current_rate, index); 2021 rs_fill_lq_cmd(mvm, sta, lq_sta, &tbl->rate);
2066 rs_fill_link_cmd(mvm, sta, lq_sta, tbl->current_rate); 2022 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
2067 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
2068 } else { 2023 } else {
2069 done_search = 1; 2024 done_search = 1;
2070 } 2025 }
2071 } 2026 }
2072 2027
2073 if (done_search && !lq_sta->stay_in_tbl) { 2028 if (done_search && lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_ENDED) {
2074 /* If the "active" (non-search) mode was legacy, 2029 /* If the "active" (non-search) mode was legacy,
2075 * and we've tried switching antennas, 2030 * and we've tried switching antennas,
2076 * but we haven't been able to try HT modes (not available), 2031 * but we haven't been able to try HT modes (not available),
2077 * stay with best antenna legacy modulation for a while 2032 * stay with best antenna legacy modulation for a while
2078 * before next round of mode comparisons. */ 2033 * before next round of mode comparisons. */
2079 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); 2034 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
2080 if (is_legacy(tbl1->lq_type) && !sta->ht_cap.ht_supported && 2035 if (is_legacy(&tbl1->rate) && !sta->ht_cap.ht_supported) {
2081 lq_sta->action_counter > tbl1->max_search) {
2082 IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n"); 2036 IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n");
2083 rs_set_stay_in_table(mvm, 1, lq_sta); 2037 rs_set_stay_in_table(mvm, 1, lq_sta);
2084 } 2038 } else {
2085
2086 /* If we're in an HT mode, and all 3 mode switch actions 2039 /* If we're in an HT mode, and all 3 mode switch actions
2087 * have been tried and compared, stay in this best modulation 2040 * have been tried and compared, stay in this best modulation
2088 * mode for a while before next round of mode comparisons. */ 2041 * mode for a while before next round of mode comparisons. */
2089 if (lq_sta->enable_counter &&
2090 (lq_sta->action_counter >= tbl1->max_search)) {
2091 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && 2042 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
2092 (lq_sta->tx_agg_tid_en & (1 << tid)) && 2043 (lq_sta->tx_agg_tid_en & (1 << tid)) &&
2093 (tid != IWL_MAX_TID_COUNT)) { 2044 (tid != IWL_MAX_TID_COUNT)) {
@@ -2105,7 +2056,6 @@ lq_update:
2105 } 2056 }
2106 2057
2107out: 2058out:
2108 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, index);
2109 lq_sta->last_txrate_idx = index; 2059 lq_sta->last_txrate_idx = index;
2110} 2060}
2111 2061
@@ -2126,12 +2076,12 @@ out:
2126static void rs_initialize_lq(struct iwl_mvm *mvm, 2076static void rs_initialize_lq(struct iwl_mvm *mvm,
2127 struct ieee80211_sta *sta, 2077 struct ieee80211_sta *sta,
2128 struct iwl_lq_sta *lq_sta, 2078 struct iwl_lq_sta *lq_sta,
2129 enum ieee80211_band band) 2079 enum ieee80211_band band,
2080 bool init)
2130{ 2081{
2131 struct iwl_scale_tbl_info *tbl; 2082 struct iwl_scale_tbl_info *tbl;
2132 int rate_idx; 2083 struct rs_rate *rate;
2133 int i; 2084 int i;
2134 u32 rate;
2135 u8 active_tbl = 0; 2085 u8 active_tbl = 0;
2136 u8 valid_tx_ant; 2086 u8 valid_tx_ant;
2137 2087
@@ -2148,27 +2098,30 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
2148 active_tbl = 1 - lq_sta->active_tbl; 2098 active_tbl = 1 - lq_sta->active_tbl;
2149 2099
2150 tbl = &(lq_sta->lq_info[active_tbl]); 2100 tbl = &(lq_sta->lq_info[active_tbl]);
2101 rate = &tbl->rate;
2151 2102
2152 if ((i < 0) || (i >= IWL_RATE_COUNT)) 2103 if ((i < 0) || (i >= IWL_RATE_COUNT))
2153 i = 0; 2104 i = 0;
2154 2105
2155 rate = iwl_rates[i].plcp; 2106 rate->index = i;
2156 tbl->ant_type = first_antenna(valid_tx_ant); 2107 rate->ant = first_antenna(valid_tx_ant);
2157 rate |= tbl->ant_type << RATE_MCS_ANT_POS; 2108 rate->sgi = false;
2158 2109 rate->bw = RATE_MCS_CHAN_WIDTH_20;
2159 if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE) 2110 if (band == IEEE80211_BAND_5GHZ)
2160 rate |= RATE_MCS_CCK_MSK; 2111 rate->type = LQ_LEGACY_A;
2112 else
2113 rate->type = LQ_LEGACY_G;
2161 2114
2162 rs_get_tbl_info_from_mcs(rate, band, tbl, &rate_idx); 2115 WARN_ON_ONCE(rate->ant != ANT_A && rate->ant != ANT_B);
2163 if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type)) 2116 if (rate->ant == ANT_A)
2164 rs_toggle_antenna(valid_tx_ant, &rate, tbl); 2117 tbl->column = RS_COLUMN_LEGACY_ANT_A;
2118 else
2119 tbl->column = RS_COLUMN_LEGACY_ANT_B;
2165 2120
2166 rate = rate_n_flags_from_tbl(mvm, tbl, rate_idx);
2167 tbl->current_rate = rate;
2168 rs_set_expected_tpt_table(lq_sta, tbl); 2121 rs_set_expected_tpt_table(lq_sta, tbl);
2169 rs_fill_link_cmd(NULL, NULL, lq_sta, rate); 2122 rs_fill_lq_cmd(mvm, sta, lq_sta, rate);
2170 /* TODO restore station should remember the lq cmd */ 2123 /* TODO restore station should remember the lq cmd */
2171 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_SYNC, true); 2124 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, init);
2172} 2125}
2173 2126
2174static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta, 2127static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
@@ -2182,8 +2135,6 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
2182 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2135 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2183 struct iwl_lq_sta *lq_sta = mvm_sta; 2136 struct iwl_lq_sta *lq_sta = mvm_sta;
2184 2137
2185 IWL_DEBUG_RATE_LIMIT(mvm, "rate scale calculate new rate for skb\n");
2186
2187 /* Get max rate if user set max rate */ 2138 /* Get max rate if user set max rate */
2188 if (lq_sta) { 2139 if (lq_sta) {
2189 lq_sta->max_rate_idx = txrc->max_rate_idx; 2140 lq_sta->max_rate_idx = txrc->max_rate_idx;
@@ -2242,11 +2193,59 @@ static int rs_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap,
2242 return -1; 2193 return -1;
2243} 2194}
2244 2195
2196static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
2197 struct ieee80211_sta_vht_cap *vht_cap,
2198 struct iwl_lq_sta *lq_sta)
2199{
2200 int i;
2201 int highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 1);
2202
2203 if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
2204 for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
2205 if (i == IWL_RATE_9M_INDEX)
2206 continue;
2207
2208 /* Disable MCS9 as a workaround */
2209 if (i == IWL_RATE_MCS_9_INDEX)
2210 continue;
2211
2212 /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */
2213 if (i == IWL_RATE_MCS_9_INDEX &&
2214 sta->bandwidth == IEEE80211_STA_RX_BW_20)
2215 continue;
2216
2217 lq_sta->active_siso_rate |= BIT(i);
2218 }
2219 }
2220
2221 if (sta->rx_nss < 2)
2222 return;
2223
2224 highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 2);
2225 if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
2226 for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
2227 if (i == IWL_RATE_9M_INDEX)
2228 continue;
2229
2230 /* Disable MCS9 as a workaround */
2231 if (i == IWL_RATE_MCS_9_INDEX)
2232 continue;
2233
2234 /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */
2235 if (i == IWL_RATE_MCS_9_INDEX &&
2236 sta->bandwidth == IEEE80211_STA_RX_BW_20)
2237 continue;
2238
2239 lq_sta->active_mimo2_rate |= BIT(i);
2240 }
2241 }
2242}
2243
2245/* 2244/*
2246 * Called after adding a new station to initialize rate scaling 2245 * Called after adding a new station to initialize rate scaling
2247 */ 2246 */
2248void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 2247void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2249 enum ieee80211_band band) 2248 enum ieee80211_band band, bool init)
2250{ 2249{
2251 int i, j; 2250 int i, j;
2252 struct ieee80211_hw *hw = mvm->hw; 2251 struct ieee80211_hw *hw = mvm->hw;
@@ -2259,6 +2258,8 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2259 2258
2260 sta_priv = (struct iwl_mvm_sta *)sta->drv_priv; 2259 sta_priv = (struct iwl_mvm_sta *)sta->drv_priv;
2261 lq_sta = &sta_priv->lq_sta; 2260 lq_sta = &sta_priv->lq_sta;
2261 memset(lq_sta, 0, sizeof(*lq_sta));
2262
2262 sband = hw->wiphy->bands[band]; 2263 sband = hw->wiphy->bands[band];
2263 2264
2264 lq_sta->lq.sta_id = sta_priv->sta_id; 2265 lq_sta->lq.sta_id = sta_priv->sta_id;
@@ -2268,7 +2269,6 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2268 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); 2269 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2269 2270
2270 lq_sta->flush_timer = 0; 2271 lq_sta->flush_timer = 0;
2271 lq_sta->supp_rates = sta->supp_rates[sband->band];
2272 2272
2273 IWL_DEBUG_RATE(mvm, 2273 IWL_DEBUG_RATE(mvm,
2274 "LQ: *** rate scale station global init for station %d ***\n", 2274 "LQ: *** rate scale station global init for station %d ***\n",
@@ -2308,27 +2308,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2308 2308
2309 lq_sta->is_vht = false; 2309 lq_sta->is_vht = false;
2310 } else { 2310 } else {
2311 int highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 1); 2311 rs_vht_set_enabled_rates(sta, vht_cap, lq_sta);
2312 if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
2313 for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
2314 if (i == IWL_RATE_9M_INDEX)
2315 continue;
2316
2317 lq_sta->active_siso_rate |= BIT(i);
2318 }
2319 }
2320
2321 highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 2);
2322 if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
2323 for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
2324 if (i == IWL_RATE_9M_INDEX)
2325 continue;
2326
2327 lq_sta->active_mimo2_rate |= BIT(i);
2328 }
2329 }
2330
2331 /* TODO: avoid MCS9 in 20Mhz which isn't valid for 11ac */
2332 lq_sta->is_vht = true; 2312 lq_sta->is_vht = true;
2333 } 2313 }
2334 2314
@@ -2341,15 +2321,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2341 /* These values will be overridden later */ 2321 /* These values will be overridden later */
2342 lq_sta->lq.single_stream_ant_msk = 2322 lq_sta->lq.single_stream_ant_msk =
2343 first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); 2323 first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
2344 lq_sta->lq.dual_stream_ant_msk = 2324 lq_sta->lq.dual_stream_ant_msk = ANT_AB;
2345 iwl_fw_valid_tx_ant(mvm->fw) &
2346 ~first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
2347 if (!lq_sta->lq.dual_stream_ant_msk) {
2348 lq_sta->lq.dual_stream_ant_msk = ANT_AB;
2349 } else if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) == 2) {
2350 lq_sta->lq.dual_stream_ant_msk =
2351 iwl_fw_valid_tx_ant(mvm->fw);
2352 }
2353 2325
2354 /* as default allow aggregation for all tids */ 2326 /* as default allow aggregation for all tids */
2355 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; 2327 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
@@ -2364,121 +2336,184 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2364 lq_sta->dbg_fixed_rate = 0; 2336 lq_sta->dbg_fixed_rate = 0;
2365#endif 2337#endif
2366 2338
2367 rs_initialize_lq(mvm, sta, lq_sta, band); 2339 rs_initialize_lq(mvm, sta, lq_sta, band, init);
2368} 2340}
2369 2341
2370static void rs_fill_link_cmd(struct iwl_mvm *mvm, 2342static void rs_rate_update(void *mvm_r,
2371 struct ieee80211_sta *sta, 2343 struct ieee80211_supported_band *sband,
2372 struct iwl_lq_sta *lq_sta, u32 new_rate) 2344 struct cfg80211_chan_def *chandef,
2345 struct ieee80211_sta *sta, void *priv_sta,
2346 u32 changed)
2347{
2348 u8 tid;
2349 struct iwl_op_mode *op_mode =
2350 (struct iwl_op_mode *)mvm_r;
2351 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
2352
2353 /* Stop any ongoing aggregations as rs starts off assuming no agg */
2354 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
2355 ieee80211_stop_tx_ba_session(sta, tid);
2356
2357 iwl_mvm_rs_rate_init(mvm, sta, sband->band, false);
2358}
2359
2360#ifdef CONFIG_MAC80211_DEBUGFS
2361static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm,
2362 struct iwl_lq_cmd *lq_cmd,
2363 enum ieee80211_band band,
2364 u32 ucode_rate)
2365{
2366 struct rs_rate rate;
2367 int i;
2368 int num_rates = ARRAY_SIZE(lq_cmd->rs_table);
2369 __le32 ucode_rate_le32 = cpu_to_le32(ucode_rate);
2370
2371 for (i = 0; i < num_rates; i++)
2372 lq_cmd->rs_table[i] = ucode_rate_le32;
2373
2374 rs_rate_from_ucode_rate(ucode_rate, band, &rate);
2375
2376 if (is_mimo(&rate))
2377 lq_cmd->mimo_delim = num_rates - 1;
2378 else
2379 lq_cmd->mimo_delim = 0;
2380}
2381#endif /* CONFIG_MAC80211_DEBUGFS */
2382
2383static void rs_fill_rates_for_column(struct iwl_mvm *mvm,
2384 struct iwl_lq_sta *lq_sta,
2385 struct rs_rate *rate,
2386 __le32 *rs_table, int *rs_table_index,
2387 int num_rates, int num_retries,
2388 u8 valid_tx_ant, bool toggle_ant)
2389{
2390 int i, j;
2391 __le32 ucode_rate;
2392 bool bottom_reached = false;
2393 int prev_rate_idx = rate->index;
2394 int end = LINK_QUAL_MAX_RETRY_NUM;
2395 int index = *rs_table_index;
2396
2397 for (i = 0; i < num_rates && index < end; i++) {
2398 ucode_rate = cpu_to_le32(ucode_rate_from_rs_rate(mvm, rate));
2399 for (j = 0; j < num_retries && index < end; j++, index++)
2400 rs_table[index] = ucode_rate;
2401
2402 if (toggle_ant)
2403 rs_toggle_antenna(valid_tx_ant, rate);
2404
2405 prev_rate_idx = rate->index;
2406 bottom_reached = rs_get_lower_rate_in_column(lq_sta, rate);
2407 if (bottom_reached && !is_legacy(rate))
2408 break;
2409 }
2410
2411 if (!bottom_reached)
2412 rate->index = prev_rate_idx;
2413
2414 *rs_table_index = index;
2415}
2416
2417/* Building the rate table is non trivial. When we're in MIMO2/VHT/80Mhz/SGI
2418 * column the rate table should look like this:
2419 *
2420 * rate[0] 0x400D019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
2421 * rate[1] 0x400D019 VHT | ANT: AB BW: 80Mhz MCS: 9 NSS: 2 SGI
2422 * rate[2] 0x400D018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
2423 * rate[3] 0x400D018 VHT | ANT: AB BW: 80Mhz MCS: 8 NSS: 2 SGI
2424 * rate[4] 0x400D017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
2425 * rate[5] 0x400D017 VHT | ANT: AB BW: 80Mhz MCS: 7 NSS: 2 SGI
2426 * rate[6] 0x4005007 VHT | ANT: A BW: 80Mhz MCS: 7 NSS: 1 NGI
2427 * rate[7] 0x4009006 VHT | ANT: B BW: 80Mhz MCS: 6 NSS: 1 NGI
2428 * rate[8] 0x4005005 VHT | ANT: A BW: 80Mhz MCS: 5 NSS: 1 NGI
2429 * rate[9] 0x800B Legacy | ANT: B Rate: 36 Mbps
2430 * rate[10] 0x4009 Legacy | ANT: A Rate: 24 Mbps
2431 * rate[11] 0x8007 Legacy | ANT: B Rate: 18 Mbps
2432 * rate[12] 0x4005 Legacy | ANT: A Rate: 12 Mbps
2433 * rate[13] 0x800F Legacy | ANT: B Rate: 9 Mbps
2434 * rate[14] 0x400D Legacy | ANT: A Rate: 6 Mbps
2435 * rate[15] 0x800D Legacy | ANT: B Rate: 6 Mbps
2436 */
2437static void rs_build_rates_table(struct iwl_mvm *mvm,
2438 struct iwl_lq_sta *lq_sta,
2439 const struct rs_rate *initial_rate)
2373{ 2440{
2374 struct iwl_scale_tbl_info tbl_type; 2441 struct rs_rate rate;
2375 int index = 0; 2442 int num_rates, num_retries, index = 0;
2376 int rate_idx;
2377 int repeat_rate = 0;
2378 u8 ant_toggle_cnt = 0;
2379 u8 use_ht_possible = 1;
2380 u8 valid_tx_ant = 0; 2443 u8 valid_tx_ant = 0;
2381 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; 2444 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
2445 bool toggle_ant = false;
2382 2446
2383 /* Override starting rate (index 0) if needed for debug purposes */ 2447 memcpy(&rate, initial_rate, sizeof(rate));
2384 rs_dbgfs_set_mcs(lq_sta, &new_rate);
2385 2448
2386 /* Interpret new_rate (rate_n_flags) */ 2449 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
2387 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
2388 &tbl_type, &rate_idx);
2389 2450
2390 /* How many times should we repeat the initial rate? */ 2451 if (is_siso(&rate)) {
2391 if (is_legacy(tbl_type.lq_type)) { 2452 num_rates = RS_INITIAL_SISO_NUM_RATES;
2392 ant_toggle_cnt = 1; 2453 num_retries = RS_HT_VHT_RETRIES_PER_RATE;
2393 repeat_rate = IWL_NUMBER_TRY; 2454 } else if (is_mimo(&rate)) {
2455 num_rates = RS_INITIAL_MIMO_NUM_RATES;
2456 num_retries = RS_HT_VHT_RETRIES_PER_RATE;
2394 } else { 2457 } else {
2395 repeat_rate = min(IWL_HT_NUMBER_TRY, 2458 num_rates = RS_INITIAL_LEGACY_NUM_RATES;
2396 LINK_QUAL_AGG_DISABLE_START_DEF - 1); 2459 num_retries = RS_LEGACY_RETRIES_PER_RATE;
2460 toggle_ant = true;
2397 } 2461 }
2398 2462
2399 lq_cmd->mimo_delim = is_mimo(tbl_type.lq_type) ? 1 : 0; 2463 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index,
2400 2464 num_rates, num_retries, valid_tx_ant,
2401 /* Fill 1st table entry (index 0) */ 2465 toggle_ant);
2402 lq_cmd->rs_table[index] = cpu_to_le32(new_rate);
2403
2404 if (num_of_ant(tbl_type.ant_type) == 1)
2405 lq_cmd->single_stream_ant_msk = tbl_type.ant_type;
2406 else if (num_of_ant(tbl_type.ant_type) == 2)
2407 lq_cmd->dual_stream_ant_msk = tbl_type.ant_type;
2408 /* otherwise we don't modify the existing value */
2409
2410 index++;
2411 repeat_rate--;
2412 if (mvm)
2413 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
2414
2415 /* Fill rest of rate table */
2416 while (index < LINK_QUAL_MAX_RETRY_NUM) {
2417 /* Repeat initial/next rate.
2418 * For legacy IWL_NUMBER_TRY == 1, this loop will not execute.
2419 * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */
2420 while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {
2421 if (is_legacy(tbl_type.lq_type)) {
2422 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
2423 ant_toggle_cnt++;
2424 else if (mvm &&
2425 rs_toggle_antenna(valid_tx_ant,
2426 &new_rate, &tbl_type))
2427 ant_toggle_cnt = 1;
2428 }
2429 2466
2430 /* Override next rate if needed for debug purposes */ 2467 rs_get_lower_rate_down_column(lq_sta, &rate);
2431 rs_dbgfs_set_mcs(lq_sta, &new_rate);
2432 2468
2433 /* Fill next table entry */ 2469 if (is_siso(&rate)) {
2434 lq_cmd->rs_table[index] = 2470 num_rates = RS_SECONDARY_SISO_NUM_RATES;
2435 cpu_to_le32(new_rate); 2471 num_retries = RS_SECONDARY_SISO_RETRIES;
2436 repeat_rate--; 2472 } else if (is_legacy(&rate)) {
2437 index++; 2473 num_rates = RS_SECONDARY_LEGACY_NUM_RATES;
2438 } 2474 num_retries = RS_LEGACY_RETRIES_PER_RATE;
2475 } else {
2476 WARN_ON_ONCE(1);
2477 }
2439 2478
2440 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, 2479 toggle_ant = true;
2441 &rate_idx);
2442
2443 /* Indicate to uCode which entries might be MIMO.
2444 * If initial rate was MIMO, this will finally end up
2445 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
2446 if (is_mimo(tbl_type.lq_type))
2447 lq_cmd->mimo_delim = index;
2448
2449 /* Get next rate */
2450 new_rate = rs_get_lower_rate(lq_sta, &tbl_type, rate_idx,
2451 use_ht_possible);
2452
2453 /* How many times should we repeat the next rate? */
2454 if (is_legacy(tbl_type.lq_type)) {
2455 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
2456 ant_toggle_cnt++;
2457 else if (mvm &&
2458 rs_toggle_antenna(valid_tx_ant,
2459 &new_rate, &tbl_type))
2460 ant_toggle_cnt = 1;
2461
2462 repeat_rate = IWL_NUMBER_TRY;
2463 } else {
2464 repeat_rate = IWL_HT_NUMBER_TRY;
2465 }
2466 2480
2467 /* Don't allow HT rates after next pass. 2481 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index,
2468 * rs_get_lower_rate() will change type to LQ_LEGACY_A 2482 num_rates, num_retries, valid_tx_ant,
2469 * or LQ_LEGACY_G. 2483 toggle_ant);
2470 */
2471 use_ht_possible = 0;
2472 2484
2473 /* Override next rate if needed for debug purposes */ 2485 rs_get_lower_rate_down_column(lq_sta, &rate);
2474 rs_dbgfs_set_mcs(lq_sta, &new_rate);
2475 2486
2476 /* Fill next table entry */ 2487 num_rates = RS_SECONDARY_LEGACY_NUM_RATES;
2477 lq_cmd->rs_table[index] = cpu_to_le32(new_rate); 2488 num_retries = RS_LEGACY_RETRIES_PER_RATE;
2478 2489
2479 index++; 2490 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index,
2480 repeat_rate--; 2491 num_rates, num_retries, valid_tx_ant,
2481 } 2492 toggle_ant);
2493
2494}
2495
2496static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
2497 struct ieee80211_sta *sta,
2498 struct iwl_lq_sta *lq_sta,
2499 const struct rs_rate *initial_rate)
2500{
2501 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
2502 u8 ant = initial_rate->ant;
2503
2504#ifdef CONFIG_MAC80211_DEBUGFS
2505 if (lq_sta->dbg_fixed_rate) {
2506 rs_build_rates_table_from_fixed(mvm, lq_cmd,
2507 lq_sta->band,
2508 lq_sta->dbg_fixed_rate);
2509 ant = (lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) >>
2510 RATE_MCS_ANT_POS;
2511 } else
2512#endif
2513 rs_build_rates_table(mvm, lq_sta, initial_rate);
2514
2515 if (num_of_ant(ant) == 1)
2516 lq_cmd->single_stream_ant_msk = ant;
2482 2517
2483 lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; 2518 lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
2484 lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; 2519 lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
@@ -2512,31 +2547,83 @@ static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta,
2512} 2547}
2513 2548
2514#ifdef CONFIG_MAC80211_DEBUGFS 2549#ifdef CONFIG_MAC80211_DEBUGFS
2515static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, 2550static int rs_pretty_print_rate(char *buf, const u32 rate)
2516 u32 *rate_n_flags)
2517{ 2551{
2518 struct iwl_mvm *mvm;
2519 u8 valid_tx_ant;
2520 u8 ant_sel_tx;
2521 2552
2522 mvm = lq_sta->drv; 2553 char *type, *bw;
2523 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); 2554 u8 mcs = 0, nss = 0;
2524 if (lq_sta->dbg_fixed_rate) { 2555 u8 ant = (rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS;
2525 ant_sel_tx = 2556
2526 ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) 2557 if (!(rate & RATE_MCS_HT_MSK) &&
2527 >> RATE_MCS_ANT_POS); 2558 !(rate & RATE_MCS_VHT_MSK)) {
2528 if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) { 2559 int index = iwl_hwrate_to_plcp_idx(rate);
2529 *rate_n_flags = lq_sta->dbg_fixed_rate; 2560
2530 IWL_DEBUG_RATE(mvm, "Fixed rate ON\n"); 2561 return sprintf(buf, "Legacy | ANT: %s Rate: %s Mbps\n",
2531 } else { 2562 rs_pretty_ant(ant),
2532 lq_sta->dbg_fixed_rate = 0; 2563 index == IWL_RATE_INVALID ? "BAD" :
2533 IWL_ERR(mvm, 2564 iwl_rate_mcs[index].mbps);
2534 "Invalid antenna selection 0x%X, Valid is 0x%X\n", 2565 }
2535 ant_sel_tx, valid_tx_ant); 2566
2536 IWL_DEBUG_RATE(mvm, "Fixed rate OFF\n"); 2567 if (rate & RATE_MCS_VHT_MSK) {
2537 } 2568 type = "VHT";
2569 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;
2570 nss = ((rate & RATE_VHT_MCS_NSS_MSK)
2571 >> RATE_VHT_MCS_NSS_POS) + 1;
2572 } else if (rate & RATE_MCS_HT_MSK) {
2573 type = "HT";
2574 mcs = rate & RATE_HT_MCS_INDEX_MSK;
2538 } else { 2575 } else {
2539 IWL_DEBUG_RATE(mvm, "Fixed rate OFF\n"); 2576 type = "Unknown"; /* shouldn't happen */
2577 }
2578
2579 switch (rate & RATE_MCS_CHAN_WIDTH_MSK) {
2580 case RATE_MCS_CHAN_WIDTH_20:
2581 bw = "20Mhz";
2582 break;
2583 case RATE_MCS_CHAN_WIDTH_40:
2584 bw = "40Mhz";
2585 break;
2586 case RATE_MCS_CHAN_WIDTH_80:
2587 bw = "80Mhz";
2588 break;
2589 case RATE_MCS_CHAN_WIDTH_160:
2590 bw = "160Mhz";
2591 break;
2592 default:
2593 bw = "BAD BW";
2594 }
2595
2596 return sprintf(buf, "%s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s\n",
2597 type, rs_pretty_ant(ant), bw, mcs, nss,
2598 (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ",
2599 (rate & RATE_MCS_STBC_MSK) ? "STBC " : "",
2600 (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "",
2601 (rate & RATE_MCS_BF_MSK) ? "BF " : "",
2602 (rate & RATE_MCS_ZLF_MSK) ? "ZLF " : "");
2603}
2604
2605/**
2606 * Program the device to use fixed rate for frame transmit
2607 * This is for debugging/testing only
2608 * once the device start use fixed rate, we need to reload the module
2609 * to being back the normal operation.
2610 */
2611static void rs_program_fix_rate(struct iwl_mvm *mvm,
2612 struct iwl_lq_sta *lq_sta)
2613{
2614 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
2615 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2616 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2617
2618 IWL_DEBUG_RATE(mvm, "sta_id %d rate 0x%X\n",
2619 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
2620
2621 if (lq_sta->dbg_fixed_rate) {
2622 struct rs_rate rate;
2623 rs_rate_from_ucode_rate(lq_sta->dbg_fixed_rate,
2624 lq_sta->band, &rate);
2625 rs_fill_lq_cmd(mvm, NULL, lq_sta, &rate);
2626 iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, false);
2540 } 2627 }
2541} 2628}
2542 2629
@@ -2572,15 +2659,14 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2572 char *buff; 2659 char *buff;
2573 int desc = 0; 2660 int desc = 0;
2574 int i = 0; 2661 int i = 0;
2575 int index = 0;
2576 ssize_t ret; 2662 ssize_t ret;
2577 2663
2578 struct iwl_lq_sta *lq_sta = file->private_data; 2664 struct iwl_lq_sta *lq_sta = file->private_data;
2579 struct iwl_mvm *mvm; 2665 struct iwl_mvm *mvm;
2580 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 2666 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2581 2667 struct rs_rate *rate = &tbl->rate;
2582 mvm = lq_sta->drv; 2668 mvm = lq_sta->drv;
2583 buff = kmalloc(1024, GFP_KERNEL); 2669 buff = kmalloc(2048, GFP_KERNEL);
2584 if (!buff) 2670 if (!buff)
2585 return -ENOMEM; 2671 return -ENOMEM;
2586 2672
@@ -2595,23 +2681,23 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2595 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "", 2681 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "",
2596 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : ""); 2682 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : "");
2597 desc += sprintf(buff+desc, "lq type %s\n", 2683 desc += sprintf(buff+desc, "lq type %s\n",
2598 (is_legacy(tbl->lq_type)) ? "legacy" : 2684 (is_legacy(rate)) ? "legacy" :
2599 is_vht(tbl->lq_type) ? "VHT" : "HT"); 2685 is_vht(rate) ? "VHT" : "HT");
2600 if (is_ht(tbl->lq_type)) { 2686 if (!is_legacy(rate)) {
2601 desc += sprintf(buff+desc, " %s", 2687 desc += sprintf(buff+desc, " %s",
2602 (is_siso(tbl->lq_type)) ? "SISO" : "MIMO2"); 2688 (is_siso(rate)) ? "SISO" : "MIMO2");
2603 desc += sprintf(buff+desc, " %s", 2689 desc += sprintf(buff+desc, " %s",
2604 (is_ht20(tbl)) ? "20MHz" : 2690 (is_ht20(rate)) ? "20MHz" :
2605 (is_ht40(tbl)) ? "40MHz" : 2691 (is_ht40(rate)) ? "40MHz" :
2606 (is_ht80(tbl)) ? "80Mhz" : "BAD BW"); 2692 (is_ht80(rate)) ? "80Mhz" : "BAD BW");
2607 desc += sprintf(buff+desc, " %s %s\n", 2693 desc += sprintf(buff+desc, " %s %s\n",
2608 (tbl->is_SGI) ? "SGI" : "", 2694 (rate->sgi) ? "SGI" : "NGI",
2609 (lq_sta->is_agg) ? "AGG on" : ""); 2695 (lq_sta->is_agg) ? "AGG on" : "");
2610 } 2696 }
2611 desc += sprintf(buff+desc, "last tx rate=0x%X\n", 2697 desc += sprintf(buff+desc, "last tx rate=0x%X\n",
2612 lq_sta->last_rate_n_flags); 2698 lq_sta->last_rate_n_flags);
2613 desc += sprintf(buff+desc, 2699 desc += sprintf(buff+desc,
2614 "general: flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n", 2700 "general: flags=0x%X mimo-d=%d s-ant=0x%x d-ant=0x%x\n",
2615 lq_sta->lq.flags, 2701 lq_sta->lq.flags,
2616 lq_sta->lq.mimo_delim, 2702 lq_sta->lq.mimo_delim,
2617 lq_sta->lq.single_stream_ant_msk, 2703 lq_sta->lq.single_stream_ant_msk,
@@ -2631,19 +2717,10 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2631 lq_sta->lq.initial_rate_index[3]); 2717 lq_sta->lq.initial_rate_index[3]);
2632 2718
2633 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { 2719 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
2634 index = iwl_hwrate_to_plcp_idx( 2720 u32 r = le32_to_cpu(lq_sta->lq.rs_table[i]);
2635 le32_to_cpu(lq_sta->lq.rs_table[i])); 2721
2636 if (is_legacy(tbl->lq_type)) { 2722 desc += sprintf(buff+desc, " rate[%d] 0x%X ", i, r);
2637 desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n", 2723 desc += rs_pretty_print_rate(buff+desc, r);
2638 i, le32_to_cpu(lq_sta->lq.rs_table[i]),
2639 iwl_rate_mcs[index].mbps);
2640 } else {
2641 desc += sprintf(buff+desc,
2642 " rate[%d] 0x%X %smbps (%s)\n",
2643 i, le32_to_cpu(lq_sta->lq.rs_table[i]),
2644 iwl_rate_mcs[index].mbps,
2645 iwl_rate_mcs[index].mcs);
2646 }
2647 } 2724 }
2648 2725
2649 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); 2726 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
@@ -2665,6 +2742,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2665 int i, j; 2742 int i, j;
2666 ssize_t ret; 2743 ssize_t ret;
2667 struct iwl_scale_tbl_info *tbl; 2744 struct iwl_scale_tbl_info *tbl;
2745 struct rs_rate *rate;
2668 struct iwl_lq_sta *lq_sta = file->private_data; 2746 struct iwl_lq_sta *lq_sta = file->private_data;
2669 2747
2670 buff = kmalloc(1024, GFP_KERNEL); 2748 buff = kmalloc(1024, GFP_KERNEL);
@@ -2673,16 +2751,17 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2673 2751
2674 for (i = 0; i < LQ_SIZE; i++) { 2752 for (i = 0; i < LQ_SIZE; i++) {
2675 tbl = &(lq_sta->lq_info[i]); 2753 tbl = &(lq_sta->lq_info[i]);
2754 rate = &tbl->rate;
2676 desc += sprintf(buff+desc, 2755 desc += sprintf(buff+desc,
2677 "%s type=%d SGI=%d BW=%s DUP=0\n" 2756 "%s type=%d SGI=%d BW=%s DUP=0\n"
2678 "rate=0x%X\n", 2757 "index=%d\n",
2679 lq_sta->active_tbl == i ? "*" : "x", 2758 lq_sta->active_tbl == i ? "*" : "x",
2680 tbl->lq_type, 2759 rate->type,
2681 tbl->is_SGI, 2760 rate->sgi,
2682 is_ht20(tbl) ? "20Mhz" : 2761 is_ht20(rate) ? "20Mhz" :
2683 is_ht40(tbl) ? "40Mhz" : 2762 is_ht40(rate) ? "40Mhz" :
2684 is_ht80(tbl) ? "80Mhz" : "ERR", 2763 is_ht80(rate) ? "80Mhz" : "ERR",
2685 tbl->current_rate); 2764 rate->index);
2686 for (j = 0; j < IWL_RATE_COUNT; j++) { 2765 for (j = 0; j < IWL_RATE_COUNT; j++) {
2687 desc += sprintf(buff+desc, 2766 desc += sprintf(buff+desc,
2688 "counter=%d success=%d %%=%d\n", 2767 "counter=%d success=%d %%=%d\n",
@@ -2746,6 +2825,7 @@ static struct rate_control_ops rs_mvm_ops = {
2746 .free = rs_free, 2825 .free = rs_free,
2747 .alloc_sta = rs_alloc_sta, 2826 .alloc_sta = rs_alloc_sta,
2748 .free_sta = rs_free_sta, 2827 .free_sta = rs_free_sta,
2828 .rate_update = rs_rate_update,
2749#ifdef CONFIG_MAC80211_DEBUGFS 2829#ifdef CONFIG_MAC80211_DEBUGFS
2750 .add_sta_debugfs = rs_add_debugfs, 2830 .add_sta_debugfs = rs_add_debugfs,
2751 .remove_sta_debugfs = rs_remove_debugfs, 2831 .remove_sta_debugfs = rs_remove_debugfs,
@@ -2778,13 +2858,13 @@ int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
2778 2858
2779 if (enable) { 2859 if (enable) {
2780 if (mvmsta->tx_protection == 0) 2860 if (mvmsta->tx_protection == 0)
2781 lq->flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK; 2861 lq->flags |= LQ_FLAG_USE_RTS_MSK;
2782 mvmsta->tx_protection++; 2862 mvmsta->tx_protection++;
2783 } else { 2863 } else {
2784 mvmsta->tx_protection--; 2864 mvmsta->tx_protection--;
2785 if (mvmsta->tx_protection == 0) 2865 if (mvmsta->tx_protection == 0)
2786 lq->flags &= ~LQ_FLAG_SET_STA_TLC_RTS_MSK; 2866 lq->flags &= ~LQ_FLAG_USE_RTS_MSK;
2787 } 2867 }
2788 2868
2789 return iwl_mvm_send_lq_cmd(mvm, lq, CMD_ASYNC, false); 2869 return iwl_mvm_send_lq_cmd(mvm, lq, false);
2790} 2870}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 5d5344f7070b..7bc6404f6986 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as 6 * under the terms of version 2 of the GNU General Public License as
@@ -155,38 +155,7 @@ enum {
155#define IWL_RATE_SCALE_SWITCH 10880 /* 85% */ 155#define IWL_RATE_SCALE_SWITCH 10880 /* 85% */
156#define IWL_RATE_HIGH_TH 10880 /* 85% */ 156#define IWL_RATE_HIGH_TH 10880 /* 85% */
157#define IWL_RATE_INCREASE_TH 6400 /* 50% */ 157#define IWL_RATE_INCREASE_TH 6400 /* 50% */
158#define IWL_RATE_DECREASE_TH 1920 /* 15% */ 158#define RS_SR_FORCE_DECREASE 1920 /* 15% */
159
160/* possible actions when in legacy mode */
161enum {
162 IWL_LEGACY_SWITCH_ANTENNA,
163 IWL_LEGACY_SWITCH_SISO,
164 IWL_LEGACY_SWITCH_MIMO2,
165 IWL_LEGACY_FIRST_ACTION = IWL_LEGACY_SWITCH_ANTENNA,
166 IWL_LEGACY_LAST_ACTION = IWL_LEGACY_SWITCH_MIMO2,
167};
168
169/* possible actions when in siso mode */
170enum {
171 IWL_SISO_SWITCH_ANTENNA,
172 IWL_SISO_SWITCH_MIMO2,
173 IWL_SISO_SWITCH_GI,
174 IWL_SISO_FIRST_ACTION = IWL_SISO_SWITCH_ANTENNA,
175 IWL_SISO_LAST_ACTION = IWL_SISO_SWITCH_GI,
176};
177
178/* possible actions when in mimo mode */
179enum {
180 IWL_MIMO2_SWITCH_SISO_A,
181 IWL_MIMO2_SWITCH_SISO_B,
182 IWL_MIMO2_SWITCH_GI,
183 IWL_MIMO2_FIRST_ACTION = IWL_MIMO2_SWITCH_SISO_A,
184 IWL_MIMO2_LAST_ACTION = IWL_MIMO2_SWITCH_GI,
185};
186
187#define IWL_MAX_SEARCH IWL_MIMO2_LAST_ACTION
188
189#define IWL_ACTION_LIMIT 3 /* # possible actions */
190 159
191#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ 160#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
192#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000) 161#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000)
@@ -224,22 +193,45 @@ enum iwl_table_type {
224 LQ_MAX, 193 LQ_MAX,
225}; 194};
226 195
227#define is_legacy(tbl) (((tbl) == LQ_LEGACY_G) || ((tbl) == LQ_LEGACY_A)) 196struct rs_rate {
228#define is_ht_siso(tbl) ((tbl) == LQ_HT_SISO) 197 int index;
229#define is_ht_mimo2(tbl) ((tbl) == LQ_HT_MIMO2) 198 enum iwl_table_type type;
230#define is_vht_siso(tbl) ((tbl) == LQ_VHT_SISO) 199 u8 ant;
231#define is_vht_mimo2(tbl) ((tbl) == LQ_VHT_MIMO2) 200 u32 bw;
232#define is_siso(tbl) (is_ht_siso(tbl) || is_vht_siso(tbl)) 201 bool sgi;
233#define is_mimo2(tbl) (is_ht_mimo2(tbl) || is_vht_mimo2(tbl)) 202};
234#define is_mimo(tbl) (is_mimo2(tbl)) 203
235#define is_ht(tbl) (is_ht_siso(tbl) || is_ht_mimo2(tbl)) 204
236#define is_vht(tbl) (is_vht_siso(tbl) || is_vht_mimo2(tbl)) 205#define is_type_legacy(type) (((type) == LQ_LEGACY_G) || \
237#define is_a_band(tbl) ((tbl) == LQ_LEGACY_A) 206 ((type) == LQ_LEGACY_A))
238#define is_g_band(tbl) ((tbl) == LQ_LEGACY_G) 207#define is_type_ht_siso(type) ((type) == LQ_HT_SISO)
239 208#define is_type_ht_mimo2(type) ((type) == LQ_HT_MIMO2)
240#define is_ht20(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_20) 209#define is_type_vht_siso(type) ((type) == LQ_VHT_SISO)
241#define is_ht40(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_40) 210#define is_type_vht_mimo2(type) ((type) == LQ_VHT_MIMO2)
242#define is_ht80(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_80) 211#define is_type_siso(type) (is_type_ht_siso(type) || is_type_vht_siso(type))
212#define is_type_mimo2(type) (is_type_ht_mimo2(type) || is_type_vht_mimo2(type))
213#define is_type_mimo(type) (is_type_mimo2(type))
214#define is_type_ht(type) (is_type_ht_siso(type) || is_type_ht_mimo2(type))
215#define is_type_vht(type) (is_type_vht_siso(type) || is_type_vht_mimo2(type))
216#define is_type_a_band(type) ((type) == LQ_LEGACY_A)
217#define is_type_g_band(type) ((type) == LQ_LEGACY_G)
218
219#define is_legacy(rate) is_type_legacy((rate)->type)
220#define is_ht_siso(rate) is_type_ht_siso((rate)->type)
221#define is_ht_mimo2(rate) is_type_ht_mimo2((rate)->type)
222#define is_vht_siso(rate) is_type_vht_siso((rate)->type)
223#define is_vht_mimo2(rate) is_type_vht_mimo2((rate)->type)
224#define is_siso(rate) is_type_siso((rate)->type)
225#define is_mimo2(rate) is_type_mimo2((rate)->type)
226#define is_mimo(rate) is_type_mimo((rate)->type)
227#define is_ht(rate) is_type_ht((rate)->type)
228#define is_vht(rate) is_type_vht((rate)->type)
229#define is_a_band(rate) is_type_a_band((rate)->type)
230#define is_g_band(rate) is_type_g_band((rate)->type)
231
232#define is_ht20(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_20)
233#define is_ht40(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_40)
234#define is_ht80(rate) ((rate)->bw == RATE_MCS_CHAN_WIDTH_80)
243 235
244#define IWL_MAX_MCS_DISPLAY_SIZE 12 236#define IWL_MAX_MCS_DISPLAY_SIZE 12
245 237
@@ -257,7 +249,23 @@ struct iwl_rate_scale_data {
257 s32 success_ratio; /* per-cent * 128 */ 249 s32 success_ratio; /* per-cent * 128 */
258 s32 counter; /* number of frames attempted */ 250 s32 counter; /* number of frames attempted */
259 s32 average_tpt; /* success ratio * expected throughput */ 251 s32 average_tpt; /* success ratio * expected throughput */
260 unsigned long stamp; 252};
253
254/* Possible Tx columns
255 * Tx Column = a combo of legacy/siso/mimo x antenna x SGI
256 */
257enum rs_column {
258 RS_COLUMN_LEGACY_ANT_A = 0,
259 RS_COLUMN_LEGACY_ANT_B,
260 RS_COLUMN_SISO_ANT_A,
261 RS_COLUMN_SISO_ANT_B,
262 RS_COLUMN_SISO_ANT_A_SGI,
263 RS_COLUMN_SISO_ANT_B_SGI,
264 RS_COLUMN_MIMO2,
265 RS_COLUMN_MIMO2_SGI,
266
267 RS_COLUMN_LAST = RS_COLUMN_MIMO2_SGI,
268 RS_COLUMN_INVALID,
261}; 269};
262 270
263/** 271/**
@@ -267,17 +275,18 @@ struct iwl_rate_scale_data {
267 * one for "active", and one for "search". 275 * one for "active", and one for "search".
268 */ 276 */
269struct iwl_scale_tbl_info { 277struct iwl_scale_tbl_info {
270 enum iwl_table_type lq_type; 278 struct rs_rate rate;
271 u8 ant_type; 279 enum rs_column column;
272 u8 is_SGI; /* 1 = short guard interval */
273 u32 bw; /* channel bandwidth; RATE_MCS_CHAN_WIDTH_XX */
274 u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
275 u8 max_search; /* maximun number of tables we can search */
276 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ 280 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
277 u32 current_rate; /* rate_n_flags, uCode API format */
278 struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ 281 struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
279}; 282};
280 283
284enum {
285 RS_STATE_SEARCH_CYCLE_STARTED,
286 RS_STATE_SEARCH_CYCLE_ENDED,
287 RS_STATE_STAY_IN_COLUMN,
288};
289
281/** 290/**
282 * struct iwl_lq_sta -- driver's rate scaling private structure 291 * struct iwl_lq_sta -- driver's rate scaling private structure
283 * 292 *
@@ -285,8 +294,7 @@ struct iwl_scale_tbl_info {
285 */ 294 */
286struct iwl_lq_sta { 295struct iwl_lq_sta {
287 u8 active_tbl; /* index of active table, range 0-1 */ 296 u8 active_tbl; /* index of active table, range 0-1 */
288 u8 enable_counter; /* indicates HT mode */ 297 u8 rs_state; /* RS_STATE_* */
289 u8 stay_in_tbl; /* 1: disallow, 0: allow search for new mode */
290 u8 search_better_tbl; /* 1: currently trying alternate mode */ 298 u8 search_better_tbl; /* 1: currently trying alternate mode */
291 s32 last_tpt; 299 s32 last_tpt;
292 300
@@ -299,12 +307,13 @@ struct iwl_lq_sta {
299 u32 total_success; /* total successful frames, any/all rates */ 307 u32 total_success; /* total successful frames, any/all rates */
300 u64 flush_timer; /* time staying in mode before new search */ 308 u64 flush_timer; /* time staying in mode before new search */
301 309
302 u8 action_counter; /* # mode-switch actions tried */ 310 u32 visited_columns; /* Bitmask marking which Tx columns were
311 * explored during a search cycle
312 */
303 bool is_vht; 313 bool is_vht;
304 enum ieee80211_band band; 314 enum ieee80211_band band;
305 315
306 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ 316 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
307 u32 supp_rates;
308 u16 active_legacy_rate; 317 u16 active_legacy_rate;
309 u16 active_siso_rate; 318 u16 active_siso_rate;
310 u16 active_mimo2_rate; 319 u16 active_mimo2_rate;
@@ -328,32 +337,11 @@ struct iwl_lq_sta {
328 u32 last_rate_n_flags; 337 u32 last_rate_n_flags;
329 /* packets destined for this STA are aggregated */ 338 /* packets destined for this STA are aggregated */
330 u8 is_agg; 339 u8 is_agg;
331 /* BT traffic this sta was last updated in */
332 u8 last_bt_traffic;
333};
334
335enum iwl_bt_coex_profile_traffic_load {
336 IWL_BT_COEX_TRAFFIC_LOAD_NONE = 0,
337 IWL_BT_COEX_TRAFFIC_LOAD_LOW = 1,
338 IWL_BT_COEX_TRAFFIC_LOAD_HIGH = 2,
339 IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS = 3,
340/*
341 * There are no more even though below is a u8, the
342 * indication from the BT device only has two bits.
343 */
344}; 340};
345 341
346
347static inline u8 num_of_ant(u8 mask)
348{
349 return !!((mask) & ANT_A) +
350 !!((mask) & ANT_B) +
351 !!((mask) & ANT_C);
352}
353
354/* Initialize station's rate scaling information after adding station */ 342/* Initialize station's rate scaling information after adding station */
355void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 343void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
356 enum ieee80211_band band); 344 enum ieee80211_band band, bool init);
357 345
358/** 346/**
359 * iwl_rate_control_register - Register the rate control algorithm callbacks 347 * iwl_rate_control_register - Register the rate control algorithm callbacks
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 3a1f3982109d..a85b60f7e67e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -251,6 +251,12 @@ static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm,
251 stats->flag |= RX_FLAG_DECRYPTED; 251 stats->flag |= RX_FLAG_DECRYPTED;
252 return 0; 252 return 0;
253 253
254 case RX_MPDU_RES_STATUS_SEC_EXT_ENC:
255 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_MIC_OK))
256 return -1;
257 stats->flag |= RX_FLAG_DECRYPTED;
258 return 0;
259
254 default: 260 default:
255 IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status); 261 IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status);
256 } 262 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index dff7592e1ff8..0e0007960612 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -70,6 +70,9 @@
70 70
71#define IWL_PLCP_QUIET_THRESH 1 71#define IWL_PLCP_QUIET_THRESH 1
72#define IWL_ACTIVE_QUIET_TIME 10 72#define IWL_ACTIVE_QUIET_TIME 10
73#define LONG_OUT_TIME_PERIOD 600
74#define SHORT_OUT_TIME_PERIOD 200
75#define SUSPEND_TIME_PERIOD 100
73 76
74static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) 77static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
75{ 78{
@@ -87,20 +90,22 @@ static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
87 return cpu_to_le16(rx_chain); 90 return cpu_to_le16(rx_chain);
88} 91}
89 92
90static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif) 93static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif,
94 u32 flags, bool is_assoc)
91{ 95{
92 if (vif->bss_conf.assoc) 96 if (!is_assoc)
93 return cpu_to_le32(200 * 1024);
94 else
95 return 0; 97 return 0;
98 if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY)
99 return cpu_to_le32(ieee80211_tu_to_usec(SHORT_OUT_TIME_PERIOD));
100 return cpu_to_le32(ieee80211_tu_to_usec(LONG_OUT_TIME_PERIOD));
96} 101}
97 102
98static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif) 103static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif,
104 bool is_assoc)
99{ 105{
100 if (!vif->bss_conf.assoc) 106 if (!is_assoc)
101 return 0; 107 return 0;
102 108 return cpu_to_le32(ieee80211_tu_to_usec(SUSPEND_TIME_PERIOD));
103 return cpu_to_le32(ieee80211_tu_to_usec(vif->bss_conf.beacon_int));
104} 109}
105 110
106static inline __le32 111static inline __le32
@@ -192,7 +197,7 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
192 for (i = 0; i < cmd->channel_count; i++) { 197 for (i = 0; i < cmd->channel_count; i++) {
193 chan->channel = cpu_to_le16(req->channels[i]->hw_value); 198 chan->channel = cpu_to_le16(req->channels[i]->hw_value);
194 chan->type = cpu_to_le32(type); 199 chan->type = cpu_to_le32(type);
195 if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) 200 if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR)
196 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE); 201 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
197 chan->active_dwell = cpu_to_le16(active_dwell); 202 chan->active_dwell = cpu_to_le16(active_dwell);
198 chan->passive_dwell = cpu_to_le16(passive_dwell); 203 chan->passive_dwell = cpu_to_le16(passive_dwell);
@@ -262,6 +267,15 @@ static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
262 return (u16)len; 267 return (u16)len;
263} 268}
264 269
270static void iwl_mvm_vif_assoc_iterator(void *data, u8 *mac,
271 struct ieee80211_vif *vif)
272{
273 bool *is_assoc = data;
274
275 if (vif->bss_conf.assoc)
276 *is_assoc = true;
277}
278
265int iwl_mvm_scan_request(struct iwl_mvm *mvm, 279int iwl_mvm_scan_request(struct iwl_mvm *mvm,
266 struct ieee80211_vif *vif, 280 struct ieee80211_vif *vif,
267 struct cfg80211_scan_request *req) 281 struct cfg80211_scan_request *req)
@@ -274,6 +288,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
274 .dataflags = { IWL_HCMD_DFL_NOCOPY, }, 288 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
275 }; 289 };
276 struct iwl_scan_cmd *cmd = mvm->scan_cmd; 290 struct iwl_scan_cmd *cmd = mvm->scan_cmd;
291 bool is_assoc = false;
277 int ret; 292 int ret;
278 u32 status; 293 u32 status;
279 int ssid_len = 0; 294 int ssid_len = 0;
@@ -289,13 +304,17 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
289 memset(cmd, 0, sizeof(struct iwl_scan_cmd) + 304 memset(cmd, 0, sizeof(struct iwl_scan_cmd) +
290 mvm->fw->ucode_capa.max_probe_length + 305 mvm->fw->ucode_capa.max_probe_length +
291 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel))); 306 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel)));
292 307 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
308 IEEE80211_IFACE_ITER_NORMAL,
309 iwl_mvm_vif_assoc_iterator,
310 &is_assoc);
293 cmd->channel_count = (u8)req->n_channels; 311 cmd->channel_count = (u8)req->n_channels;
294 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME); 312 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
295 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); 313 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
296 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm); 314 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm);
297 cmd->max_out_time = iwl_mvm_scan_max_out_time(vif); 315 cmd->max_out_time = iwl_mvm_scan_max_out_time(vif, req->flags,
298 cmd->suspend_time = iwl_mvm_scan_suspend_time(vif); 316 is_assoc);
317 cmd->suspend_time = iwl_mvm_scan_suspend_time(vif, is_assoc);
299 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req); 318 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req);
300 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 319 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
301 MAC_FILTER_IN_BEACON); 320 MAC_FILTER_IN_BEACON);
@@ -454,13 +473,18 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
454 if (mvm->scan_status == IWL_MVM_SCAN_NONE) 473 if (mvm->scan_status == IWL_MVM_SCAN_NONE)
455 return; 474 return;
456 475
476 if (iwl_mvm_is_radio_killed(mvm)) {
477 ieee80211_scan_completed(mvm->hw, true);
478 mvm->scan_status = IWL_MVM_SCAN_NONE;
479 return;
480 }
481
457 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort, 482 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort,
458 scan_abort_notif, 483 scan_abort_notif,
459 ARRAY_SIZE(scan_abort_notif), 484 ARRAY_SIZE(scan_abort_notif),
460 iwl_mvm_scan_abort_notif, NULL); 485 iwl_mvm_scan_abort_notif, NULL);
461 486
462 ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, 487 ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, CMD_SYNC, 0, NULL);
463 CMD_SYNC | CMD_SEND_IN_RFKILL, 0, NULL);
464 if (ret) { 488 if (ret) {
465 IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret); 489 IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret);
466 /* mac80211's state will be cleaned in the fw_restart flow */ 490 /* mac80211's state will be cleaned in the fw_restart flow */
@@ -522,6 +546,12 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
522 struct cfg80211_sched_scan_request *req, 546 struct cfg80211_sched_scan_request *req,
523 struct iwl_scan_offload_cmd *scan) 547 struct iwl_scan_offload_cmd *scan)
524{ 548{
549 bool is_assoc = false;
550
551 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
552 IEEE80211_IFACE_ITER_NORMAL,
553 iwl_mvm_vif_assoc_iterator,
554 &is_assoc);
525 scan->channel_count = 555 scan->channel_count =
526 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels + 556 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels +
527 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; 557 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
@@ -529,8 +559,9 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
529 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); 559 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
530 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT; 560 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT;
531 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm); 561 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm);
532 scan->max_out_time = cpu_to_le32(200 * 1024); 562 scan->max_out_time = iwl_mvm_scan_max_out_time(vif, req->flags,
533 scan->suspend_time = iwl_mvm_scan_suspend_time(vif); 563 is_assoc);
564 scan->suspend_time = iwl_mvm_scan_suspend_time(vif, is_assoc);
534 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 565 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
535 MAC_FILTER_IN_BEACON); 566 MAC_FILTER_IN_BEACON);
536 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND); 567 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND);
@@ -642,7 +673,7 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
642 channels->iter_count[index] = cpu_to_le16(1); 673 channels->iter_count[index] = cpu_to_le16(1);
643 channels->iter_interval[index] = 0; 674 channels->iter_interval[index] = 0;
644 675
645 if (!(s_band->channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) 676 if (!(s_band->channels[i].flags & IEEE80211_CHAN_NO_IR))
646 channels->type[index] |= 677 channels->type[index] |=
647 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE); 678 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE);
648 679
@@ -817,11 +848,10 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
817 IWL_DEBUG_SCAN(mvm, 848 IWL_DEBUG_SCAN(mvm,
818 "Sending scheduled scan with filtering, filter len %d\n", 849 "Sending scheduled scan with filtering, filter len %d\n",
819 req->n_match_sets); 850 req->n_match_sets);
820 scan_req.flags |=
821 cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID);
822 } else { 851 } else {
823 IWL_DEBUG_SCAN(mvm, 852 IWL_DEBUG_SCAN(mvm,
824 "Sending Scheduled scan without filtering\n"); 853 "Sending Scheduled scan without filtering\n");
854 scan_req.flags |= cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_PASS_ALL);
825 } 855 }
826 856
827 return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, CMD_SYNC, 857 return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, CMD_SYNC,
diff --git a/drivers/net/wireless/iwlwifi/mvm/sf.c b/drivers/net/wireless/iwlwifi/mvm/sf.c
new file mode 100644
index 000000000000..8401627c0030
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/sf.c
@@ -0,0 +1,291 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#include "mvm.h"
64
65/* For counting bound interfaces */
66struct iwl_mvm_active_iface_iterator_data {
67 struct ieee80211_vif *ignore_vif;
68 u8 sta_vif_ap_sta_id;
69 enum iwl_sf_state sta_vif_state;
70 int num_active_macs;
71};
72
73/*
74 * Count bound interfaces which are not p2p, besides data->ignore_vif.
75 * data->station_vif will point to one bound vif of type station, if exists.
76 */
77static void iwl_mvm_bound_iface_iterator(void *_data, u8 *mac,
78 struct ieee80211_vif *vif)
79{
80 struct iwl_mvm_active_iface_iterator_data *data = _data;
81 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
82
83 if (vif == data->ignore_vif || !mvmvif->phy_ctxt ||
84 vif->type == NL80211_IFTYPE_P2P_DEVICE)
85 return;
86
87 data->num_active_macs++;
88
89 if (vif->type == NL80211_IFTYPE_STATION) {
90 data->sta_vif_ap_sta_id = mvmvif->ap_sta_id;
91 if (vif->bss_conf.assoc)
92 data->sta_vif_state = SF_FULL_ON;
93 else
94 data->sta_vif_state = SF_INIT_OFF;
95 }
96}
97
98/*
99 * Aging and idle timeouts for the different possible scenarios
100 * in SF_FULL_ON state.
101 */
102static const __le32 sf_full_timeout[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES] = {
103 {
104 cpu_to_le32(SF_SINGLE_UNICAST_AGING_TIMER),
105 cpu_to_le32(SF_SINGLE_UNICAST_IDLE_TIMER)
106 },
107 {
108 cpu_to_le32(SF_AGG_UNICAST_AGING_TIMER),
109 cpu_to_le32(SF_AGG_UNICAST_IDLE_TIMER)
110 },
111 {
112 cpu_to_le32(SF_MCAST_AGING_TIMER),
113 cpu_to_le32(SF_MCAST_IDLE_TIMER)
114 },
115 {
116 cpu_to_le32(SF_BA_AGING_TIMER),
117 cpu_to_le32(SF_BA_IDLE_TIMER)
118 },
119 {
120 cpu_to_le32(SF_TX_RE_AGING_TIMER),
121 cpu_to_le32(SF_TX_RE_IDLE_TIMER)
122 },
123};
124
125static void iwl_mvm_fill_sf_command(struct iwl_sf_cfg_cmd *sf_cmd,
126 struct ieee80211_sta *sta)
127{
128 int i, j, watermark;
129
130 sf_cmd->watermark[SF_LONG_DELAY_ON] = cpu_to_le32(SF_W_MARK_SCAN);
131
132 /*
133 * If we are in association flow - check antenna configuration
134 * capabilities of the AP station, and choose the watermark accordingly.
135 */
136 if (sta) {
137 if (sta->ht_cap.ht_supported || sta->vht_cap.vht_supported) {
138 switch (sta->rx_nss) {
139 case 1:
140 watermark = SF_W_MARK_SISO;
141 break;
142 case 2:
143 watermark = SF_W_MARK_MIMO2;
144 break;
145 default:
146 watermark = SF_W_MARK_MIMO3;
147 break;
148 }
149 } else {
150 watermark = SF_W_MARK_LEGACY;
151 }
152 /* default watermark value for unassociated mode. */
153 } else {
154 watermark = SF_W_MARK_MIMO2;
155 }
156 sf_cmd->watermark[SF_FULL_ON] = cpu_to_le32(watermark);
157
158 for (i = 0; i < SF_NUM_SCENARIO; i++) {
159 for (j = 0; j < SF_NUM_TIMEOUT_TYPES; j++) {
160 sf_cmd->long_delay_timeouts[i][j] =
161 cpu_to_le32(SF_LONG_DELAY_AGING_TIMER);
162 }
163 }
164 BUILD_BUG_ON(sizeof(sf_full_timeout) !=
165 sizeof(__le32) * SF_NUM_SCENARIO * SF_NUM_TIMEOUT_TYPES);
166
167 memcpy(sf_cmd->full_on_timeouts, sf_full_timeout,
168 sizeof(sf_full_timeout));
169}
170
171static int iwl_mvm_sf_config(struct iwl_mvm *mvm, u8 sta_id,
172 enum iwl_sf_state new_state)
173{
174 struct iwl_sf_cfg_cmd sf_cmd = {
175 .state = new_state,
176 };
177 struct ieee80211_sta *sta;
178 int ret = 0;
179
180 /*
181 * If an associated AP sta changed its antenna configuration, the state
182 * will remain FULL_ON but SF parameters need to be reconsidered.
183 */
184 if (new_state != SF_FULL_ON && mvm->sf_state == new_state)
185 return 0;
186
187 switch (new_state) {
188 case SF_UNINIT:
189 break;
190 case SF_FULL_ON:
191 if (sta_id == IWL_MVM_STATION_COUNT) {
192 IWL_ERR(mvm,
193 "No station: Cannot switch SF to FULL_ON\n");
194 return -EINVAL;
195 }
196 rcu_read_lock();
197 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
198 if (IS_ERR_OR_NULL(sta)) {
199 IWL_ERR(mvm, "Invalid station id\n");
200 rcu_read_unlock();
201 return -EINVAL;
202 }
203 iwl_mvm_fill_sf_command(&sf_cmd, sta);
204 rcu_read_unlock();
205 break;
206 case SF_INIT_OFF:
207 iwl_mvm_fill_sf_command(&sf_cmd, NULL);
208 break;
209 default:
210 WARN_ONCE(1, "Invalid state: %d. not sending Smart Fifo cmd\n",
211 new_state);
212 return -EINVAL;
213 }
214
215 ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_SF_CFG_CMD, CMD_ASYNC,
216 sizeof(sf_cmd), &sf_cmd);
217 if (!ret)
218 mvm->sf_state = new_state;
219
220 return ret;
221}
222
223/*
224 * Update Smart fifo:
225 * Count bound interfaces that are not to be removed, ignoring p2p devices,
226 * and set new state accordingly.
227 */
228int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *changed_vif,
229 bool remove_vif)
230{
231 enum iwl_sf_state new_state;
232 u8 sta_id = IWL_MVM_STATION_COUNT;
233 struct iwl_mvm_vif *mvmvif = NULL;
234 struct iwl_mvm_active_iface_iterator_data data = {
235 .ignore_vif = changed_vif,
236 .sta_vif_state = SF_UNINIT,
237 .sta_vif_ap_sta_id = IWL_MVM_STATION_COUNT,
238 };
239
240 if (IWL_UCODE_API(mvm->fw->ucode_ver) < 8)
241 return 0;
242
243 /*
244 * Ignore the call if we are in HW Restart flow, or if the handled
245 * vif is a p2p device.
246 */
247 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) ||
248 (changed_vif && changed_vif->type == NL80211_IFTYPE_P2P_DEVICE))
249 return 0;
250
251 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
252 IEEE80211_IFACE_ITER_NORMAL,
253 iwl_mvm_bound_iface_iterator,
254 &data);
255
256 /* If changed_vif exists and is not to be removed, add to the count */
257 if (changed_vif && !remove_vif)
258 data.num_active_macs++;
259
260 switch (data.num_active_macs) {
261 case 0:
262 /* If there are no active macs - change state to SF_INIT_OFF */
263 new_state = SF_INIT_OFF;
264 break;
265 case 1:
266 if (remove_vif) {
267 /* The one active mac left is of type station
268 * and we filled the relevant data during iteration
269 */
270 new_state = data.sta_vif_state;
271 sta_id = data.sta_vif_ap_sta_id;
272 } else {
273 if (WARN_ON(!changed_vif))
274 return -EINVAL;
275 if (changed_vif->type != NL80211_IFTYPE_STATION) {
276 new_state = SF_UNINIT;
277 } else if (changed_vif->bss_conf.assoc) {
278 mvmvif = iwl_mvm_vif_from_mac80211(changed_vif);
279 sta_id = mvmvif->ap_sta_id;
280 new_state = SF_FULL_ON;
281 } else {
282 new_state = SF_INIT_OFF;
283 }
284 }
285 break;
286 default:
287 /* If there are multiple active macs - change to SF_UNINIT */
288 new_state = SF_UNINIT;
289 }
290 return iwl_mvm_sf_config(mvm, sta_id, new_state);
291}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 329952363a54..ec1812133235 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -452,8 +452,15 @@ void iwl_mvm_sta_drained_wk(struct work_struct *wk)
452 rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], 452 rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
453 lockdep_is_held(&mvm->mutex)); 453 lockdep_is_held(&mvm->mutex));
454 454
455 /* This station is in use */ 455 /*
456 if (!IS_ERR(sta)) 456 * This station is in use or RCU-removed; the latter happens in
457 * managed mode, where mac80211 removes the station before we
458 * can remove it from firmware (we can only do that after the
459 * MAC is marked unassociated), and possibly while the deauth
460 * frame to disconnect from the AP is still queued. Then, the
461 * station pointer is -ENOENT when the last skb is reclaimed.
462 */
463 if (!IS_ERR(sta) || PTR_ERR(sta) == -ENOENT)
457 continue; 464 continue;
458 465
459 if (PTR_ERR(sta) == -EINVAL) { 466 if (PTR_ERR(sta) == -EINVAL) {
@@ -840,7 +847,7 @@ static const u8 tid_to_ac[] = {
840int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 847int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
841 struct ieee80211_sta *sta, u16 tid, u16 *ssn) 848 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
842{ 849{
843 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 850 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
844 struct iwl_mvm_tid_data *tid_data; 851 struct iwl_mvm_tid_data *tid_data;
845 int txq_id; 852 int txq_id;
846 853
@@ -895,7 +902,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
895int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 902int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
896 struct ieee80211_sta *sta, u16 tid, u8 buf_size) 903 struct ieee80211_sta *sta, u16 tid, u8 buf_size)
897{ 904{
898 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 905 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
899 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 906 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
900 int queue, fifo, ret; 907 int queue, fifo, ret;
901 u16 ssn; 908 u16 ssn;
@@ -932,26 +939,13 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
932 IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n", 939 IWL_DEBUG_HT(mvm, "Tx aggregation enabled on ra = %pM tid = %d\n",
933 sta->addr, tid); 940 sta->addr, tid);
934 941
935 if (mvm->cfg->ht_params->use_rts_for_aggregation) { 942 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, false);
936 /*
937 * switch to RTS/CTS if it is the prefer protection
938 * method for HT traffic
939 * this function also sends the LQ command
940 */
941 return iwl_mvm_tx_protection(mvm, mvmsta, true);
942 /*
943 * TODO: remove the TLC_RTS flag when we tear down the last
944 * AGG session (agg_tids_count in DVM)
945 */
946 }
947
948 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false);
949} 943}
950 944
951int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 945int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
952 struct ieee80211_sta *sta, u16 tid) 946 struct ieee80211_sta *sta, u16 tid)
953{ 947{
954 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 948 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
955 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 949 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
956 u16 txq_id; 950 u16 txq_id;
957 int err; 951 int err;
@@ -1023,7 +1017,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1023int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 1017int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1024 struct ieee80211_sta *sta, u16 tid) 1018 struct ieee80211_sta *sta, u16 tid)
1025{ 1019{
1026 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1020 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1027 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 1021 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
1028 u16 txq_id; 1022 u16 txq_id;
1029 enum iwl_mvm_agg_state old_state; 1023 enum iwl_mvm_agg_state old_state;
@@ -1123,8 +1117,8 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
1123 memcpy(cmd.key, keyconf->key, keyconf->keylen); 1117 memcpy(cmd.key, keyconf->key, keyconf->keylen);
1124 break; 1118 break;
1125 default: 1119 default:
1126 WARN_ON(1); 1120 key_flags |= cpu_to_le16(STA_KEY_FLG_EXT);
1127 return -EINVAL; 1121 memcpy(cmd.key, keyconf->key, keyconf->keylen);
1128 } 1122 }
1129 1123
1130 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) 1124 if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
@@ -1288,8 +1282,8 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
1288 0, NULL, CMD_SYNC); 1282 0, NULL, CMD_SYNC);
1289 break; 1283 break;
1290 default: 1284 default:
1291 IWL_ERR(mvm, "Unknown cipher %x\n", keyconf->cipher); 1285 ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf,
1292 ret = -EINVAL; 1286 sta_id, 0, NULL, CMD_SYNC);
1293 } 1287 }
1294 1288
1295 if (ret) 1289 if (ret)
@@ -1416,7 +1410,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
1416void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, 1410void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
1417 struct ieee80211_sta *sta) 1411 struct ieee80211_sta *sta)
1418{ 1412{
1419 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1413 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1420 struct iwl_mvm_add_sta_cmd_v6 cmd = { 1414 struct iwl_mvm_add_sta_cmd_v6 cmd = {
1421 .add_modify = STA_MODE_MODIFY, 1415 .add_modify = STA_MODE_MODIFY,
1422 .sta_id = mvmsta->sta_id, 1416 .sta_id = mvmsta->sta_id,
@@ -1438,7 +1432,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
1438 u16 sleep_state_flags = 1432 u16 sleep_state_flags =
1439 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ? 1433 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ?
1440 STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL; 1434 STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL;
1441 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1435 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1442 struct iwl_mvm_add_sta_cmd_v6 cmd = { 1436 struct iwl_mvm_add_sta_cmd_v6 cmd = {
1443 .add_modify = STA_MODE_MODIFY, 1437 .add_modify = STA_MODE_MODIFY,
1444 .sta_id = mvmsta->sta_id, 1438 .sta_id = mvmsta->sta_id,
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index 4dfc359a4bdd..4968d0237dc5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -298,6 +298,12 @@ struct iwl_mvm_sta {
298 bool tt_tx_protection; 298 bool tt_tx_protection;
299}; 299};
300 300
301static inline struct iwl_mvm_sta *
302iwl_mvm_sta_from_mac80211(struct ieee80211_sta *sta)
303{
304 return (void *)sta->drv_priv;
305}
306
301/** 307/**
302 * struct iwl_mvm_int_sta - representation of an internal station (auxiliary or 308 * struct iwl_mvm_int_sta - representation of an internal station (auxiliary or
303 * broadcast) 309 * broadcast)
diff --git a/drivers/net/wireless/iwlwifi/mvm/testmode.h b/drivers/net/wireless/iwlwifi/mvm/testmode.h
index eb74391d91ca..0241665925f7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/testmode.h
+++ b/drivers/net/wireless/iwlwifi/mvm/testmode.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index 95ce4b601fef..b4c2abaa297b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -249,12 +249,12 @@ static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait,
249 container_of(notif_wait, struct iwl_mvm, notif_wait); 249 container_of(notif_wait, struct iwl_mvm, notif_wait);
250 struct iwl_mvm_time_event_data *te_data = data; 250 struct iwl_mvm_time_event_data *te_data = data;
251 struct iwl_time_event_resp *resp; 251 struct iwl_time_event_resp *resp;
252 int resp_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 252 int resp_len = iwl_rx_packet_payload_len(pkt);
253 253
254 if (WARN_ON(pkt->hdr.cmd != TIME_EVENT_CMD)) 254 if (WARN_ON(pkt->hdr.cmd != TIME_EVENT_CMD))
255 return true; 255 return true;
256 256
257 if (WARN_ON_ONCE(resp_len != sizeof(pkt->hdr) + sizeof(*resp))) { 257 if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
258 IWL_ERR(mvm, "Invalid TIME_EVENT_CMD response\n"); 258 IWL_ERR(mvm, "Invalid TIME_EVENT_CMD response\n");
259 return true; 259 return true;
260 } 260 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h
index d9c8d6cfa2db..4a61c8c02372 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.h
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
index 1f3282dff513..3afa6b6bf835 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -340,7 +340,7 @@ static void check_exit_ctkill(struct work_struct *work)
340 340
341 iwl_trans_start_hw(mvm->trans); 341 iwl_trans_start_hw(mvm->trans);
342 temp = check_nic_temperature(mvm); 342 temp = check_nic_temperature(mvm);
343 iwl_trans_stop_hw(mvm->trans, false); 343 iwl_trans_stop_device(mvm->trans);
344 344
345 if (temp < MIN_TEMPERATURE || temp > MAX_TEMPERATURE) { 345 if (temp < MIN_TEMPERATURE || temp > MAX_TEMPERATURE) {
346 IWL_DEBUG_TEMP(mvm, "Failed to measure NIC temperature\n"); 346 IWL_DEBUG_TEMP(mvm, "Failed to measure NIC temperature\n");
@@ -388,7 +388,7 @@ static void iwl_mvm_tt_tx_protection(struct iwl_mvm *mvm, bool enable)
388 lockdep_is_held(&mvm->mutex)); 388 lockdep_is_held(&mvm->mutex));
389 if (IS_ERR_OR_NULL(sta)) 389 if (IS_ERR_OR_NULL(sta))
390 continue; 390 continue;
391 mvmsta = (void *)sta->drv_priv; 391 mvmsta = iwl_mvm_sta_from_mac80211(sta);
392 if (enable == mvmsta->tt_tx_protection) 392 if (enable == mvmsta->tt_tx_protection)
393 continue; 393 continue;
394 err = iwl_mvm_tx_protection(mvm, mvmsta, enable); 394 err = iwl_mvm_tx_protection(mvm, mvmsta, enable);
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 43d97c33a75a..90378c217bc7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -253,8 +253,7 @@ static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm,
253 memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen); 253 memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
254 break; 254 break;
255 default: 255 default:
256 IWL_ERR(mvm, "Unknown encode cipher %x\n", keyconf->cipher); 256 tx_cmd->sec_ctl |= TX_CMD_SEC_EXT;
257 break;
258 } 257 }
259} 258}
260 259
@@ -276,6 +275,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
276 return NULL; 275 return NULL;
277 276
278 memset(dev_cmd, 0, sizeof(*dev_cmd)); 277 memset(dev_cmd, 0, sizeof(*dev_cmd));
278 dev_cmd->hdr.cmd = TX_CMD;
279 tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload; 279 tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;
280 280
281 if (info->control.hw_key) 281 if (info->control.hw_key)
@@ -361,7 +361,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
361 u8 txq_id = info->hw_queue; 361 u8 txq_id = info->hw_queue;
362 bool is_data_qos = false, is_ampdu = false; 362 bool is_data_qos = false, is_ampdu = false;
363 363
364 mvmsta = (void *)sta->drv_priv; 364 mvmsta = iwl_mvm_sta_from_mac80211(sta);
365 fc = hdr->frame_control; 365 fc = hdr->frame_control;
366 366
367 if (WARN_ON_ONCE(!mvmsta)) 367 if (WARN_ON_ONCE(!mvmsta))
@@ -390,7 +390,6 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
390 seq_number &= IEEE80211_SCTL_SEQ; 390 seq_number &= IEEE80211_SCTL_SEQ;
391 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); 391 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
392 hdr->seq_ctrl |= cpu_to_le16(seq_number); 392 hdr->seq_ctrl |= cpu_to_le16(seq_number);
393 seq_number += 0x10;
394 is_data_qos = true; 393 is_data_qos = true;
395 is_ampdu = info->flags & IEEE80211_TX_CTL_AMPDU; 394 is_ampdu = info->flags & IEEE80211_TX_CTL_AMPDU;
396 } 395 }
@@ -407,13 +406,13 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
407 } 406 }
408 407
409 IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x\n", mvmsta->sta_id, 408 IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x\n", mvmsta->sta_id,
410 tid, txq_id, seq_number); 409 tid, txq_id, IEEE80211_SEQ_TO_SN(seq_number));
411 410
412 if (iwl_trans_tx(mvm->trans, skb, dev_cmd, txq_id)) 411 if (iwl_trans_tx(mvm->trans, skb, dev_cmd, txq_id))
413 goto drop_unlock_sta; 412 goto drop_unlock_sta;
414 413
415 if (is_data_qos && !ieee80211_has_morefrags(fc)) 414 if (is_data_qos && !ieee80211_has_morefrags(fc))
416 mvmsta->tid_data[tid].seq_number = seq_number; 415 mvmsta->tid_data[tid].seq_number = seq_number + 0x10;
417 416
418 spin_unlock(&mvmsta->lock); 417 spin_unlock(&mvmsta->lock);
419 418
@@ -432,7 +431,7 @@ drop:
432static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm, 431static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
433 struct ieee80211_sta *sta, u8 tid) 432 struct ieee80211_sta *sta, u8 tid)
434{ 433{
435 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 434 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
436 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 435 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
437 struct ieee80211_vif *vif = mvmsta->vif; 436 struct ieee80211_vif *vif = mvmsta->vif;
438 437
@@ -662,7 +661,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
662 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); 661 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
663 662
664 if (!IS_ERR_OR_NULL(sta)) { 663 if (!IS_ERR_OR_NULL(sta)) {
665 mvmsta = (void *)sta->drv_priv; 664 mvmsta = iwl_mvm_sta_from_mac80211(sta);
666 665
667 if (tid != IWL_TID_NON_QOS) { 666 if (tid != IWL_TID_NON_QOS) {
668 struct iwl_mvm_tid_data *tid_data = 667 struct iwl_mvm_tid_data *tid_data =
@@ -704,7 +703,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
704 */ 703 */
705 spin_lock_bh(&mvmsta->lock); 704 spin_lock_bh(&mvmsta->lock);
706 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); 705 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
707 if (IS_ERR_OR_NULL(sta)) { 706 if (!sta || PTR_ERR(sta) == -EBUSY) {
708 /* 707 /*
709 * Station disappeared in the meantime: 708 * Station disappeared in the meantime:
710 * so we are draining. 709 * so we are draining.
@@ -713,7 +712,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
713 schedule_work(&mvm->sta_drained_wk); 712 schedule_work(&mvm->sta_drained_wk);
714 } 713 }
715 spin_unlock_bh(&mvmsta->lock); 714 spin_unlock_bh(&mvmsta->lock);
716 } else if (!mvmsta) { 715 } else if (!mvmsta && PTR_ERR(sta) == -EBUSY) {
717 /* Tx response without STA, so we are draining */ 716 /* Tx response without STA, so we are draining */
718 set_bit(sta_id, mvm->sta_drained); 717 set_bit(sta_id, mvm->sta_drained);
719 schedule_work(&mvm->sta_drained_wk); 718 schedule_work(&mvm->sta_drained_wk);
@@ -793,7 +792,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
793 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); 792 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
794 793
795 if (!WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) { 794 if (!WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) {
796 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 795 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
797 mvmsta->tid_data[tid].rate_n_flags = 796 mvmsta->tid_data[tid].rate_n_flags =
798 le32_to_cpu(tx_resp->initial_rate); 797 le32_to_cpu(tx_resp->initial_rate);
799 } 798 }
@@ -849,7 +848,7 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
849 return 0; 848 return 0;
850 } 849 }
851 850
852 mvmsta = (void *)sta->drv_priv; 851 mvmsta = iwl_mvm_sta_from_mac80211(sta);
853 tid_data = &mvmsta->tid_data[tid]; 852 tid_data = &mvmsta->tid_data[tid];
854 853
855 if (WARN_ONCE(tid_data->txq_id != scd_flow, "Q %d, tid %d, flow %d", 854 if (WARN_ONCE(tid_data->txq_id != scd_flow, "Q %d, tid %d, flow %d",
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index ed69e9b78e82..a4a5e25623c3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
30 * 30 *
31 * BSD LICENSE 31 * BSD LICENSE
32 * 32 *
33 * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. 33 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
@@ -168,8 +168,8 @@ int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd,
168 goto out_free_resp; 168 goto out_free_resp;
169 } 169 }
170 170
171 resp_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 171 resp_len = iwl_rx_packet_payload_len(pkt);
172 if (WARN_ON_ONCE(resp_len != sizeof(pkt->hdr) + sizeof(*resp))) { 172 if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
173 ret = -EIO; 173 ret = -EIO;
174 goto out_free_resp; 174 goto out_free_resp;
175 } 175 }
@@ -486,22 +486,18 @@ void iwl_mvm_dump_sram(struct iwl_mvm *mvm)
486 * this case to clear the state indicating that station creation is in 486 * this case to clear the state indicating that station creation is in
487 * progress. 487 * progress.
488 */ 488 */
489int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, 489int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init)
490 u8 flags, bool init)
491{ 490{
492 struct iwl_host_cmd cmd = { 491 struct iwl_host_cmd cmd = {
493 .id = LQ_CMD, 492 .id = LQ_CMD,
494 .len = { sizeof(struct iwl_lq_cmd), }, 493 .len = { sizeof(struct iwl_lq_cmd), },
495 .flags = flags, 494 .flags = init ? CMD_SYNC : CMD_ASYNC,
496 .data = { lq, }, 495 .data = { lq, },
497 }; 496 };
498 497
499 if (WARN_ON(lq->sta_id == IWL_MVM_STATION_COUNT)) 498 if (WARN_ON(lq->sta_id == IWL_MVM_STATION_COUNT))
500 return -EINVAL; 499 return -EINVAL;
501 500
502 if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
503 return -EINVAL;
504
505 return iwl_mvm_send_cmd(mvm, &cmd); 501 return iwl_mvm_send_cmd(mvm, &cmd);
506} 502}
507 503
@@ -522,6 +518,11 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
522 int i; 518 int i;
523 519
524 lockdep_assert_held(&mvm->mutex); 520 lockdep_assert_held(&mvm->mutex);
521
522 /* SMPS is irrelevant for NICs that don't have at least 2 RX antenna */
523 if (num_of_ant(iwl_fw_valid_rx_ant(mvm->fw)) == 1)
524 return;
525
525 mvmvif = iwl_mvm_vif_from_mac80211(vif); 526 mvmvif = iwl_mvm_vif_from_mac80211(vif);
526 mvmvif->smps_requests[req_type] = smps_request; 527 mvmvif->smps_requests[req_type] = smps_request;
527 for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) { 528 for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) {