aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-12-11 10:49:24 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-12-11 10:49:24 -0500
commitd9a577c35a5f874cb11d96993dec26775e9738f7 (patch)
treed993d7e3ff97e4ef9b082c950c8becd85d24eb92
parentd6b5075d73adbc10fac873ca86798e30c115a018 (diff)
parent9d10849e4ea8bf9d8da80afa73918a9fe45c09ef (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rs.h7
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c13
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c38
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c190
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c636
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.h101
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h27
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c51
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c19
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h11
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c23
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c1681
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h150
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c55
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c14
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c11
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c8
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c5
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c26
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c33
30 files changed, 1538 insertions, 1592 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.h b/drivers/net/wireless/iwlwifi/dvm/rs.h
index 26fc550cd68c..41988f4b8a5a 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/dvm/rs.h
@@ -389,13 +389,6 @@ struct iwl_lq_sta {
389 u8 last_bt_traffic; 389 u8 last_bt_traffic;
390}; 390};
391 391
392static inline u8 num_of_ant(u8 mask)
393{
394 return !!((mask) & ANT_A) +
395 !!((mask) & ANT_B) +
396 !!((mask) & ANT_C);
397}
398
399static inline u8 first_antenna(u8 mask) 392static inline u8 first_antenna(u8 mask)
400{ 393{
401 if (mask & ANT_A) 394 if (mask & ANT_A)
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index 1fef5240e6ad..e12b1a63c484 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -368,6 +368,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
368 goto drop_unlock_priv; 368 goto drop_unlock_priv;
369 369
370 memset(dev_cmd, 0, sizeof(*dev_cmd)); 370 memset(dev_cmd, 0, sizeof(*dev_cmd));
371 dev_cmd->hdr.cmd = REPLY_TX;
371 tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload; 372 tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload;
372 373
373 /* Total # bytes to be transmitted */ 374 /* Total # bytes to be transmitted */
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 03fd9aa8bfda..0b916249669e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -129,6 +129,12 @@ enum iwl_led_mode {
129#define ANT_BC (ANT_B | ANT_C) 129#define ANT_BC (ANT_B | ANT_C)
130#define ANT_ABC (ANT_A | ANT_B | ANT_C) 130#define ANT_ABC (ANT_A | ANT_B | ANT_C)
131 131
132static inline u8 num_of_ant(u8 mask)
133{
134 return !!((mask) & ANT_A) +
135 !!((mask) & ANT_B) +
136 !!((mask) & ANT_C);
137}
132 138
133/* 139/*
134 * @max_ll_items: max number of OTP blocks 140 * @max_ll_items: max number of OTP blocks
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 2fab203d3027..94aef22df73a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -283,7 +283,8 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
283 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | 283 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
284 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14); 284 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
285 285
286 if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) { 286 if (num_of_ant(data->valid_rx_ant) == 1 ||
287 cfg->rx_with_siso_diversity) {
287 vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN | 288 vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
288 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN; 289 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
289 /* this works because NOT_SUPPORTED == 3 */ 290 /* this works because NOT_SUPPORTED == 3 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index a70c7b9d9bad..f6412dae2659 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -102,6 +102,9 @@
102/* Device system time */ 102/* Device system time */
103#define DEVICE_SYSTEM_TIME_REG 0xA0206C 103#define DEVICE_SYSTEM_TIME_REG 0xA0206C
104 104
105/* Device NMI register */
106#define DEVICE_SET_NMI_REG 0x00a01c30
107
105/***************************************************************************** 108/*****************************************************************************
106 * 7000/3000 series SHR DTS addresses * 109 * 7000/3000 series SHR DTS addresses *
107 *****************************************************************************/ 110 *****************************************************************************/
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index 6d73817850ce..285d8c7486f5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -5,6 +5,7 @@ iwlmvm-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
8iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o
8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o 9iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
9 10
10ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../ 11ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
index 75b72a956552..d126245c48de 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -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/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index b9b81e881dd0..665f87e788d6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -1216,10 +1216,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1216 if (len >= sizeof(u32) * 2) { 1216 if (len >= sizeof(u32) * 2) {
1217 mvm->d3_test_pme_ptr = 1217 mvm->d3_test_pme_ptr =
1218 le32_to_cpup((__le32 *)d3_cfg_cmd.resp_pkt->data); 1218 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 } 1219 }
1224#endif 1220#endif
1225 iwl_free_resp(&d3_cfg_cmd); 1221 iwl_free_resp(&d3_cfg_cmd);
@@ -1231,10 +1227,11 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1231 mvm->aux_sta.sta_id = old_aux_sta_id; 1227 mvm->aux_sta.sta_id = old_aux_sta_id;
1232 mvm_ap_sta->sta_id = old_ap_sta_id; 1228 mvm_ap_sta->sta_id = old_ap_sta_id;
1233 mvmvif->ap_sta_id = old_ap_sta_id; 1229 mvmvif->ap_sta_id = old_ap_sta_id;
1234 out_noreset: 1230
1235 kfree(key_data.rsc_tsc);
1236 if (ret < 0) 1231 if (ret < 0)
1237 ieee80211_restart_hw(mvm->hw); 1232 ieee80211_restart_hw(mvm->hw);
1233 out_noreset:
1234 kfree(key_data.rsc_tsc);
1238 1235
1239 mutex_unlock(&mvm->mutex); 1236 mutex_unlock(&mvm->mutex);
1240 1237
@@ -1537,10 +1534,16 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
1537 struct iwl_mvm_d3_gtk_iter_data gtkdata = { 1534 struct iwl_mvm_d3_gtk_iter_data gtkdata = {
1538 .status = status, 1535 .status = status,
1539 }; 1536 };
1537 u32 disconnection_reasons =
1538 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
1539 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH;
1540 1540
1541 if (!status || !vif->bss_conf.bssid) 1541 if (!status || !vif->bss_conf.bssid)
1542 return false; 1542 return false;
1543 1543
1544 if (le32_to_cpu(status->wakeup_reasons) & disconnection_reasons)
1545 return false;
1546
1544 /* find last GTK that we used initially, if any */ 1547 /* find last GTK that we used initially, if any */
1545 gtkdata.find_phase = true; 1548 gtkdata.find_phase = true;
1546 ieee80211_iter_keys(mvm->hw, vif, 1549 ieee80211_iter_keys(mvm->hw, vif,
@@ -1805,6 +1808,10 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
1805 iwl_mvm_read_d3_sram(mvm); 1808 iwl_mvm_read_d3_sram(mvm);
1806 1809
1807 keep = iwl_mvm_query_wakeup_reasons(mvm, vif); 1810 keep = iwl_mvm_query_wakeup_reasons(mvm, vif);
1811#ifdef CONFIG_IWLWIFI_DEBUGFS
1812 if (keep)
1813 mvm->keep_vif = vif;
1814#endif
1808 /* has unlocked the mutex, so skip that */ 1815 /* has unlocked the mutex, so skip that */
1809 goto out; 1816 goto out;
1810 1817
@@ -1861,6 +1868,7 @@ static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file)
1861 return err; 1868 return err;
1862 } 1869 }
1863 mvm->d3_test_active = true; 1870 mvm->d3_test_active = true;
1871 mvm->keep_vif = NULL;
1864 return 0; 1872 return 0;
1865} 1873}
1866 1874
@@ -1871,10 +1879,14 @@ static ssize_t iwl_mvm_d3_test_read(struct file *file, char __user *user_buf,
1871 u32 pme_asserted; 1879 u32 pme_asserted;
1872 1880
1873 while (true) { 1881 while (true) {
1874 pme_asserted = iwl_trans_read_mem32(mvm->trans, 1882 /* read pme_ptr if available */
1875 mvm->d3_test_pme_ptr); 1883 if (mvm->d3_test_pme_ptr) {
1876 if (pme_asserted) 1884 pme_asserted = iwl_trans_read_mem32(mvm->trans,
1877 break; 1885 mvm->d3_test_pme_ptr);
1886 if (pme_asserted)
1887 break;
1888 }
1889
1878 if (msleep_interruptible(100)) 1890 if (msleep_interruptible(100))
1879 break; 1891 break;
1880 } 1892 }
@@ -1885,6 +1897,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, 1897static void iwl_mvm_d3_test_disconn_work_iter(void *_data, u8 *mac,
1886 struct ieee80211_vif *vif) 1898 struct ieee80211_vif *vif)
1887{ 1899{
1900 /* skip the one we keep connection on */
1901 if (_data == vif)
1902 return;
1903
1888 if (vif->type == NL80211_IFTYPE_STATION) 1904 if (vif->type == NL80211_IFTYPE_STATION)
1889 ieee80211_connection_loss(vif); 1905 ieee80211_connection_loss(vif);
1890} 1906}
@@ -1911,7 +1927,7 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
1911 1927
1912 ieee80211_iterate_active_interfaces_atomic( 1928 ieee80211_iterate_active_interfaces_atomic(
1913 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 1929 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1914 iwl_mvm_d3_test_disconn_work_iter, NULL); 1930 iwl_mvm_d3_test_disconn_work_iter, mvm->keep_vif);
1915 1931
1916 ieee80211_wake_queues(mvm->hw); 1932 ieee80211_wake_queues(mvm->hw);
1917 1933
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..67f6a2071653
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
@@ -0,0 +1,190 @@
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 - 2013 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 - 2013 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 ssize_t iwl_dbgfs_mac_params_read(struct file *file,
67 char __user *user_buf,
68 size_t count, loff_t *ppos)
69{
70 struct ieee80211_vif *vif = file->private_data;
71 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
72 struct iwl_mvm *mvm = mvmvif->mvm;
73 u8 ap_sta_id;
74 struct ieee80211_chanctx_conf *chanctx_conf;
75 char buf[512];
76 int bufsz = sizeof(buf);
77 int pos = 0;
78 int i;
79
80 mutex_lock(&mvm->mutex);
81
82 ap_sta_id = mvmvif->ap_sta_id;
83
84 pos += scnprintf(buf+pos, bufsz-pos, "mac id/color: %d / %d\n",
85 mvmvif->id, mvmvif->color);
86 pos += scnprintf(buf+pos, bufsz-pos, "bssid: %pM\n",
87 vif->bss_conf.bssid);
88 pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n");
89 for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++)
90 pos += scnprintf(buf+pos, bufsz-pos,
91 "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n",
92 i, mvmvif->queue_params[i].txop,
93 mvmvif->queue_params[i].cw_min,
94 mvmvif->queue_params[i].cw_max,
95 mvmvif->queue_params[i].aifs,
96 mvmvif->queue_params[i].uapsd);
97
98 if (vif->type == NL80211_IFTYPE_STATION &&
99 ap_sta_id != IWL_MVM_STATION_COUNT) {
100 struct ieee80211_sta *sta;
101 struct iwl_mvm_sta *mvm_sta;
102
103 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[ap_sta_id],
104 lockdep_is_held(&mvm->mutex));
105 mvm_sta = (void *)sta->drv_priv;
106 pos += scnprintf(buf+pos, bufsz-pos,
107 "ap_sta_id %d - reduced Tx power %d\n",
108 ap_sta_id, mvm_sta->bt_reduced_txpower);
109 }
110
111 rcu_read_lock();
112 chanctx_conf = rcu_dereference(vif->chanctx_conf);
113 if (chanctx_conf)
114 pos += scnprintf(buf+pos, bufsz-pos,
115 "idle rx chains %d, active rx chains: %d\n",
116 chanctx_conf->rx_chains_static,
117 chanctx_conf->rx_chains_dynamic);
118 rcu_read_unlock();
119
120 mutex_unlock(&mvm->mutex);
121
122 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
123}
124
125#define MVM_DEBUGFS_ADD_FILE_VIF(name, parent, mode) do { \
126 if (!debugfs_create_file(#name, mode, parent, vif, \
127 &iwl_dbgfs_##name##_ops)) \
128 goto err; \
129 } while (0)
130
131MVM_DEBUGFS_READ_FILE_OPS(mac_params);
132
133void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
134{
135 struct dentry *dbgfs_dir = vif->debugfs_dir;
136 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
137 char buf[100];
138
139 /*
140 * Check if debugfs directory already exist before creating it.
141 * This may happen when, for example, resetting hw or suspend-resume
142 */
143 if (!dbgfs_dir || mvmvif->dbgfs_dir)
144 return;
145
146 mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
147 mvmvif->mvm = mvm;
148
149 if (!mvmvif->dbgfs_dir) {
150 IWL_ERR(mvm, "Failed to create debugfs directory under %s\n",
151 dbgfs_dir->d_name.name);
152 return;
153 }
154
155 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir,
156 S_IRUSR);
157
158 /*
159 * Create symlink for convenience pointing to interface specific
160 * debugfs entries for the driver. For example, under
161 * /sys/kernel/debug/iwlwifi/0000\:02\:00.0/iwlmvm/
162 * find
163 * netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/
164 */
165 snprintf(buf, 100, "../../../%s/%s/%s/%s",
166 dbgfs_dir->d_parent->d_parent->d_name.name,
167 dbgfs_dir->d_parent->d_name.name,
168 dbgfs_dir->d_name.name,
169 mvmvif->dbgfs_dir->d_name.name);
170
171 mvmvif->dbgfs_slink = debugfs_create_symlink(dbgfs_dir->d_name.name,
172 mvm->debugfs_dir, buf);
173 if (!mvmvif->dbgfs_slink)
174 IWL_ERR(mvm, "Can't create debugfs symbolic link under %s\n",
175 dbgfs_dir->d_name.name);
176 return;
177err:
178 IWL_ERR(mvm, "Can't create debugfs entity\n");
179}
180
181void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
182{
183 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
184
185 debugfs_remove(mvmvif->dbgfs_slink);
186 mvmvif->dbgfs_slink = NULL;
187
188 debugfs_remove_recursive(mvmvif->dbgfs_dir);
189 mvmvif->dbgfs_dir = NULL;
190}
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index a8fe6b41f9a3..e8f62a6a1b57 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -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)
@@ -194,20 +173,11 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
194 return ret; 173 return ret;
195} 174}
196 175
197static ssize_t iwl_dbgfs_sram_write(struct file *file, 176static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf,
198 const char __user *user_buf, size_t count, 177 size_t count, loff_t *ppos)
199 loff_t *ppos)
200{ 178{
201 struct iwl_mvm *mvm = file->private_data;
202 char buf[64];
203 int buf_size;
204 u32 offset, len; 179 u32 offset, len;
205 180
206 memset(buf, 0, sizeof(buf));
207 buf_size = min(count, sizeof(buf) - 1);
208 if (copy_from_user(buf, user_buf, buf_size))
209 return -EFAULT;
210
211 if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 181 if (sscanf(buf, "%x,%x", &offset, &len) == 2) {
212 if ((offset & 0x3) || (len & 0x3)) 182 if ((offset & 0x3) || (len & 0x3))
213 return -EINVAL; 183 return -EINVAL;
@@ -267,22 +237,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); 237 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
268} 238}
269 239
270static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file, 240static 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) 241 size_t count, loff_t *ppos)
273{ 242{
274 struct iwl_mvm *mvm = file->private_data; 243 int ret, val;
275 char buf[64] = {};
276 int ret;
277 int val;
278 244
279 if (!mvm->ucode_loaded) 245 if (!mvm->ucode_loaded)
280 return -EIO; 246 return -EIO;
281 247
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)) { 248 if (!strncmp("disable_power_off_d0=", buf, 21)) {
287 if (sscanf(buf + 21, "%d", &val) != 1) 249 if (sscanf(buf + 21, "%d", &val) != 1)
288 return -EINVAL; 250 return -EINVAL;
@@ -302,212 +264,6 @@ static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file,
302 return ret ?: count; 264 return ret ?: count;
303} 265}
304 266
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) \ 267#define BT_MBOX_MSG(_notif, _num, _field) \
512 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ 268 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
513 >> BT_MBOX##_num##_##_field##_POS) 269 >> BT_MBOX##_num##_##_field##_POS)
@@ -783,11 +539,9 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
783} 539}
784#undef PRINT_STAT_LE32 540#undef PRINT_STAT_LE32
785 541
786static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, 542static 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) 543 size_t count, loff_t *ppos)
789{ 544{
790 struct iwl_mvm *mvm = file->private_data;
791 int ret; 545 int ret;
792 546
793 mutex_lock(&mvm->mutex); 547 mutex_lock(&mvm->mutex);
@@ -804,6 +558,14 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
804 return count; 558 return count;
805} 559}
806 560
561static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf,
562 size_t count, loff_t *ppos)
563{
564 iwl_write_prph(mvm->trans, DEVICE_SET_NMI_REG, 1);
565
566 return count;
567}
568
807static ssize_t 569static ssize_t
808iwl_dbgfs_scan_ant_rxchain_read(struct file *file, 570iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
809 char __user *user_buf, 571 char __user *user_buf,
@@ -828,21 +590,11 @@ iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
828} 590}
829 591
830static ssize_t 592static ssize_t
831iwl_dbgfs_scan_ant_rxchain_write(struct file *file, 593iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
832 const char __user *user_buf,
833 size_t count, loff_t *ppos) 594 size_t count, loff_t *ppos)
834{ 595{
835 struct iwl_mvm *mvm = file->private_data;
836 char buf[8];
837 int buf_size;
838 u8 scan_rx_ant; 596 u8 scan_rx_ant;
839 597
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) 598 if (sscanf(buf, "%hhx", &scan_rx_ant) != 1)
847 return -EINVAL; 599 return -EINVAL;
848 if (scan_rx_ant > ANT_ABC) 600 if (scan_rx_ant > ANT_ABC)
@@ -850,228 +602,17 @@ iwl_dbgfs_scan_ant_rxchain_write(struct file *file,
850 if (scan_rx_ant & ~iwl_fw_valid_rx_ant(mvm->fw)) 602 if (scan_rx_ant & ~iwl_fw_valid_rx_ant(mvm->fw))
851 return -EINVAL; 603 return -EINVAL;
852 604
853 /* change the rx antennas for scan command */
854 mvm->scan_rx_ant = scan_rx_ant; 605 mvm->scan_rx_ant = scan_rx_ant;
855 606
856 return count; 607 return count;
857} 608}
858 609
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 610#ifdef CONFIG_PM_SLEEP
1063static ssize_t iwl_dbgfs_d3_sram_write(struct file *file, 611static 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) 612 size_t count, loff_t *ppos)
1066{ 613{
1067 struct iwl_mvm *mvm = file->private_data;
1068 char buf[8] = {};
1069 int store; 614 int store;
1070 615
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) 616 if (sscanf(buf, "%d", &store) != 1)
1076 return -EINVAL; 617 return -EINVAL;
1077 618
@@ -1124,61 +665,33 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
1124} 665}
1125#endif 666#endif
1126 667
1127#define MVM_DEBUGFS_READ_FILE_OPS(name) \ 668#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
1128static const struct file_operations iwl_dbgfs_##name##_ops = { \ 669 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
1129 .read = iwl_dbgfs_##name##_read, \ 670#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
1130 .open = simple_open, \ 671 _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 { \ 672#define MVM_DEBUGFS_ADD_FILE(name, parent, mode) do { \
1150 if (!debugfs_create_file(#name, mode, parent, mvm, \ 673 if (!debugfs_create_file(#name, mode, parent, mvm, \
1151 &iwl_dbgfs_##name##_ops)) \ 674 &iwl_dbgfs_##name##_ops)) \
1152 goto err; \ 675 goto err; \
1153 } while (0) 676 } while (0)
1154 677
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 */ 678/* Device wide debugfs entries */
1162MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush); 679MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
1163MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); 680MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
1164MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); 681MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64);
1165MVM_DEBUGFS_READ_FILE_OPS(stations); 682MVM_DEBUGFS_READ_FILE_OPS(stations);
1166MVM_DEBUGFS_READ_FILE_OPS(bt_notif); 683MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
1167MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); 684MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
1168MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off); 685MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64);
1169MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats); 686MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
1170MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); 687MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
1171MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain); 688MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
689MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
1172 690
1173#ifdef CONFIG_PM_SLEEP 691#ifdef CONFIG_PM_SLEEP
1174MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram); 692MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8);
1175#endif 693#endif
1176 694
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) 695int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1183{ 696{
1184 char buf[100]; 697 char buf[100];
@@ -1196,6 +709,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1196 S_IRUSR | S_IWUSR); 709 S_IRUSR | S_IWUSR);
1197 MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR); 710 MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR);
1198 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); 711 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
712 MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, S_IWUSR);
1199 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 713 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir,
1200 S_IWUSR | S_IRUSR); 714 S_IWUSR | S_IRUSR);
1201#ifdef CONFIG_PM_SLEEP 715#ifdef CONFIG_PM_SLEEP
@@ -1206,6 +720,19 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1206 goto err; 720 goto err;
1207#endif 721#endif
1208 722
723 if (!debugfs_create_blob("nvm_hw", S_IRUSR,
724 mvm->debugfs_dir, &mvm->nvm_hw_blob))
725 goto err;
726 if (!debugfs_create_blob("nvm_sw", S_IRUSR,
727 mvm->debugfs_dir, &mvm->nvm_sw_blob))
728 goto err;
729 if (!debugfs_create_blob("nvm_calib", S_IRUSR,
730 mvm->debugfs_dir, &mvm->nvm_calib_blob))
731 goto err;
732 if (!debugfs_create_blob("nvm_prod", S_IRUSR,
733 mvm->debugfs_dir, &mvm->nvm_prod_blob))
734 goto err;
735
1209 /* 736 /*
1210 * Create a symlink with mac80211. It will be removed when mac80211 737 * Create a symlink with mac80211. It will be removed when mac80211
1211 * exists (before the opmode exists which removes the target.) 738 * exists (before the opmode exists which removes the target.)
@@ -1221,72 +748,3 @@ err:
1221 IWL_ERR(mvm, "Can't create the mvm debugfs directory\n"); 748 IWL_ERR(mvm, "Can't create the mvm debugfs directory\n");
1222 return -ENOMEM; 749 return -ENOMEM;
1223} 750}
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..85f9f958bfd2
--- /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 - 2013 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 - 2013 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..af500996bbf1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
@@ -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-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
index 538f1c7a5966..532312c7b937 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
@@ -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..b3ed59237cba 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -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/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index f41f9b079831..fb93961da750 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -488,6 +488,40 @@ static void iwl_mvm_ack_rates(struct iwl_mvm *mvm,
488 *ofdm_rates = ofdm; 488 *ofdm_rates = ofdm;
489} 489}
490 490
491static void iwl_mvm_mac_ctxt_set_ht_flags(struct iwl_mvm *mvm,
492 struct ieee80211_vif *vif,
493 struct iwl_mac_ctx_cmd *cmd)
494{
495 /* for both sta and ap, ht_operation_mode hold the protection_mode */
496 u8 protection_mode = vif->bss_conf.ht_operation_mode &
497 IEEE80211_HT_OP_MODE_PROTECTION;
498 /* The fw does not distinguish between ht and fat */
499 u32 ht_flag = MAC_PROT_FLG_HT_PROT | MAC_PROT_FLG_FAT_PROT;
500
501 IWL_DEBUG_RATE(mvm, "protection mode set to %d\n", protection_mode);
502 /*
503 * See section 9.23.3.1 of IEEE 80211-2012.
504 * Nongreenfield HT STAs Present is not supported.
505 */
506 switch (protection_mode) {
507 case IEEE80211_HT_OP_MODE_PROTECTION_NONE:
508 break;
509 case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
510 case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
511 cmd->protection_flags |= cpu_to_le32(ht_flag);
512 break;
513 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
514 /* Protect when channel wider than 20MHz */
515 if (vif->bss_conf.chandef.width > NL80211_CHAN_WIDTH_20)
516 cmd->protection_flags |= cpu_to_le32(ht_flag);
517 break;
518 default:
519 IWL_ERR(mvm, "Illegal protection mode %d\n",
520 protection_mode);
521 break;
522 }
523}
524
491static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, 525static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
492 struct ieee80211_vif *vif, 526 struct ieee80211_vif *vif,
493 struct iwl_mac_ctx_cmd *cmd, 527 struct iwl_mac_ctx_cmd *cmd,
@@ -495,6 +529,8 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
495{ 529{
496 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 530 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
497 struct ieee80211_chanctx_conf *chanctx; 531 struct ieee80211_chanctx_conf *chanctx;
532 bool ht_enabled = !!(vif->bss_conf.ht_operation_mode &
533 IEEE80211_HT_OP_MODE_PROTECTION);
498 u8 cck_ack_rates, ofdm_ack_rates; 534 u8 cck_ack_rates, ofdm_ack_rates;
499 int i; 535 int i;
500 536
@@ -573,16 +609,13 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
573 cmd->protection_flags |= 609 cmd->protection_flags |=
574 cpu_to_le32(MAC_PROT_FLG_SELF_CTS_EN); 610 cpu_to_le32(MAC_PROT_FLG_SELF_CTS_EN);
575 } 611 }
576 612 IWL_DEBUG_RATE(mvm, "use_cts_prot %d, ht_operation_mode %d\n",
577 /* 613 vif->bss_conf.use_cts_prot,
578 * I think that we should enable these 2 flags regardless the HT PROT 614 vif->bss_conf.ht_operation_mode);
579 * fields in the HT IE, but I am not sure. Someone knows whom to ask?... 615 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); 616 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_TGN);
583 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_HT_PROT | 617 if (ht_enabled)
584 MAC_PROT_FLG_FAT_PROT); 618 iwl_mvm_mac_ctxt_set_ht_flags(mvm, vif, cmd);
585 }
586 619
587 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP); 620 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP);
588} 621}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index b56c989ad784..afc4419be46d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -256,7 +256,8 @@ 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
@@ -990,6 +991,17 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
990 struct ieee80211_bss_conf *bss_conf, 991 struct ieee80211_bss_conf *bss_conf,
991 u32 changes) 992 u32 changes)
992{ 993{
994 enum ieee80211_bss_change ht_change = BSS_CHANGED_ERP_CTS_PROT |
995 BSS_CHANGED_HT |
996 BSS_CHANGED_BANDWIDTH;
997 int ret;
998
999 if (changes & ht_change) {
1000 ret = iwl_mvm_mac_ctxt_changed(mvm, vif);
1001 if (ret)
1002 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
1003 }
1004
993 /* Need to send a new beacon template to the FW */ 1005 /* Need to send a new beacon template to the FW */
994 if (changes & BSS_CHANGED_BEACON) { 1006 if (changes & BSS_CHANGED_BEACON) {
995 if (iwl_mvm_mac_ctxt_beacon_changed(mvm, vif)) 1007 if (iwl_mvm_mac_ctxt_beacon_changed(mvm, vif))
@@ -1080,7 +1092,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
1080 struct ieee80211_sta *sta) 1092 struct ieee80211_sta *sta)
1081{ 1093{
1082 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1094 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1083 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1095 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1084 1096
1085 switch (cmd) { 1097 switch (cmd) {
1086 case STA_NOTIFY_SLEEP: 1098 case STA_NOTIFY_SLEEP:
@@ -1149,7 +1161,8 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
1149 ret = iwl_mvm_update_sta(mvm, vif, sta); 1161 ret = iwl_mvm_update_sta(mvm, vif, sta);
1150 if (ret == 0) 1162 if (ret == 0)
1151 iwl_mvm_rs_rate_init(mvm, sta, 1163 iwl_mvm_rs_rate_init(mvm, sta,
1152 mvmvif->phy_ctxt->channel->band); 1164 mvmvif->phy_ctxt->channel->band,
1165 true);
1153 } else if (old_state == IEEE80211_STA_ASSOC && 1166 } else if (old_state == IEEE80211_STA_ASSOC &&
1154 new_state == IEEE80211_STA_AUTHORIZED) { 1167 new_state == IEEE80211_STA_AUTHORIZED) {
1155 /* enable beacon filtering */ 1168 /* enable beacon filtering */
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index fed21ef4162d..7dc57cfe5803 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -323,9 +323,9 @@ struct iwl_mvm_vif {
323#endif 323#endif
324 324
325#ifdef CONFIG_IWLWIFI_DEBUGFS 325#ifdef CONFIG_IWLWIFI_DEBUGFS
326 struct iwl_mvm *mvm;
326 struct dentry *dbgfs_dir; 327 struct dentry *dbgfs_dir;
327 struct dentry *dbgfs_slink; 328 struct dentry *dbgfs_slink;
328 void *dbgfs_data;
329 struct iwl_dbgfs_pm dbgfs_pm; 329 struct iwl_dbgfs_pm dbgfs_pm;
330 struct iwl_dbgfs_bf dbgfs_bf; 330 struct iwl_dbgfs_bf dbgfs_bf;
331#endif 331#endif
@@ -494,6 +494,11 @@ struct iwl_mvm {
494 u32 dbgfs_sram_offset, dbgfs_sram_len; 494 u32 dbgfs_sram_offset, dbgfs_sram_len;
495 bool disable_power_off; 495 bool disable_power_off;
496 bool disable_power_off_d3; 496 bool disable_power_off_d3;
497
498 struct debugfs_blob_wrapper nvm_hw_blob;
499 struct debugfs_blob_wrapper nvm_sw_blob;
500 struct debugfs_blob_wrapper nvm_calib_blob;
501 struct debugfs_blob_wrapper nvm_prod_blob;
497#endif 502#endif
498 503
499 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX]; 504 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
@@ -531,6 +536,7 @@ struct iwl_mvm {
531 bool store_d3_resume_sram; 536 bool store_d3_resume_sram;
532 void *d3_resume_sram; 537 void *d3_resume_sram;
533 u32 d3_test_pme_ptr; 538 u32 d3_test_pme_ptr;
539 struct ieee80211_vif *keep_vif;
534#endif 540#endif
535#endif 541#endif
536 542
@@ -750,8 +756,7 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
750#endif /* CONFIG_IWLWIFI_DEBUGFS */ 756#endif /* CONFIG_IWLWIFI_DEBUGFS */
751 757
752/* rate scaling */ 758/* rate scaling */
753int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, 759int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init);
754 u8 flags, bool init);
755 760
756/* power managment */ 761/* power managment */
757static inline int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, 762static inline int iwl_mvm_power_update_mode(struct iwl_mvm *mvm,
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 2beffd028b67..48089b1625ff 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -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/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index 17e2bc827f9a..38165eba2a17 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -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..bf6e29f5b4d0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -47,28 +47,25 @@
47#define IWL_HT_NUMBER_TRY 3 47#define IWL_HT_NUMBER_TRY 3
48 48
49#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */ 49#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */
50#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */ 50#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 */ 51#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */
52 52
53/* max allowed rate miss before sync LQ cmd */ 53/* max allowed rate miss before sync LQ cmd */
54#define IWL_MISSED_RATE_MAX 15 54#define IWL_MISSED_RATE_MAX 15
55/* max time to accum history 2 seconds */ 55#define RS_STAY_IN_COLUMN_TIMEOUT (5*HZ)
56#define IWL_RATE_SCALE_FLUSH_INTVL (3*HZ) 56
57 57
58static u8 rs_ht_to_legacy[] = { 58static u8 rs_ht_to_legacy[] = {
59 [IWL_RATE_1M_INDEX] = IWL_RATE_6M_INDEX, 59 [IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX,
60 [IWL_RATE_2M_INDEX] = IWL_RATE_6M_INDEX, 60 [IWL_RATE_MCS_1_INDEX] = IWL_RATE_9M_INDEX,
61 [IWL_RATE_5M_INDEX] = IWL_RATE_6M_INDEX, 61 [IWL_RATE_MCS_2_INDEX] = IWL_RATE_12M_INDEX,
62 [IWL_RATE_11M_INDEX] = IWL_RATE_6M_INDEX, 62 [IWL_RATE_MCS_3_INDEX] = IWL_RATE_18M_INDEX,
63 [IWL_RATE_6M_INDEX] = IWL_RATE_6M_INDEX, 63 [IWL_RATE_MCS_4_INDEX] = IWL_RATE_24M_INDEX,
64 [IWL_RATE_9M_INDEX] = IWL_RATE_6M_INDEX, 64 [IWL_RATE_MCS_5_INDEX] = IWL_RATE_36M_INDEX,
65 [IWL_RATE_12M_INDEX] = IWL_RATE_9M_INDEX, 65 [IWL_RATE_MCS_6_INDEX] = IWL_RATE_48M_INDEX,
66 [IWL_RATE_18M_INDEX] = IWL_RATE_12M_INDEX, 66 [IWL_RATE_MCS_7_INDEX] = IWL_RATE_54M_INDEX,
67 [IWL_RATE_24M_INDEX] = IWL_RATE_18M_INDEX, 67 [IWL_RATE_MCS_8_INDEX] = IWL_RATE_54M_INDEX,
68 [IWL_RATE_36M_INDEX] = IWL_RATE_24M_INDEX, 68 [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}; 69};
73 70
74static const u8 ant_toggle_lookup[] = { 71static const u8 ant_toggle_lookup[] = {
@@ -126,6 +123,190 @@ static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = {
126 IWL_DECLARE_MCS_RATE(9), /* MCS 9 */ 123 IWL_DECLARE_MCS_RATE(9), /* MCS 9 */
127}; 124};
128 125
126enum rs_column_mode {
127 RS_INVALID = 0,
128 RS_LEGACY,
129 RS_SISO,
130 RS_MIMO2,
131};
132
133#define MAX_NEXT_COLUMNS 5
134#define MAX_COLUMN_CHECKS 3
135
136typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm,
137 struct ieee80211_sta *sta,
138 struct iwl_scale_tbl_info *tbl);
139
140struct rs_tx_column {
141 enum rs_column_mode mode;
142 u8 ant;
143 bool sgi;
144 enum rs_column next_columns[MAX_NEXT_COLUMNS];
145 allow_column_func_t checks[MAX_COLUMN_CHECKS];
146};
147
148static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
149 struct iwl_scale_tbl_info *tbl)
150{
151 if (!sta->ht_cap.ht_supported)
152 return false;
153
154 if (sta->smps_mode == IEEE80211_SMPS_STATIC)
155 return false;
156
157 if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 2)
158 return false;
159
160 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
161 return false;
162
163 return true;
164}
165
166static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
167 struct iwl_scale_tbl_info *tbl)
168{
169 if (!sta->ht_cap.ht_supported)
170 return false;
171
172 return true;
173}
174
175static bool rs_sgi_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
176 struct iwl_scale_tbl_info *tbl)
177{
178 struct rs_rate *rate = &tbl->rate;
179 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
180 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
181
182 if (is_ht20(rate) && (ht_cap->cap &
183 IEEE80211_HT_CAP_SGI_20))
184 return true;
185 if (is_ht40(rate) && (ht_cap->cap &
186 IEEE80211_HT_CAP_SGI_40))
187 return true;
188 if (is_ht80(rate) && (vht_cap->cap &
189 IEEE80211_VHT_CAP_SHORT_GI_80))
190 return true;
191
192 return false;
193}
194
195static const struct rs_tx_column rs_tx_columns[] = {
196 [RS_COLUMN_LEGACY_ANT_A] = {
197 .mode = RS_LEGACY,
198 .ant = ANT_A,
199 .next_columns = {
200 RS_COLUMN_LEGACY_ANT_B,
201 RS_COLUMN_SISO_ANT_A,
202 RS_COLUMN_MIMO2,
203 RS_COLUMN_INVALID,
204 RS_COLUMN_INVALID,
205 },
206 },
207 [RS_COLUMN_LEGACY_ANT_B] = {
208 .mode = RS_LEGACY,
209 .ant = ANT_B,
210 .next_columns = {
211 RS_COLUMN_LEGACY_ANT_A,
212 RS_COLUMN_SISO_ANT_B,
213 RS_COLUMN_MIMO2,
214 RS_COLUMN_INVALID,
215 RS_COLUMN_INVALID,
216 },
217 },
218 [RS_COLUMN_SISO_ANT_A] = {
219 .mode = RS_SISO,
220 .ant = ANT_A,
221 .next_columns = {
222 RS_COLUMN_SISO_ANT_B,
223 RS_COLUMN_MIMO2,
224 RS_COLUMN_SISO_ANT_A_SGI,
225 RS_COLUMN_INVALID,
226 RS_COLUMN_INVALID,
227 },
228 .checks = {
229 rs_siso_allow,
230 },
231 },
232 [RS_COLUMN_SISO_ANT_B] = {
233 .mode = RS_SISO,
234 .ant = ANT_B,
235 .next_columns = {
236 RS_COLUMN_SISO_ANT_A,
237 RS_COLUMN_MIMO2,
238 RS_COLUMN_SISO_ANT_B_SGI,
239 RS_COLUMN_INVALID,
240 RS_COLUMN_INVALID,
241 },
242 .checks = {
243 rs_siso_allow,
244 },
245 },
246 [RS_COLUMN_SISO_ANT_A_SGI] = {
247 .mode = RS_SISO,
248 .ant = ANT_A,
249 .sgi = true,
250 .next_columns = {
251 RS_COLUMN_SISO_ANT_B_SGI,
252 RS_COLUMN_MIMO2_SGI,
253 RS_COLUMN_SISO_ANT_A,
254 RS_COLUMN_INVALID,
255 RS_COLUMN_INVALID,
256 },
257 .checks = {
258 rs_siso_allow,
259 rs_sgi_allow,
260 },
261 },
262 [RS_COLUMN_SISO_ANT_B_SGI] = {
263 .mode = RS_SISO,
264 .ant = ANT_B,
265 .sgi = true,
266 .next_columns = {
267 RS_COLUMN_SISO_ANT_A_SGI,
268 RS_COLUMN_MIMO2_SGI,
269 RS_COLUMN_SISO_ANT_B,
270 RS_COLUMN_INVALID,
271 RS_COLUMN_INVALID,
272 },
273 .checks = {
274 rs_siso_allow,
275 rs_sgi_allow,
276 },
277 },
278 [RS_COLUMN_MIMO2] = {
279 .mode = RS_MIMO2,
280 .ant = ANT_AB,
281 .next_columns = {
282 RS_COLUMN_SISO_ANT_A,
283 RS_COLUMN_MIMO2_SGI,
284 RS_COLUMN_INVALID,
285 RS_COLUMN_INVALID,
286 RS_COLUMN_INVALID,
287 },
288 .checks = {
289 rs_mimo_allow,
290 },
291 },
292 [RS_COLUMN_MIMO2_SGI] = {
293 .mode = RS_MIMO2,
294 .ant = ANT_AB,
295 .sgi = true,
296 .next_columns = {
297 RS_COLUMN_SISO_ANT_A_SGI,
298 RS_COLUMN_MIMO2,
299 RS_COLUMN_INVALID,
300 RS_COLUMN_INVALID,
301 RS_COLUMN_INVALID,
302 },
303 .checks = {
304 rs_mimo_allow,
305 rs_sgi_allow,
306 },
307 },
308};
309
129static inline u8 rs_extract_rate(u32 rate_n_flags) 310static inline u8 rs_extract_rate(u32 rate_n_flags)
130{ 311{
131 /* also works for HT because bits 7:6 are zero there */ 312 /* also works for HT because bits 7:6 are zero there */
@@ -175,7 +356,6 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
175 struct iwl_lq_sta *lq_sta, u32 rate_n_flags); 356 struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
176static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search); 357static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);
177 358
178
179#ifdef CONFIG_MAC80211_DEBUGFS 359#ifdef CONFIG_MAC80211_DEBUGFS
180static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, 360static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
181 u32 *rate_n_flags); 361 u32 *rate_n_flags);
@@ -264,6 +444,52 @@ static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
264 444
265#define MCS_INDEX_PER_STREAM (8) 445#define MCS_INDEX_PER_STREAM (8)
266 446
447static const char *rs_pretty_ant(u8 ant)
448{
449 static const char * const ant_name[] = {
450 [ANT_NONE] = "None",
451 [ANT_A] = "A",
452 [ANT_B] = "B",
453 [ANT_AB] = "AB",
454 [ANT_C] = "C",
455 [ANT_AC] = "AC",
456 [ANT_BC] = "BC",
457 [ANT_ABC] = "ABC",
458 };
459
460 if (ant > ANT_ABC)
461 return "UNKNOWN";
462
463 return ant_name[ant];
464}
465
466static const char *rs_pretty_lq_type(enum iwl_table_type type)
467{
468 static const char * const lq_types[] = {
469 [LQ_NONE] = "NONE",
470 [LQ_LEGACY_A] = "LEGACY_A",
471 [LQ_LEGACY_G] = "LEGACY_G",
472 [LQ_HT_SISO] = "HT SISO",
473 [LQ_HT_MIMO2] = "HT MIMO",
474 [LQ_VHT_SISO] = "VHT SISO",
475 [LQ_VHT_MIMO2] = "VHT MIMO",
476 };
477
478 if (type < LQ_NONE || type >= LQ_MAX)
479 return "UNKNOWN";
480
481 return lq_types[type];
482}
483
484static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate,
485 const char *prefix)
486{
487 IWL_DEBUG_RATE(mvm, "%s: (%s: %d) ANT: %s BW: %d SGI: %d\n",
488 prefix, rs_pretty_lq_type(rate->type),
489 rate->index, rs_pretty_ant(rate->ant),
490 rate->bw, rate->sgi);
491}
492
267static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) 493static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
268{ 494{
269 window->data = 0; 495 window->data = 0;
@@ -271,7 +497,6 @@ static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
271 window->success_ratio = IWL_INVALID_VALUE; 497 window->success_ratio = IWL_INVALID_VALUE;
272 window->counter = 0; 498 window->counter = 0;
273 window->average_tpt = IWL_INVALID_VALUE; 499 window->average_tpt = IWL_INVALID_VALUE;
274 window->stamp = 0;
275} 500}
276 501
277static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type) 502static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
@@ -298,7 +523,7 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm,
298 523
299 if (lq_sta->dbg_fixed_rate) { 524 if (lq_sta->dbg_fixed_rate) {
300 rs_fill_link_cmd(NULL, NULL, lq_sta, lq_sta->dbg_fixed_rate); 525 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); 526 iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, false);
302 } 527 }
303} 528}
304#endif 529#endif
@@ -428,192 +653,174 @@ static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
428 else 653 else
429 window->average_tpt = IWL_INVALID_VALUE; 654 window->average_tpt = IWL_INVALID_VALUE;
430 655
431 /* Tag this window as having been updated */
432 window->stamp = jiffies;
433
434 return 0; 656 return 0;
435} 657}
436 658
437/* 659/* Convert rs_rate object into ucode rate bitmask */
438 * Fill uCode API rate_n_flags field, based on "search" or "active" table. 660static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm,
439 */ 661 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{ 662{
444 u32 rate_n_flags = 0; 663 u32 ucode_rate = 0;
664 int index = rate->index;
445 665
446 rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) & 666 ucode_rate |= ((rate->ant << RATE_MCS_ANT_POS) &
447 RATE_MCS_ANT_ABC_MSK); 667 RATE_MCS_ANT_ABC_MSK);
448 668
449 if (is_legacy(tbl->lq_type)) { 669 if (is_legacy(rate)) {
450 rate_n_flags |= iwl_rates[index].plcp; 670 ucode_rate |= iwl_rates[index].plcp;
451 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) 671 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
452 rate_n_flags |= RATE_MCS_CCK_MSK; 672 ucode_rate |= RATE_MCS_CCK_MSK;
453 return rate_n_flags; 673 return ucode_rate;
454 } 674 }
455 675
456 if (is_ht(tbl->lq_type)) { 676 if (is_ht(rate)) {
457 if (index < IWL_FIRST_HT_RATE || index > IWL_LAST_HT_RATE) { 677 if (index < IWL_FIRST_HT_RATE || index > IWL_LAST_HT_RATE) {
458 IWL_ERR(mvm, "Invalid HT rate index %d\n", index); 678 IWL_ERR(mvm, "Invalid HT rate index %d\n", index);
459 index = IWL_LAST_HT_RATE; 679 index = IWL_LAST_HT_RATE;
460 } 680 }
461 rate_n_flags |= RATE_MCS_HT_MSK; 681 ucode_rate |= RATE_MCS_HT_MSK;
462 682
463 if (is_ht_siso(tbl->lq_type)) 683 if (is_ht_siso(rate))
464 rate_n_flags |= iwl_rates[index].plcp_ht_siso; 684 ucode_rate |= iwl_rates[index].plcp_ht_siso;
465 else if (is_ht_mimo2(tbl->lq_type)) 685 else if (is_ht_mimo2(rate))
466 rate_n_flags |= iwl_rates[index].plcp_ht_mimo2; 686 ucode_rate |= iwl_rates[index].plcp_ht_mimo2;
467 else 687 else
468 WARN_ON_ONCE(1); 688 WARN_ON_ONCE(1);
469 } else if (is_vht(tbl->lq_type)) { 689 } else if (is_vht(rate)) {
470 if (index < IWL_FIRST_VHT_RATE || index > IWL_LAST_VHT_RATE) { 690 if (index < IWL_FIRST_VHT_RATE || index > IWL_LAST_VHT_RATE) {
471 IWL_ERR(mvm, "Invalid VHT rate index %d\n", index); 691 IWL_ERR(mvm, "Invalid VHT rate index %d\n", index);
472 index = IWL_LAST_VHT_RATE; 692 index = IWL_LAST_VHT_RATE;
473 } 693 }
474 rate_n_flags |= RATE_MCS_VHT_MSK; 694 ucode_rate |= RATE_MCS_VHT_MSK;
475 if (is_vht_siso(tbl->lq_type)) 695 if (is_vht_siso(rate))
476 rate_n_flags |= iwl_rates[index].plcp_vht_siso; 696 ucode_rate |= iwl_rates[index].plcp_vht_siso;
477 else if (is_vht_mimo2(tbl->lq_type)) 697 else if (is_vht_mimo2(rate))
478 rate_n_flags |= iwl_rates[index].plcp_vht_mimo2; 698 ucode_rate |= iwl_rates[index].plcp_vht_mimo2;
479 else 699 else
480 WARN_ON_ONCE(1); 700 WARN_ON_ONCE(1);
481 701
482 } else { 702 } else {
483 IWL_ERR(mvm, "Invalid tbl->lq_type %d\n", tbl->lq_type); 703 IWL_ERR(mvm, "Invalid rate->type %d\n", rate->type);
484 } 704 }
485 705
486 rate_n_flags |= tbl->bw; 706 ucode_rate |= rate->bw;
487 if (tbl->is_SGI) 707 if (rate->sgi)
488 rate_n_flags |= RATE_MCS_SGI_MSK; 708 ucode_rate |= RATE_MCS_SGI_MSK;
489 709
490 return rate_n_flags; 710 return ucode_rate;
491} 711}
492 712
493/* 713/* Convert a ucode rate into an rs_rate object */
494 * Interpret uCode API's rate_n_flags format, 714static int rs_rate_from_ucode_rate(const u32 ucode_rate,
495 * fill "search" or "active" tx mode table. 715 enum ieee80211_band band,
496 */ 716 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{ 717{
502 u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK); 718 u32 ant_msk = ucode_rate & RATE_MCS_ANT_ABC_MSK;
503 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags); 719 u8 num_of_ant = get_num_of_ant_from_rate(ucode_rate);
504 u8 nss; 720 u8 nss;
505 721
506 memset(tbl, 0, offsetof(struct iwl_scale_tbl_info, win)); 722 memset(rate, 0, sizeof(struct rs_rate));
507 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); 723 rate->index = iwl_hwrate_to_plcp_idx(ucode_rate);
508 724
509 if (*rate_idx == IWL_RATE_INVALID) { 725 if (rate->index == IWL_RATE_INVALID) {
510 *rate_idx = -1; 726 rate->index = -1;
511 return -EINVAL; 727 return -EINVAL;
512 } 728 }
513 tbl->is_SGI = 0; /* default legacy setup */ 729
514 tbl->bw = 0; 730 rate->ant = (ant_msk >> RATE_MCS_ANT_POS);
515 tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
516 tbl->lq_type = LQ_NONE;
517 tbl->max_search = IWL_MAX_SEARCH;
518 731
519 /* Legacy */ 732 /* Legacy */
520 if (!(rate_n_flags & RATE_MCS_HT_MSK) && 733 if (!(ucode_rate & RATE_MCS_HT_MSK) &&
521 !(rate_n_flags & RATE_MCS_VHT_MSK)) { 734 !(ucode_rate & RATE_MCS_VHT_MSK)) {
522 if (num_of_ant == 1) { 735 if (num_of_ant == 1) {
523 if (band == IEEE80211_BAND_5GHZ) 736 if (band == IEEE80211_BAND_5GHZ)
524 tbl->lq_type = LQ_LEGACY_A; 737 rate->type = LQ_LEGACY_A;
525 else 738 else
526 tbl->lq_type = LQ_LEGACY_G; 739 rate->type = LQ_LEGACY_G;
527 } 740 }
528 741
529 return 0; 742 return 0;
530 } 743 }
531 744
532 /* HT or VHT */ 745 /* HT or VHT */
533 if (rate_n_flags & RATE_MCS_SGI_MSK) 746 if (ucode_rate & RATE_MCS_SGI_MSK)
534 tbl->is_SGI = 1; 747 rate->sgi = true;
535 748
536 tbl->bw = rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK; 749 rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK;
537 750
538 if (rate_n_flags & RATE_MCS_HT_MSK) { 751 if (ucode_rate & RATE_MCS_HT_MSK) {
539 nss = ((rate_n_flags & RATE_HT_MCS_NSS_MSK) >> 752 nss = ((ucode_rate & RATE_HT_MCS_NSS_MSK) >>
540 RATE_HT_MCS_NSS_POS) + 1; 753 RATE_HT_MCS_NSS_POS) + 1;
541 754
542 if (nss == 1) { 755 if (nss == 1) {
543 tbl->lq_type = LQ_HT_SISO; 756 rate->type = LQ_HT_SISO;
544 WARN_ON_ONCE(num_of_ant != 1); 757 WARN_ON_ONCE(num_of_ant != 1);
545 } else if (nss == 2) { 758 } else if (nss == 2) {
546 tbl->lq_type = LQ_HT_MIMO2; 759 rate->type = LQ_HT_MIMO2;
547 WARN_ON_ONCE(num_of_ant != 2); 760 WARN_ON_ONCE(num_of_ant != 2);
548 } else { 761 } else {
549 WARN_ON_ONCE(1); 762 WARN_ON_ONCE(1);
550 } 763 }
551 } else if (rate_n_flags & RATE_MCS_VHT_MSK) { 764 } else if (ucode_rate & RATE_MCS_VHT_MSK) {
552 nss = ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> 765 nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >>
553 RATE_VHT_MCS_NSS_POS) + 1; 766 RATE_VHT_MCS_NSS_POS) + 1;
554 767
555 if (nss == 1) { 768 if (nss == 1) {
556 tbl->lq_type = LQ_VHT_SISO; 769 rate->type = LQ_VHT_SISO;
557 WARN_ON_ONCE(num_of_ant != 1); 770 WARN_ON_ONCE(num_of_ant != 1);
558 } else if (nss == 2) { 771 } else if (nss == 2) {
559 tbl->lq_type = LQ_VHT_MIMO2; 772 rate->type = LQ_VHT_MIMO2;
560 WARN_ON_ONCE(num_of_ant != 2); 773 WARN_ON_ONCE(num_of_ant != 2);
561 } else { 774 } else {
562 WARN_ON_ONCE(1); 775 WARN_ON_ONCE(1);
563 } 776 }
564 } 777 }
565 778
566 WARN_ON_ONCE(tbl->bw == RATE_MCS_CHAN_WIDTH_160); 779 WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_160);
567 WARN_ON_ONCE(tbl->bw == RATE_MCS_CHAN_WIDTH_80 && 780 WARN_ON_ONCE(rate->bw == RATE_MCS_CHAN_WIDTH_80 &&
568 !is_vht(tbl->lq_type)); 781 !is_vht(rate));
569 782
570 return 0; 783 return 0;
571} 784}
572 785
573/* switch to another antenna/antennas and return 1 */ 786/* switch to another antenna/antennas and return 1 */
574/* if no other valid antenna found, return 0 */ 787/* if no other valid antenna found, return 0 */
575static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, 788static int rs_toggle_antenna(u32 valid_ant, u32 *ucode_rate,
576 struct iwl_scale_tbl_info *tbl) 789 struct rs_rate *rate)
577{ 790{
578 u8 new_ant_type; 791 u8 new_ant_type;
579 792
580 if (!tbl->ant_type || tbl->ant_type > ANT_ABC) 793 if (!rate->ant || rate->ant > ANT_ABC)
581 return 0; 794 return 0;
582 795
583 if (!rs_is_valid_ant(valid_ant, tbl->ant_type)) 796 if (!rs_is_valid_ant(valid_ant, rate->ant))
584 return 0; 797 return 0;
585 798
586 new_ant_type = ant_toggle_lookup[tbl->ant_type]; 799 new_ant_type = ant_toggle_lookup[rate->ant];
587 800
588 while ((new_ant_type != tbl->ant_type) && 801 while ((new_ant_type != rate->ant) &&
589 !rs_is_valid_ant(valid_ant, new_ant_type)) 802 !rs_is_valid_ant(valid_ant, new_ant_type))
590 new_ant_type = ant_toggle_lookup[new_ant_type]; 803 new_ant_type = ant_toggle_lookup[new_ant_type];
591 804
592 if (new_ant_type == tbl->ant_type) 805 if (new_ant_type == rate->ant)
593 return 0; 806 return 0;
594 807
595 tbl->ant_type = new_ant_type; 808 rate->ant = new_ant_type;
596 *rate_n_flags &= ~RATE_MCS_ANT_ABC_MSK; 809
597 *rate_n_flags |= new_ant_type << RATE_MCS_ANT_POS; 810 /* TODO: get rid of ucode_rate here. This should handle only rs_rate */
811 *ucode_rate &= ~RATE_MCS_ANT_ABC_MSK;
812 *ucode_rate |= new_ant_type << RATE_MCS_ANT_POS;
598 return 1; 813 return 1;
599} 814}
600 815
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, 816static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
609 struct ieee80211_hdr *hdr, 817 struct rs_rate *rate)
610 enum iwl_table_type rate_type)
611{ 818{
612 if (is_legacy(rate_type)) 819 if (is_legacy(rate))
613 return lq_sta->active_legacy_rate; 820 return lq_sta->active_legacy_rate;
614 else if (is_siso(rate_type)) 821 else if (is_siso(rate))
615 return lq_sta->active_siso_rate; 822 return lq_sta->active_siso_rate;
616 else if (is_mimo2(rate_type)) 823 else if (is_mimo2(rate))
617 return lq_sta->active_mimo2_rate; 824 return lq_sta->active_mimo2_rate;
618 825
619 WARN_ON_ONCE(1); 826 WARN_ON_ONCE(1);
@@ -628,7 +835,7 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
628 835
629 /* 802.11A or ht walks to the next literal adjacent rate in 836 /* 802.11A or ht walks to the next literal adjacent rate in
630 * the rate table */ 837 * the rate table */
631 if (is_a_band(rate_type) || !is_legacy(rate_type)) { 838 if (is_type_a_band(rate_type) || !is_type_legacy(rate_type)) {
632 int i; 839 int i;
633 u32 mask; 840 u32 mask;
634 841
@@ -677,7 +884,7 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
677} 884}
678 885
679static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, 886static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
680 struct iwl_scale_tbl_info *tbl, 887 struct rs_rate *rate,
681 u8 scale_index, u8 ht_possible) 888 u8 scale_index, u8 ht_possible)
682{ 889{
683 s32 low; 890 s32 low;
@@ -689,30 +896,31 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
689 /* check if we need to switch from HT to legacy rates. 896 /* check if we need to switch from HT to legacy rates.
690 * assumption is that mandatory rates (1Mbps or 6Mbps) 897 * assumption is that mandatory rates (1Mbps or 6Mbps)
691 * are always supported (spec demand) */ 898 * are always supported (spec demand) */
692 if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) { 899 if (!is_legacy(rate) && (!ht_possible || !scale_index)) {
693 switch_to_legacy = 1; 900 switch_to_legacy = 1;
901 WARN_ON_ONCE(scale_index < IWL_RATE_MCS_0_INDEX &&
902 scale_index > IWL_RATE_MCS_9_INDEX);
694 scale_index = rs_ht_to_legacy[scale_index]; 903 scale_index = rs_ht_to_legacy[scale_index];
695 if (lq_sta->band == IEEE80211_BAND_5GHZ) 904 if (lq_sta->band == IEEE80211_BAND_5GHZ)
696 tbl->lq_type = LQ_LEGACY_A; 905 rate->type = LQ_LEGACY_A;
697 else 906 else
698 tbl->lq_type = LQ_LEGACY_G; 907 rate->type = LQ_LEGACY_G;
699 908
700 if (num_of_ant(tbl->ant_type) > 1) 909 if (num_of_ant(rate->ant) > 1)
701 tbl->ant_type = 910 rate->ant =
702 first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); 911 first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
703 912
704 tbl->bw = 0; 913 rate->bw = RATE_MCS_CHAN_WIDTH_20;
705 tbl->is_SGI = 0; 914 rate->sgi = false;
706 tbl->max_search = IWL_MAX_SEARCH;
707 } 915 }
708 916
709 rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type); 917 rate_mask = rs_get_supported_rates(lq_sta, rate);
710 918
711 /* Mask with station rate restriction */ 919 /* Mask with station rate restriction */
712 if (is_legacy(tbl->lq_type)) { 920 if (is_legacy(rate)) {
713 /* supp_rates has no CCK bits in A mode */ 921 /* supp_rates has no CCK bits in A mode */
714 if (lq_sta->band == IEEE80211_BAND_5GHZ) 922 if (lq_sta->band == IEEE80211_BAND_5GHZ)
715 rate_mask = (u16)(rate_mask & 923 rate_mask = (u16)(rate_mask &
716 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); 924 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
717 else 925 else
718 rate_mask = (u16)(rate_mask & lq_sta->supp_rates); 926 rate_mask = (u16)(rate_mask & lq_sta->supp_rates);
@@ -725,24 +933,22 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
725 } 933 }
726 934
727 high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask, 935 high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask,
728 tbl->lq_type); 936 rate->type);
729 low = high_low & 0xff; 937 low = high_low & 0xff;
730 938
731 if (low == IWL_RATE_INVALID) 939 if (low == IWL_RATE_INVALID)
732 low = scale_index; 940 low = scale_index;
733 941
734out: 942out:
735 return rate_n_flags_from_tbl(lq_sta->drv, tbl, low); 943 rate->index = low;
944 return ucode_rate_from_rs_rate(lq_sta->drv, rate);
736} 945}
737 946
738/* 947/* Simple function to compare two rate scale table types */
739 * Simple function to compare two rate scale table types 948static inline bool rs_rate_match(struct rs_rate *a,
740 */ 949 struct rs_rate *b)
741static bool table_type_matches(struct iwl_scale_tbl_info *a,
742 struct iwl_scale_tbl_info *b)
743{ 950{
744 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && 951 return (a->type == b->type) && (a->ant == b->ant) && (a->sgi == b->sgi);
745 (a->is_SGI == b->is_SGI);
746} 952}
747 953
748static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags) 954static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags)
@@ -766,7 +972,7 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
766{ 972{
767 int legacy_success; 973 int legacy_success;
768 int retries; 974 int retries;
769 int rs_index, mac_index, i; 975 int mac_index, i;
770 struct iwl_lq_sta *lq_sta = priv_sta; 976 struct iwl_lq_sta *lq_sta = priv_sta;
771 struct iwl_lq_cmd *table; 977 struct iwl_lq_cmd *table;
772 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 978 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
@@ -774,13 +980,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); 980 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
775 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 981 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
776 enum mac80211_rate_control_flags mac_flags; 982 enum mac80211_rate_control_flags mac_flags;
777 u32 tx_rate; 983 u32 ucode_rate;
778 struct iwl_scale_tbl_info tbl_type; 984 struct rs_rate rate;
779 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; 985 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
780 986
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. */ 987 /* Treat uninitialized rate scaling data same as non-existing. */
785 if (!lq_sta) { 988 if (!lq_sta) {
786 IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n"); 989 IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n");
@@ -808,10 +1011,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). 1011 * to a new "search" mode (which might become the new "active" mode).
809 */ 1012 */
810 table = &lq_sta->lq; 1013 table = &lq_sta->lq;
811 tx_rate = le32_to_cpu(table->rs_table[0]); 1014 ucode_rate = le32_to_cpu(table->rs_table[0]);
812 rs_get_tbl_info_from_mcs(tx_rate, info->band, &tbl_type, &rs_index); 1015 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
813 if (info->band == IEEE80211_BAND_5GHZ) 1016 if (info->band == IEEE80211_BAND_5GHZ)
814 rs_index -= IWL_FIRST_OFDM_RATE; 1017 rate.index -= IWL_FIRST_OFDM_RATE;
815 mac_flags = info->status.rates[0].flags; 1018 mac_flags = info->status.rates[0].flags;
816 mac_index = info->status.rates[0].idx; 1019 mac_index = info->status.rates[0].idx;
817 /* For HT packets, map MCS to PLCP */ 1020 /* For HT packets, map MCS to PLCP */
@@ -834,19 +1037,19 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
834 1037
835 /* Here we actually compare this rate to the latest LQ command */ 1038 /* Here we actually compare this rate to the latest LQ command */
836 if ((mac_index < 0) || 1039 if ((mac_index < 0) ||
837 (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) || 1040 (rate.sgi != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
838 (tbl_type.bw != rs_ch_width_from_mac_flags(mac_flags)) || 1041 (rate.bw != rs_ch_width_from_mac_flags(mac_flags)) ||
839 (tbl_type.ant_type != info->status.antenna) || 1042 (rate.ant != info->status.antenna) ||
840 (!!(tx_rate & RATE_MCS_HT_MSK) != 1043 (!!(ucode_rate & RATE_MCS_HT_MSK) !=
841 !!(mac_flags & IEEE80211_TX_RC_MCS)) || 1044 !!(mac_flags & IEEE80211_TX_RC_MCS)) ||
842 (!!(tx_rate & RATE_MCS_VHT_MSK) != 1045 (!!(ucode_rate & RATE_MCS_VHT_MSK) !=
843 !!(mac_flags & IEEE80211_TX_RC_VHT_MCS)) || 1046 !!(mac_flags & IEEE80211_TX_RC_VHT_MCS)) ||
844 (!!(tx_rate & RATE_HT_MCS_GF_MSK) != 1047 (!!(ucode_rate & RATE_HT_MCS_GF_MSK) !=
845 !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) || 1048 !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
846 (rs_index != mac_index)) { 1049 (rate.index != mac_index)) {
847 IWL_DEBUG_RATE(mvm, 1050 IWL_DEBUG_RATE(mvm,
848 "initial rate %d does not match %d (0x%x)\n", 1051 "initial rate %d does not match %d (0x%x)\n",
849 mac_index, rs_index, tx_rate); 1052 mac_index, rate.index, ucode_rate);
850 /* 1053 /*
851 * Since rates mis-match, the last LQ command may have failed. 1054 * Since rates mis-match, the last LQ command may have failed.
852 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with 1055 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
@@ -855,7 +1058,10 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
855 lq_sta->missed_rate_counter++; 1058 lq_sta->missed_rate_counter++;
856 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { 1059 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
857 lq_sta->missed_rate_counter = 0; 1060 lq_sta->missed_rate_counter = 0;
858 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false); 1061 IWL_DEBUG_RATE(mvm,
1062 "Too many rates mismatch. Send sync LQ. rs_state %d\n",
1063 lq_sta->rs_state);
1064 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
859 } 1065 }
860 /* Regardless, ignore this status info for outdated rate */ 1066 /* Regardless, ignore this status info for outdated rate */
861 return; 1067 return;
@@ -864,28 +1070,23 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
864 lq_sta->missed_rate_counter = 0; 1070 lq_sta->missed_rate_counter = 0;
865 1071
866 /* Figure out if rate scale algorithm is in active or search table */ 1072 /* Figure out if rate scale algorithm is in active or search table */
867 if (table_type_matches(&tbl_type, 1073 if (rs_rate_match(&rate,
868 &(lq_sta->lq_info[lq_sta->active_tbl]))) { 1074 &(lq_sta->lq_info[lq_sta->active_tbl].rate))) {
869 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1075 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
870 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); 1076 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
871 } else if (table_type_matches( 1077 } else if (rs_rate_match(&rate,
872 &tbl_type, &lq_sta->lq_info[1 - lq_sta->active_tbl])) { 1078 &lq_sta->lq_info[1 - lq_sta->active_tbl].rate)) {
873 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); 1079 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
874 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1080 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
875 } else { 1081 } else {
876 IWL_DEBUG_RATE(mvm, 1082 IWL_DEBUG_RATE(mvm,
877 "Neither active nor search matches tx rate\n"); 1083 "Neither active nor search matches tx rate\n");
878 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1084 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
879 IWL_DEBUG_RATE(mvm, "active- lq:%x, ant:%x, SGI:%d\n", 1085 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]); 1086 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
883 IWL_DEBUG_RATE(mvm, "search- lq:%x, ant:%x, SGI:%d\n", 1087 rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH");
884 tmp_tbl->lq_type, tmp_tbl->ant_type, 1088 rs_dump_rate(mvm, &rate, "ACTUAL");
885 tmp_tbl->is_SGI); 1089
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 /* 1090 /*
890 * no matching table found, let's by-pass the data collection 1091 * no matching table found, let's by-pass the data collection
891 * and continue to perform rate scale to find the rate table 1092 * and continue to perform rate scale to find the rate table
@@ -902,15 +1103,14 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
902 * first index into rate scale table. 1103 * first index into rate scale table.
903 */ 1104 */
904 if (info->flags & IEEE80211_TX_STAT_AMPDU) { 1105 if (info->flags & IEEE80211_TX_STAT_AMPDU) {
905 tx_rate = le32_to_cpu(table->rs_table[0]); 1106 ucode_rate = le32_to_cpu(table->rs_table[0]);
906 rs_get_tbl_info_from_mcs(tx_rate, info->band, &tbl_type, 1107 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
907 &rs_index); 1108 rs_collect_tx_data(curr_tbl, rate.index,
908 rs_collect_tx_data(curr_tbl, rs_index,
909 info->status.ampdu_len, 1109 info->status.ampdu_len,
910 info->status.ampdu_ack_len); 1110 info->status.ampdu_ack_len);
911 1111
912 /* Update success/fail counts if not searching for new mode */ 1112 /* Update success/fail counts if not searching for new mode */
913 if (lq_sta->stay_in_tbl) { 1113 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
914 lq_sta->total_success += info->status.ampdu_ack_len; 1114 lq_sta->total_success += info->status.ampdu_ack_len;
915 lq_sta->total_failed += (info->status.ampdu_len - 1115 lq_sta->total_failed += (info->status.ampdu_len -
916 info->status.ampdu_ack_len); 1116 info->status.ampdu_ack_len);
@@ -927,31 +1127,36 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
927 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK); 1127 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
928 /* Collect data for each rate used during failed TX attempts */ 1128 /* Collect data for each rate used during failed TX attempts */
929 for (i = 0; i <= retries; ++i) { 1129 for (i = 0; i <= retries; ++i) {
930 tx_rate = le32_to_cpu(table->rs_table[i]); 1130 ucode_rate = le32_to_cpu(table->rs_table[i]);
931 rs_get_tbl_info_from_mcs(tx_rate, info->band, 1131 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
932 &tbl_type, &rs_index);
933 /* 1132 /*
934 * Only collect stats if retried rate is in the same RS 1133 * Only collect stats if retried rate is in the same RS
935 * table as active/search. 1134 * table as active/search.
936 */ 1135 */
937 if (table_type_matches(&tbl_type, curr_tbl)) 1136 if (rs_rate_match(&rate, &curr_tbl->rate))
938 tmp_tbl = curr_tbl; 1137 tmp_tbl = curr_tbl;
939 else if (table_type_matches(&tbl_type, other_tbl)) 1138 else if (rs_rate_match(&rate, &other_tbl->rate))
940 tmp_tbl = other_tbl; 1139 tmp_tbl = other_tbl;
941 else 1140 else {
1141 IWL_DEBUG_RATE(mvm,
1142 "Tx packet rate doesn't match ACTIVE or SEARCH tables\n");
1143 rs_dump_rate(mvm, &rate, "Tx PACKET:");
1144 rs_dump_rate(mvm, &curr_tbl->rate, "CURRENT:");
1145 rs_dump_rate(mvm, &other_tbl->rate, "OTHER:");
942 continue; 1146 continue;
943 rs_collect_tx_data(tmp_tbl, rs_index, 1, 1147 }
1148 rs_collect_tx_data(tmp_tbl, rate.index, 1,
944 i < retries ? 0 : legacy_success); 1149 i < retries ? 0 : legacy_success);
945 } 1150 }
946 1151
947 /* Update success/fail counts if not searching for new mode */ 1152 /* Update success/fail counts if not searching for new mode */
948 if (lq_sta->stay_in_tbl) { 1153 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
949 lq_sta->total_success += legacy_success; 1154 lq_sta->total_success += legacy_success;
950 lq_sta->total_failed += retries + (1 - legacy_success); 1155 lq_sta->total_failed += retries + (1 - legacy_success);
951 } 1156 }
952 } 1157 }
953 /* The last TX rate is cached in lq_sta; it's set in if/else above */ 1158 /* 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; 1159 lq_sta->last_rate_n_flags = ucode_rate;
955done: 1160done:
956 /* See if there's a better rate or modulation mode to try. */ 1161 /* See if there's a better rate or modulation mode to try. */
957 if (sta && sta->supp_rates[sband->band]) 1162 if (sta && sta->supp_rates[sband->band])
@@ -969,8 +1174,8 @@ done:
969static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy, 1174static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
970 struct iwl_lq_sta *lq_sta) 1175 struct iwl_lq_sta *lq_sta)
971{ 1176{
972 IWL_DEBUG_RATE(mvm, "we are staying in the same table\n"); 1177 IWL_DEBUG_RATE(mvm, "Moving to RS_STATE_STAY_IN_COLUMN\n");
973 lq_sta->stay_in_tbl = 1; /* only place this gets set */ 1178 lq_sta->rs_state = RS_STATE_STAY_IN_COLUMN;
974 if (is_legacy) { 1179 if (is_legacy) {
975 lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT; 1180 lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT;
976 lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT; 1181 lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT;
@@ -984,37 +1189,31 @@ static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
984 lq_sta->total_failed = 0; 1189 lq_sta->total_failed = 0;
985 lq_sta->total_success = 0; 1190 lq_sta->total_success = 0;
986 lq_sta->flush_timer = jiffies; 1191 lq_sta->flush_timer = jiffies;
987 lq_sta->action_counter = 0; 1192 lq_sta->visited_columns = 0;
988} 1193}
989 1194
990/* 1195static s32 *rs_get_expected_tpt_table(struct iwl_lq_sta *lq_sta,
991 * Find correct throughput table for given mode of modulation 1196 const struct rs_tx_column *column,
992 */ 1197 u32 bw)
993static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
994 struct iwl_scale_tbl_info *tbl)
995{ 1198{
996 /* Used to choose among HT tables */ 1199 /* Used to choose among HT tables */
997 s32 (*ht_tbl_pointer)[IWL_RATE_COUNT]; 1200 s32 (*ht_tbl_pointer)[IWL_RATE_COUNT];
998 1201
999 /* Check for invalid LQ type */ 1202 if (WARN_ON_ONCE(column->mode != RS_LEGACY &&
1000 if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_ht(tbl->lq_type) && 1203 column->mode != RS_SISO &&
1001 !(is_vht(tbl->lq_type)))) { 1204 column->mode != RS_MIMO2))
1002 tbl->expected_tpt = expected_tpt_legacy; 1205 return expected_tpt_legacy;
1003 return;
1004 }
1005 1206
1006 /* Legacy rates have only one table */ 1207 /* Legacy rates have only one table */
1007 if (is_legacy(tbl->lq_type)) { 1208 if (column->mode == RS_LEGACY)
1008 tbl->expected_tpt = expected_tpt_legacy; 1209 return expected_tpt_legacy;
1009 return;
1010 }
1011 1210
1012 ht_tbl_pointer = expected_tpt_mimo2_20MHz; 1211 ht_tbl_pointer = expected_tpt_mimo2_20MHz;
1013 /* Choose among many HT tables depending on number of streams 1212 /* Choose among many HT tables depending on number of streams
1014 * (SISO/MIMO2), channel width (20/40/80), SGI, and aggregation 1213 * (SISO/MIMO2), channel width (20/40/80), SGI, and aggregation
1015 * status */ 1214 * status */
1016 if (is_siso(tbl->lq_type)) { 1215 if (column->mode == RS_SISO) {
1017 switch (tbl->bw) { 1216 switch (bw) {
1018 case RATE_MCS_CHAN_WIDTH_20: 1217 case RATE_MCS_CHAN_WIDTH_20:
1019 ht_tbl_pointer = expected_tpt_siso_20MHz; 1218 ht_tbl_pointer = expected_tpt_siso_20MHz;
1020 break; 1219 break;
@@ -1027,8 +1226,8 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1027 default: 1226 default:
1028 WARN_ON_ONCE(1); 1227 WARN_ON_ONCE(1);
1029 } 1228 }
1030 } else if (is_mimo2(tbl->lq_type)) { 1229 } else if (column->mode == RS_MIMO2) {
1031 switch (tbl->bw) { 1230 switch (bw) {
1032 case RATE_MCS_CHAN_WIDTH_20: 1231 case RATE_MCS_CHAN_WIDTH_20:
1033 ht_tbl_pointer = expected_tpt_mimo2_20MHz; 1232 ht_tbl_pointer = expected_tpt_mimo2_20MHz;
1034 break; 1233 break;
@@ -1045,14 +1244,23 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1045 WARN_ON_ONCE(1); 1244 WARN_ON_ONCE(1);
1046 } 1245 }
1047 1246
1048 if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */ 1247 if (!column->sgi && !lq_sta->is_agg) /* Normal */
1049 tbl->expected_tpt = ht_tbl_pointer[0]; 1248 return ht_tbl_pointer[0];
1050 else if (tbl->is_SGI && !lq_sta->is_agg) /* SGI */ 1249 else if (column->sgi && !lq_sta->is_agg) /* SGI */
1051 tbl->expected_tpt = ht_tbl_pointer[1]; 1250 return ht_tbl_pointer[1];
1052 else if (!tbl->is_SGI && lq_sta->is_agg) /* AGG */ 1251 else if (!column->sgi && lq_sta->is_agg) /* AGG */
1053 tbl->expected_tpt = ht_tbl_pointer[2]; 1252 return ht_tbl_pointer[2];
1054 else /* AGG+SGI */ 1253 else /* AGG+SGI */
1055 tbl->expected_tpt = ht_tbl_pointer[3]; 1254 return ht_tbl_pointer[3];
1255}
1256
1257static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1258 struct iwl_scale_tbl_info *tbl)
1259{
1260 struct rs_rate *rate = &tbl->rate;
1261 const struct rs_tx_column *column = &rs_tx_columns[tbl->column];
1262
1263 tbl->expected_tpt = rs_get_expected_tpt_table(lq_sta, column, rate->bw);
1056} 1264}
1057 1265
1058/* 1266/*
@@ -1089,7 +1297,7 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1089 1297
1090 while (1) { 1298 while (1) {
1091 high_low = rs_get_adjacent_rate(mvm, rate, rate_mask, 1299 high_low = rs_get_adjacent_rate(mvm, rate, rate_mask,
1092 tbl->lq_type); 1300 tbl->rate.type);
1093 1301
1094 low = high_low & 0xff; 1302 low = high_low & 0xff;
1095 high = (high_low >> 8) & 0xff; 1303 high = (high_low >> 8) & 0xff;
@@ -1110,7 +1318,7 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1110 * "active" throughput (under perfect conditions). 1318 * "active" throughput (under perfect conditions).
1111 */ 1319 */
1112 if ((((100 * tpt_tbl[rate]) > lq_sta->last_tpt) && 1320 if ((((100 * tpt_tbl[rate]) > lq_sta->last_tpt) &&
1113 ((active_sr > IWL_RATE_DECREASE_TH) && 1321 ((active_sr > RS_SR_FORCE_DECREASE) &&
1114 (active_sr <= IWL_RATE_HIGH_TH) && 1322 (active_sr <= IWL_RATE_HIGH_TH) &&
1115 (tpt_tbl[rate] <= active_tpt))) || 1323 (tpt_tbl[rate] <= active_tpt))) ||
1116 ((active_sr >= IWL_RATE_SCALE_SWITCH) && 1324 ((active_sr >= IWL_RATE_SCALE_SWITCH) &&
@@ -1157,417 +1365,14 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1157 return new_rate; 1365 return new_rate;
1158} 1366}
1159 1367
1160/* Move to the next action and wrap around to the first action in case 1368static 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{ 1369{
1176 if (sta->bandwidth >= IEEE80211_STA_RX_BW_80) 1370 if (sta->bandwidth >= IEEE80211_STA_RX_BW_80)
1177 tbl->bw = RATE_MCS_CHAN_WIDTH_80; 1371 return RATE_MCS_CHAN_WIDTH_80;
1178 else if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) 1372 else if (sta->bandwidth >= IEEE80211_STA_RX_BW_40)
1179 tbl->bw = RATE_MCS_CHAN_WIDTH_40; 1373 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 1374
1570 return 0; 1375 return RATE_MCS_CHAN_WIDTH_20;
1571} 1376}
1572 1377
1573/* 1378/*
@@ -1591,13 +1396,13 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1591 tbl = &(lq_sta->lq_info[active_tbl]); 1396 tbl = &(lq_sta->lq_info[active_tbl]);
1592 1397
1593 /* If we've been disallowing search, see if we should now allow it */ 1398 /* If we've been disallowing search, see if we should now allow it */
1594 if (lq_sta->stay_in_tbl) { 1399 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
1595 /* Elapsed time using current modulation mode */ 1400 /* Elapsed time using current modulation mode */
1596 if (lq_sta->flush_timer) 1401 if (lq_sta->flush_timer)
1597 flush_interval_passed = 1402 flush_interval_passed =
1598 time_after(jiffies, 1403 time_after(jiffies,
1599 (unsigned long)(lq_sta->flush_timer + 1404 (unsigned long)(lq_sta->flush_timer +
1600 IWL_RATE_SCALE_FLUSH_INTVL)); 1405 RS_STAY_IN_COLUMN_TIMEOUT));
1601 1406
1602 /* 1407 /*
1603 * Check if we should allow search for new modulation mode. 1408 * Check if we should allow search for new modulation mode.
@@ -1619,10 +1424,14 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1619 flush_interval_passed); 1424 flush_interval_passed);
1620 1425
1621 /* Allow search for new mode */ 1426 /* Allow search for new mode */
1622 lq_sta->stay_in_tbl = 0; /* only place reset */ 1427 lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_STARTED;
1428 IWL_DEBUG_RATE(mvm,
1429 "Moving to RS_STATE_SEARCH_CYCLE_STARTED\n");
1623 lq_sta->total_failed = 0; 1430 lq_sta->total_failed = 0;
1624 lq_sta->total_success = 0; 1431 lq_sta->total_success = 0;
1625 lq_sta->flush_timer = 0; 1432 lq_sta->flush_timer = 0;
1433 /* mark the current column as visited */
1434 lq_sta->visited_columns = BIT(tbl->column);
1626 /* 1435 /*
1627 * Else if we've used this modulation mode enough repetitions 1436 * Else if we've used this modulation mode enough repetitions
1628 * (regardless of elapsed time or success/failure), reset 1437 * (regardless of elapsed time or success/failure), reset
@@ -1646,7 +1455,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 1455 /* If transitioning to allow "search", reset all history
1647 * bitmaps and stats in active table (this will become the new 1456 * bitmaps and stats in active table (this will become the new
1648 * "search" table). */ 1457 * "search" table). */
1649 if (!lq_sta->stay_in_tbl) { 1458 if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) {
1459 IWL_DEBUG_RATE(mvm, "Clearing up window stats\n");
1650 for (i = 0; i < IWL_RATE_COUNT; i++) 1460 for (i = 0; i < IWL_RATE_COUNT; i++)
1651 rs_rate_scale_clear_window(&(tbl->win[i])); 1461 rs_rate_scale_clear_window(&(tbl->win[i]));
1652 } 1462 }
@@ -1659,15 +1469,13 @@ 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, 1469static void rs_update_rate_tbl(struct iwl_mvm *mvm,
1660 struct ieee80211_sta *sta, 1470 struct ieee80211_sta *sta,
1661 struct iwl_lq_sta *lq_sta, 1471 struct iwl_lq_sta *lq_sta,
1662 struct iwl_scale_tbl_info *tbl, 1472 struct rs_rate *rate)
1663 int index)
1664{ 1473{
1665 u32 rate; 1474 u32 ucode_rate;
1666 1475
1667 /* Update uCode's rate table. */ 1476 ucode_rate = ucode_rate_from_rs_rate(mvm, rate);
1668 rate = rate_n_flags_from_tbl(mvm, tbl, index); 1477 rs_fill_link_cmd(mvm, sta, lq_sta, ucode_rate);
1669 rs_fill_link_cmd(mvm, sta, lq_sta, rate); 1478 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
1670 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false);
1671} 1479}
1672 1480
1673static u8 rs_get_tid(struct iwl_lq_sta *lq_data, 1481static u8 rs_get_tid(struct iwl_lq_sta *lq_data,
@@ -1686,6 +1494,162 @@ static u8 rs_get_tid(struct iwl_lq_sta *lq_data,
1686 return tid; 1494 return tid;
1687} 1495}
1688 1496
1497static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
1498 struct iwl_lq_sta *lq_sta,
1499 struct ieee80211_sta *sta,
1500 struct iwl_scale_tbl_info *tbl)
1501{
1502 int i, j, n;
1503 enum rs_column next_col_id;
1504 const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column];
1505 const struct rs_tx_column *next_col;
1506 allow_column_func_t allow_func;
1507 u8 valid_ants = iwl_fw_valid_tx_ant(mvm->fw);
1508 s32 *expected_tpt_tbl;
1509 s32 tpt, max_expected_tpt;
1510
1511 for (i = 0; i < MAX_NEXT_COLUMNS; i++) {
1512 next_col_id = curr_col->next_columns[i];
1513
1514 if (next_col_id == RS_COLUMN_INVALID)
1515 continue;
1516
1517 if (lq_sta->visited_columns & BIT(next_col_id)) {
1518 IWL_DEBUG_RATE(mvm, "Skip already visited column %d\n",
1519 next_col_id);
1520 continue;
1521 }
1522
1523 next_col = &rs_tx_columns[next_col_id];
1524
1525 if (!rs_is_valid_ant(valid_ants, next_col->ant)) {
1526 IWL_DEBUG_RATE(mvm,
1527 "Skip column %d as ANT config isn't supported by chip. valid_ants 0x%x column ant 0x%x\n",
1528 next_col_id, valid_ants, next_col->ant);
1529 continue;
1530 }
1531
1532 for (j = 0; j < MAX_COLUMN_CHECKS; j++) {
1533 allow_func = next_col->checks[j];
1534 if (allow_func && !allow_func(mvm, sta, tbl))
1535 break;
1536 }
1537
1538 if (j != MAX_COLUMN_CHECKS) {
1539 IWL_DEBUG_RATE(mvm,
1540 "Skip column %d: not allowed (check %d failed)\n",
1541 next_col_id, j);
1542
1543 continue;
1544 }
1545
1546 tpt = lq_sta->last_tpt / 100;
1547 expected_tpt_tbl = rs_get_expected_tpt_table(lq_sta, next_col,
1548 tbl->rate.bw);
1549 if (WARN_ON_ONCE(!expected_tpt_tbl))
1550 continue;
1551
1552 max_expected_tpt = 0;
1553 for (n = 0; n < IWL_RATE_COUNT; n++)
1554 if (expected_tpt_tbl[n] > max_expected_tpt)
1555 max_expected_tpt = expected_tpt_tbl[n];
1556
1557 if (tpt >= max_expected_tpt) {
1558 IWL_DEBUG_RATE(mvm,
1559 "Skip column %d: can't beat current TPT. Max expected %d current %d\n",
1560 next_col_id, max_expected_tpt, tpt);
1561 continue;
1562 }
1563
1564 break;
1565 }
1566
1567 if (i == MAX_NEXT_COLUMNS)
1568 return RS_COLUMN_INVALID;
1569
1570 IWL_DEBUG_RATE(mvm, "Found potential column %d\n", next_col_id);
1571
1572 return next_col_id;
1573}
1574
1575static int rs_switch_to_column(struct iwl_mvm *mvm,
1576 struct iwl_lq_sta *lq_sta,
1577 struct ieee80211_sta *sta,
1578 enum rs_column col_id)
1579{
1580 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1581 struct iwl_scale_tbl_info *search_tbl =
1582 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1583 struct rs_rate *rate = &search_tbl->rate;
1584 const struct rs_tx_column *column = &rs_tx_columns[col_id];
1585 const struct rs_tx_column *curr_column = &rs_tx_columns[tbl->column];
1586 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1587 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1588 u16 rate_mask = 0;
1589 u32 rate_idx = 0;
1590
1591 memcpy(search_tbl, tbl, sz);
1592
1593 rate->sgi = column->sgi;
1594 rate->ant = column->ant;
1595
1596 if (column->mode == RS_LEGACY) {
1597 if (lq_sta->band == IEEE80211_BAND_5GHZ)
1598 rate->type = LQ_LEGACY_A;
1599 else
1600 rate->type = LQ_LEGACY_G;
1601
1602 rate_mask = lq_sta->active_legacy_rate;
1603 } else if (column->mode == RS_SISO) {
1604 rate->type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO;
1605 rate_mask = lq_sta->active_siso_rate;
1606 } else if (column->mode == RS_MIMO2) {
1607 rate->type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2;
1608 rate_mask = lq_sta->active_mimo2_rate;
1609 } else {
1610 WARN_ON_ONCE("Bad column mode");
1611 }
1612
1613 rate->bw = rs_bw_from_sta_bw(sta);
1614 search_tbl->column = col_id;
1615 rs_set_expected_tpt_table(lq_sta, search_tbl);
1616
1617 /* Get the best matching rate if we're changing modes. e.g.
1618 * SISO->MIMO, LEGACY->SISO, MIMO->SISO
1619 */
1620 if (curr_column->mode != column->mode) {
1621 rate_idx = rs_get_best_rate(mvm, lq_sta, search_tbl,
1622 rate_mask, rate->index);
1623
1624 if ((rate_idx == IWL_RATE_INVALID) ||
1625 !(BIT(rate_idx) & rate_mask)) {
1626 IWL_DEBUG_RATE(mvm,
1627 "can not switch with index %d"
1628 " rate mask %x\n",
1629 rate_idx, rate_mask);
1630
1631 goto err;
1632 }
1633
1634 rate->index = rate_idx;
1635 }
1636
1637 /* TODO: remove current_rate and keep using rs_rate all the way until
1638 * we need to fill in the rs_table in the LQ command
1639 */
1640 search_tbl->current_rate = ucode_rate_from_rs_rate(mvm, rate);
1641 IWL_DEBUG_RATE(mvm, "Switched to column %d: Index %d\n",
1642 col_id, rate->index);
1643
1644 lq_sta->visited_columns |= BIT(col_id);
1645 return 0;
1646
1647err:
1648 rate->type = LQ_NONE;
1649 return -1;
1650}
1651
1652
1689/* 1653/*
1690 * Do rate scaling and search for new modulation mode. 1654 * Do rate scaling and search for new modulation mode.
1691 */ 1655 */
@@ -1715,10 +1679,10 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1715 u16 high_low; 1679 u16 high_low;
1716 s32 sr; 1680 s32 sr;
1717 u8 tid = IWL_MAX_TID_COUNT; 1681 u8 tid = IWL_MAX_TID_COUNT;
1682 u8 prev_agg = lq_sta->is_agg;
1718 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv; 1683 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv;
1719 struct iwl_mvm_tid_data *tid_data; 1684 struct iwl_mvm_tid_data *tid_data;
1720 1685 struct rs_rate *rate;
1721 IWL_DEBUG_RATE(mvm, "rate scale calculate new rate for skb\n");
1722 1686
1723 /* Send management frames and NO_ACK data using lowest rate. */ 1687 /* Send management frames and NO_ACK data using lowest rate. */
1724 /* TODO: this could probably be improved.. */ 1688 /* TODO: this could probably be improved.. */
@@ -1751,20 +1715,23 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1751 active_tbl = 1 - lq_sta->active_tbl; 1715 active_tbl = 1 - lq_sta->active_tbl;
1752 1716
1753 tbl = &(lq_sta->lq_info[active_tbl]); 1717 tbl = &(lq_sta->lq_info[active_tbl]);
1718 rate = &tbl->rate;
1719
1720 if (prev_agg != lq_sta->is_agg) {
1721 IWL_DEBUG_RATE(mvm,
1722 "Aggregation changed: prev %d current %d. Update expected TPT table\n",
1723 prev_agg, lq_sta->is_agg);
1724 rs_set_expected_tpt_table(lq_sta, tbl);
1725 }
1754 1726
1755 /* current tx rate */ 1727 /* current tx rate */
1756 index = lq_sta->last_txrate_idx; 1728 index = lq_sta->last_txrate_idx;
1757 1729
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 */ 1730 /* rates available for this association, and for modulation mode */
1762 rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type); 1731 rate_mask = rs_get_supported_rates(lq_sta, rate);
1763
1764 IWL_DEBUG_RATE(mvm, "mask 0x%04X\n", rate_mask);
1765 1732
1766 /* mask with station rate restriction */ 1733 /* mask with station rate restriction */
1767 if (is_legacy(tbl->lq_type)) { 1734 if (is_legacy(rate)) {
1768 if (lq_sta->band == IEEE80211_BAND_5GHZ) 1735 if (lq_sta->band == IEEE80211_BAND_5GHZ)
1769 /* supp_rates has no CCK bits in A mode */ 1736 /* supp_rates has no CCK bits in A mode */
1770 rate_scale_index_msk = (u16) (rate_mask & 1737 rate_scale_index_msk = (u16) (rate_mask &
@@ -1780,16 +1747,17 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1780 if (!rate_scale_index_msk) 1747 if (!rate_scale_index_msk)
1781 rate_scale_index_msk = rate_mask; 1748 rate_scale_index_msk = rate_mask;
1782 1749
1783 if (!((1 << index) & rate_scale_index_msk)) { 1750 if (!((BIT(index) & rate_scale_index_msk))) {
1784 IWL_ERR(mvm, "Current Rate is not valid\n"); 1751 IWL_ERR(mvm, "Current Rate is not valid\n");
1785 if (lq_sta->search_better_tbl) { 1752 if (lq_sta->search_better_tbl) {
1786 /* revert to active table if search table is not valid*/ 1753 /* revert to active table if search table is not valid*/
1787 tbl->lq_type = LQ_NONE; 1754 rate->type = LQ_NONE;
1788 lq_sta->search_better_tbl = 0; 1755 lq_sta->search_better_tbl = 0;
1789 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1756 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1790 /* get "active" rate info */ 1757 /* get "active" rate info */
1791 index = iwl_hwrate_to_plcp_idx(tbl->current_rate); 1758 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
1792 rs_update_rate_tbl(mvm, sta, lq_sta, tbl, index); 1759 tbl->rate.index = index;
1760 rs_update_rate_tbl(mvm, sta, lq_sta, &tbl->rate);
1793 } 1761 }
1794 return; 1762 return;
1795 } 1763 }
@@ -1806,6 +1774,9 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1806 index = lq_sta->max_rate_idx; 1774 index = lq_sta->max_rate_idx;
1807 update_lq = 1; 1775 update_lq = 1;
1808 window = &(tbl->win[index]); 1776 window = &(tbl->win[index]);
1777 IWL_DEBUG_RATE(mvm,
1778 "Forcing user max rate %d\n",
1779 index);
1809 goto lq_update; 1780 goto lq_update;
1810 } 1781 }
1811 1782
@@ -1822,8 +1793,9 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1822 if ((fail_count < IWL_RATE_MIN_FAILURE_TH) && 1793 if ((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
1823 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) { 1794 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) {
1824 IWL_DEBUG_RATE(mvm, 1795 IWL_DEBUG_RATE(mvm,
1825 "LQ: still below TH. succ=%d total=%d for index %d\n", 1796 "(%s: %d): Test Window: succ %d total %d\n",
1826 window->success_counter, window->counter, index); 1797 rs_pretty_lq_type(rate->type),
1798 index, window->success_counter, window->counter);
1827 1799
1828 /* Can't calculate this yet; not enough history */ 1800 /* Can't calculate this yet; not enough history */
1829 window->average_tpt = IWL_INVALID_VALUE; 1801 window->average_tpt = IWL_INVALID_VALUE;
@@ -1838,8 +1810,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1838 * actual average throughput */ 1810 * actual average throughput */
1839 if (window->average_tpt != ((window->success_ratio * 1811 if (window->average_tpt != ((window->success_ratio *
1840 tbl->expected_tpt[index] + 64) / 128)) { 1812 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 * 1813 window->average_tpt = ((window->success_ratio *
1844 tbl->expected_tpt[index] + 64) / 128); 1814 tbl->expected_tpt[index] + 64) / 128);
1845 } 1815 }
@@ -1851,27 +1821,26 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1851 * continuing to use the setup that we've been trying. */ 1821 * continuing to use the setup that we've been trying. */
1852 if (window->average_tpt > lq_sta->last_tpt) { 1822 if (window->average_tpt > lq_sta->last_tpt) {
1853 IWL_DEBUG_RATE(mvm, 1823 IWL_DEBUG_RATE(mvm,
1854 "LQ: SWITCHING TO NEW TABLE suc=%d cur-tpt=%d old-tpt=%d\n", 1824 "SWITCHING TO NEW TABLE SR: %d "
1825 "cur-tpt %d old-tpt %d\n",
1855 window->success_ratio, 1826 window->success_ratio,
1856 window->average_tpt, 1827 window->average_tpt,
1857 lq_sta->last_tpt); 1828 lq_sta->last_tpt);
1858 1829
1859 if (!is_legacy(tbl->lq_type))
1860 lq_sta->enable_counter = 1;
1861
1862 /* Swap tables; "search" becomes "active" */ 1830 /* Swap tables; "search" becomes "active" */
1863 lq_sta->active_tbl = active_tbl; 1831 lq_sta->active_tbl = active_tbl;
1864 current_tpt = window->average_tpt; 1832 current_tpt = window->average_tpt;
1865 /* Else poor success; go back to mode in "active" table */ 1833 /* Else poor success; go back to mode in "active" table */
1866 } else { 1834 } else {
1867 IWL_DEBUG_RATE(mvm, 1835 IWL_DEBUG_RATE(mvm,
1868 "LQ: GOING BACK TO THE OLD TABLE suc=%d cur-tpt=%d old-tpt=%d\n", 1836 "GOING BACK TO THE OLD TABLE: SR %d "
1837 "cur-tpt %d old-tpt %d\n",
1869 window->success_ratio, 1838 window->success_ratio,
1870 window->average_tpt, 1839 window->average_tpt,
1871 lq_sta->last_tpt); 1840 lq_sta->last_tpt);
1872 1841
1873 /* Nullify "search" table */ 1842 /* Nullify "search" table */
1874 tbl->lq_type = LQ_NONE; 1843 rate->type = LQ_NONE;
1875 1844
1876 /* Revert to "active" table */ 1845 /* Revert to "active" table */
1877 active_tbl = lq_sta->active_tbl; 1846 active_tbl = lq_sta->active_tbl;
@@ -1895,7 +1864,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1895 /* (Else) not in search of better modulation mode, try for better 1864 /* (Else) not in search of better modulation mode, try for better
1896 * starting rate, while staying in this mode. */ 1865 * starting rate, while staying in this mode. */
1897 high_low = rs_get_adjacent_rate(mvm, index, rate_scale_index_msk, 1866 high_low = rs_get_adjacent_rate(mvm, index, rate_scale_index_msk,
1898 tbl->lq_type); 1867 rate->type);
1899 low = high_low & 0xff; 1868 low = high_low & 0xff;
1900 high = (high_low >> 8) & 0xff; 1869 high = (high_low >> 8) & 0xff;
1901 1870
@@ -1913,20 +1882,31 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1913 if (high != IWL_RATE_INVALID) 1882 if (high != IWL_RATE_INVALID)
1914 high_tpt = tbl->win[high].average_tpt; 1883 high_tpt = tbl->win[high].average_tpt;
1915 1884
1885 IWL_DEBUG_RATE(mvm,
1886 "(%s: %d): cur_tpt %d SR %d low %d high %d low_tpt %d high_tpt %d\n",
1887 rs_pretty_lq_type(rate->type), index, current_tpt, sr,
1888 low, high, low_tpt, high_tpt);
1889
1916 scale_action = 0; 1890 scale_action = 0;
1917 1891
1918 /* Too many failures, decrease rate */ 1892 /* Too many failures, decrease rate */
1919 if ((sr <= IWL_RATE_DECREASE_TH) || (current_tpt == 0)) { 1893 if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) {
1920 IWL_DEBUG_RATE(mvm, 1894 IWL_DEBUG_RATE(mvm,
1921 "decrease rate because of low success_ratio\n"); 1895 "decrease rate because of low SR\n");
1922 scale_action = -1; 1896 scale_action = -1;
1923 /* No throughput measured yet for adjacent rates; try increase. */ 1897 /* No throughput measured yet for adjacent rates; try increase. */
1924 } else if ((low_tpt == IWL_INVALID_VALUE) && 1898 } else if ((low_tpt == IWL_INVALID_VALUE) &&
1925 (high_tpt == IWL_INVALID_VALUE)) { 1899 (high_tpt == IWL_INVALID_VALUE)) {
1926 if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) 1900 if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) {
1901 IWL_DEBUG_RATE(mvm,
1902 "Good SR and no high rate measurement. "
1903 "Increase rate\n");
1927 scale_action = 1; 1904 scale_action = 1;
1928 else if (low != IWL_RATE_INVALID) 1905 } else if (low != IWL_RATE_INVALID) {
1906 IWL_DEBUG_RATE(mvm,
1907 "Remain in current rate\n");
1929 scale_action = 0; 1908 scale_action = 0;
1909 }
1930 } 1910 }
1931 1911
1932 /* Both adjacent throughputs are measured, but neither one has better 1912 /* Both adjacent throughputs are measured, but neither one has better
@@ -1934,8 +1914,12 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1934 else if ((low_tpt != IWL_INVALID_VALUE) && 1914 else if ((low_tpt != IWL_INVALID_VALUE) &&
1935 (high_tpt != IWL_INVALID_VALUE) && 1915 (high_tpt != IWL_INVALID_VALUE) &&
1936 (low_tpt < current_tpt) && 1916 (low_tpt < current_tpt) &&
1937 (high_tpt < current_tpt)) 1917 (high_tpt < current_tpt)) {
1918 IWL_DEBUG_RATE(mvm,
1919 "Both high and low are worse. "
1920 "Maintain rate\n");
1938 scale_action = 0; 1921 scale_action = 0;
1922 }
1939 1923
1940 /* At least one adjacent rate's throughput is measured, 1924 /* At least one adjacent rate's throughput is measured,
1941 * and may have better performance. */ 1925 * and may have better performance. */
@@ -1945,8 +1929,14 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1945 /* Higher rate has better throughput */ 1929 /* Higher rate has better throughput */
1946 if (high_tpt > current_tpt && 1930 if (high_tpt > current_tpt &&
1947 sr >= IWL_RATE_INCREASE_TH) { 1931 sr >= IWL_RATE_INCREASE_TH) {
1932 IWL_DEBUG_RATE(mvm,
1933 "Higher rate is better and good "
1934 "SR. Increate rate\n");
1948 scale_action = 1; 1935 scale_action = 1;
1949 } else { 1936 } else {
1937 IWL_DEBUG_RATE(mvm,
1938 "Higher rate isn't better OR "
1939 "no good SR. Maintain rate\n");
1950 scale_action = 0; 1940 scale_action = 0;
1951 } 1941 }
1952 1942
@@ -1955,9 +1945,13 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1955 /* Lower rate has better throughput */ 1945 /* Lower rate has better throughput */
1956 if (low_tpt > current_tpt) { 1946 if (low_tpt > current_tpt) {
1957 IWL_DEBUG_RATE(mvm, 1947 IWL_DEBUG_RATE(mvm,
1958 "decrease rate because of low tpt\n"); 1948 "Lower rate is better. "
1949 "Decrease rate\n");
1959 scale_action = -1; 1950 scale_action = -1;
1960 } else if (sr >= IWL_RATE_INCREASE_TH) { 1951 } else if (sr >= IWL_RATE_INCREASE_TH) {
1952 IWL_DEBUG_RATE(mvm,
1953 "Lower rate isn't better and "
1954 "good SR. Increase rate\n");
1961 scale_action = 1; 1955 scale_action = 1;
1962 } 1956 }
1963 } 1957 }
@@ -1967,29 +1961,17 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1967 * has been good at old rate. Don't change it. */ 1961 * has been good at old rate. Don't change it. */
1968 if ((scale_action == -1) && (low != IWL_RATE_INVALID) && 1962 if ((scale_action == -1) && (low != IWL_RATE_INVALID) &&
1969 ((sr > IWL_RATE_HIGH_TH) || 1963 ((sr > IWL_RATE_HIGH_TH) ||
1970 (current_tpt > (100 * tbl->expected_tpt[low])))) 1964 (current_tpt > (100 * tbl->expected_tpt[low])))) {
1965 IWL_DEBUG_RATE(mvm,
1966 "Sanity check failed. Maintain rate\n");
1971 scale_action = 0; 1967 scale_action = 0;
1972
1973 if ((le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >=
1974 IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && (is_mimo(tbl->lq_type))) {
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 } 1968 }
1987 lq_sta->last_bt_traffic =
1988 le32_to_cpu(mvm->last_bt_notif.bt_activity_grading);
1989 1969
1990 if ((le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >= 1970 /* 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)) { 1971 if (is_mimo(rate) &&
1992 /* search for a new modulation */ 1972 !iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) {
1973 IWL_DEBUG_RATE(mvm,
1974 "BT Coex forbids MIMO. Search for new config\n");
1993 rs_stay_in_table(lq_sta, true); 1975 rs_stay_in_table(lq_sta, true);
1994 goto lq_update; 1976 goto lq_update;
1995 } 1977 }
@@ -2000,6 +1982,9 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2000 if (low != IWL_RATE_INVALID) { 1982 if (low != IWL_RATE_INVALID) {
2001 update_lq = 1; 1983 update_lq = 1;
2002 index = low; 1984 index = low;
1985 } else {
1986 IWL_DEBUG_RATE(mvm,
1987 "At the bottom rate. Can't decrease\n");
2003 } 1988 }
2004 1989
2005 break; 1990 break;
@@ -2008,6 +1993,9 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2008 if (high != IWL_RATE_INVALID) { 1993 if (high != IWL_RATE_INVALID) {
2009 update_lq = 1; 1994 update_lq = 1;
2010 index = high; 1995 index = high;
1996 } else {
1997 IWL_DEBUG_RATE(mvm,
1998 "At the top rate. Can't increase\n");
2011 } 1999 }
2012 2000
2013 break; 2001 break;
@@ -2017,14 +2005,12 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2017 break; 2005 break;
2018 } 2006 }
2019 2007
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: 2008lq_update:
2025 /* Replace uCode's rate table for the destination station. */ 2009 /* Replace uCode's rate table for the destination station. */
2026 if (update_lq) 2010 if (update_lq) {
2027 rs_update_rate_tbl(mvm, sta, lq_sta, tbl, index); 2011 tbl->rate.index = index;
2012 rs_update_rate_tbl(mvm, sta, lq_sta, &tbl->rate);
2013 }
2028 2014
2029 rs_stay_in_table(lq_sta, false); 2015 rs_stay_in_table(lq_sta, false);
2030 2016
@@ -2035,20 +2021,29 @@ lq_update:
2035 * 3) Allowing a new search 2021 * 3) Allowing a new search
2036 */ 2022 */
2037 if (!update_lq && !done_search && 2023 if (!update_lq && !done_search &&
2038 !lq_sta->stay_in_tbl && window->counter) { 2024 lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED
2025 && window->counter) {
2026 enum rs_column next_column;
2027
2039 /* Save current throughput to compare with "search" throughput*/ 2028 /* Save current throughput to compare with "search" throughput*/
2040 lq_sta->last_tpt = current_tpt; 2029 lq_sta->last_tpt = current_tpt;
2041 2030
2042 /* Select a new "search" modulation mode to try. 2031 IWL_DEBUG_RATE(mvm,
2043 * If one is found, set up the new "search" table. */ 2032 "Start Search: update_lq %d done_search %d rs_state %d win->counter %d\n",
2044 if (is_legacy(tbl->lq_type)) 2033 update_lq, done_search, lq_sta->rs_state,
2045 rs_move_legacy_other(mvm, lq_sta, sta, index); 2034 window->counter);
2046 else if (is_siso(tbl->lq_type)) 2035
2047 rs_move_siso_to_other(mvm, lq_sta, sta, index); 2036 next_column = rs_get_next_column(mvm, lq_sta, sta, tbl);
2048 else if (is_mimo2(tbl->lq_type)) 2037 if (next_column != RS_COLUMN_INVALID) {
2049 rs_move_mimo2_to_other(mvm, lq_sta, sta, index); 2038 int ret = rs_switch_to_column(mvm, lq_sta, sta,
2050 else 2039 next_column);
2051 WARN_ON_ONCE(1); 2040 if (!ret)
2041 lq_sta->search_better_tbl = 1;
2042 } else {
2043 IWL_DEBUG_RATE(mvm,
2044 "No more columns to explore in search cycle. Go to RS_STATE_SEARCH_CYCLE_ENDED\n");
2045 lq_sta->rs_state = RS_STATE_SEARCH_CYCLE_ENDED;
2046 }
2052 2047
2053 /* If new "search" mode was selected, set up in uCode table */ 2048 /* If new "search" mode was selected, set up in uCode table */
2054 if (lq_sta->search_better_tbl) { 2049 if (lq_sta->search_better_tbl) {
@@ -2060,34 +2055,29 @@ lq_update:
2060 /* Use new "search" start rate */ 2055 /* Use new "search" start rate */
2061 index = iwl_hwrate_to_plcp_idx(tbl->current_rate); 2056 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
2062 2057
2063 IWL_DEBUG_RATE(mvm, 2058 rs_dump_rate(mvm, &tbl->rate,
2064 "Switch current mcs: %X index: %d\n", 2059 "Switch to SEARCH TABLE:");
2065 tbl->current_rate, index);
2066 rs_fill_link_cmd(mvm, sta, lq_sta, tbl->current_rate); 2060 rs_fill_link_cmd(mvm, sta, lq_sta, tbl->current_rate);
2067 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false); 2061 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
2068 } else { 2062 } else {
2069 done_search = 1; 2063 done_search = 1;
2070 } 2064 }
2071 } 2065 }
2072 2066
2073 if (done_search && !lq_sta->stay_in_tbl) { 2067 if (done_search && lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_ENDED) {
2074 /* If the "active" (non-search) mode was legacy, 2068 /* If the "active" (non-search) mode was legacy,
2075 * and we've tried switching antennas, 2069 * and we've tried switching antennas,
2076 * but we haven't been able to try HT modes (not available), 2070 * but we haven't been able to try HT modes (not available),
2077 * stay with best antenna legacy modulation for a while 2071 * stay with best antenna legacy modulation for a while
2078 * before next round of mode comparisons. */ 2072 * before next round of mode comparisons. */
2079 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); 2073 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
2080 if (is_legacy(tbl1->lq_type) && !sta->ht_cap.ht_supported && 2074 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"); 2075 IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n");
2083 rs_set_stay_in_table(mvm, 1, lq_sta); 2076 rs_set_stay_in_table(mvm, 1, lq_sta);
2084 } 2077 } else {
2085
2086 /* If we're in an HT mode, and all 3 mode switch actions 2078 /* If we're in an HT mode, and all 3 mode switch actions
2087 * have been tried and compared, stay in this best modulation 2079 * have been tried and compared, stay in this best modulation
2088 * mode for a while before next round of mode comparisons. */ 2080 * 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) && 2081 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
2092 (lq_sta->tx_agg_tid_en & (1 << tid)) && 2082 (lq_sta->tx_agg_tid_en & (1 << tid)) &&
2093 (tid != IWL_MAX_TID_COUNT)) { 2083 (tid != IWL_MAX_TID_COUNT)) {
@@ -2105,7 +2095,8 @@ lq_update:
2105 } 2095 }
2106 2096
2107out: 2097out:
2108 tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, index); 2098 tbl->rate.index = index;
2099 tbl->current_rate = ucode_rate_from_rs_rate(mvm, &tbl->rate);
2109 lq_sta->last_txrate_idx = index; 2100 lq_sta->last_txrate_idx = index;
2110} 2101}
2111 2102
@@ -2126,12 +2117,13 @@ out:
2126static void rs_initialize_lq(struct iwl_mvm *mvm, 2117static void rs_initialize_lq(struct iwl_mvm *mvm,
2127 struct ieee80211_sta *sta, 2118 struct ieee80211_sta *sta,
2128 struct iwl_lq_sta *lq_sta, 2119 struct iwl_lq_sta *lq_sta,
2129 enum ieee80211_band band) 2120 enum ieee80211_band band,
2121 bool init)
2130{ 2122{
2131 struct iwl_scale_tbl_info *tbl; 2123 struct iwl_scale_tbl_info *tbl;
2132 int rate_idx; 2124 struct rs_rate *rate;
2133 int i; 2125 int i;
2134 u32 rate; 2126 u32 ucode_rate;
2135 u8 active_tbl = 0; 2127 u8 active_tbl = 0;
2136 u8 valid_tx_ant; 2128 u8 valid_tx_ant;
2137 2129
@@ -2148,27 +2140,33 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
2148 active_tbl = 1 - lq_sta->active_tbl; 2140 active_tbl = 1 - lq_sta->active_tbl;
2149 2141
2150 tbl = &(lq_sta->lq_info[active_tbl]); 2142 tbl = &(lq_sta->lq_info[active_tbl]);
2143 rate = &tbl->rate;
2151 2144
2152 if ((i < 0) || (i >= IWL_RATE_COUNT)) 2145 if ((i < 0) || (i >= IWL_RATE_COUNT))
2153 i = 0; 2146 i = 0;
2154 2147
2155 rate = iwl_rates[i].plcp; 2148 rate->index = i;
2156 tbl->ant_type = first_antenna(valid_tx_ant); 2149 rate->ant = first_antenna(valid_tx_ant);
2157 rate |= tbl->ant_type << RATE_MCS_ANT_POS; 2150 rate->sgi = false;
2151 rate->bw = RATE_MCS_CHAN_WIDTH_20;
2152 if (band == IEEE80211_BAND_5GHZ)
2153 rate->type = LQ_LEGACY_A;
2154 else
2155 rate->type = LQ_LEGACY_G;
2158 2156
2159 if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE) 2157 ucode_rate = ucode_rate_from_rs_rate(mvm, rate);
2160 rate |= RATE_MCS_CCK_MSK; 2158 tbl->current_rate = ucode_rate;
2161 2159
2162 rs_get_tbl_info_from_mcs(rate, band, tbl, &rate_idx); 2160 WARN_ON_ONCE(rate->ant != ANT_A && rate->ant != ANT_B);
2163 if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type)) 2161 if (rate->ant == ANT_A)
2164 rs_toggle_antenna(valid_tx_ant, &rate, tbl); 2162 tbl->column = RS_COLUMN_LEGACY_ANT_A;
2163 else
2164 tbl->column = RS_COLUMN_LEGACY_ANT_B;
2165 2165
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); 2166 rs_set_expected_tpt_table(lq_sta, tbl);
2169 rs_fill_link_cmd(NULL, NULL, lq_sta, rate); 2167 rs_fill_link_cmd(NULL, NULL, lq_sta, ucode_rate);
2170 /* TODO restore station should remember the lq cmd */ 2168 /* TODO restore station should remember the lq cmd */
2171 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_SYNC, true); 2169 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, init);
2172} 2170}
2173 2171
2174static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta, 2172static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
@@ -2182,8 +2180,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); 2180 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2183 struct iwl_lq_sta *lq_sta = mvm_sta; 2181 struct iwl_lq_sta *lq_sta = mvm_sta;
2184 2182
2185 IWL_DEBUG_RATE_LIMIT(mvm, "rate scale calculate new rate for skb\n");
2186
2187 /* Get max rate if user set max rate */ 2183 /* Get max rate if user set max rate */
2188 if (lq_sta) { 2184 if (lq_sta) {
2189 lq_sta->max_rate_idx = txrc->max_rate_idx; 2185 lq_sta->max_rate_idx = txrc->max_rate_idx;
@@ -2242,11 +2238,51 @@ static int rs_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap,
2242 return -1; 2238 return -1;
2243} 2239}
2244 2240
2241static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
2242 struct ieee80211_sta_vht_cap *vht_cap,
2243 struct iwl_lq_sta *lq_sta)
2244{
2245 int i;
2246 int highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 1);
2247
2248 if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
2249 for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
2250 if (i == IWL_RATE_9M_INDEX)
2251 continue;
2252
2253 /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */
2254 if (i == IWL_RATE_MCS_9_INDEX &&
2255 sta->bandwidth == IEEE80211_STA_RX_BW_20)
2256 continue;
2257
2258 lq_sta->active_siso_rate |= BIT(i);
2259 }
2260 }
2261
2262 if (sta->rx_nss < 2)
2263 return;
2264
2265 highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 2);
2266 if (highest_mcs >= IWL_RATE_MCS_0_INDEX) {
2267 for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) {
2268 if (i == IWL_RATE_9M_INDEX)
2269 continue;
2270
2271 /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */
2272 if (i == IWL_RATE_MCS_9_INDEX &&
2273 sta->bandwidth == IEEE80211_STA_RX_BW_20)
2274 continue;
2275
2276 lq_sta->active_mimo2_rate |= BIT(i);
2277 }
2278 }
2279}
2280
2245/* 2281/*
2246 * Called after adding a new station to initialize rate scaling 2282 * Called after adding a new station to initialize rate scaling
2247 */ 2283 */
2248void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 2284void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2249 enum ieee80211_band band) 2285 enum ieee80211_band band, bool init)
2250{ 2286{
2251 int i, j; 2287 int i, j;
2252 struct ieee80211_hw *hw = mvm->hw; 2288 struct ieee80211_hw *hw = mvm->hw;
@@ -2259,6 +2295,8 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2259 2295
2260 sta_priv = (struct iwl_mvm_sta *)sta->drv_priv; 2296 sta_priv = (struct iwl_mvm_sta *)sta->drv_priv;
2261 lq_sta = &sta_priv->lq_sta; 2297 lq_sta = &sta_priv->lq_sta;
2298 memset(lq_sta, 0, sizeof(*lq_sta));
2299
2262 sband = hw->wiphy->bands[band]; 2300 sband = hw->wiphy->bands[band];
2263 2301
2264 lq_sta->lq.sta_id = sta_priv->sta_id; 2302 lq_sta->lq.sta_id = sta_priv->sta_id;
@@ -2308,27 +2346,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2308 2346
2309 lq_sta->is_vht = false; 2347 lq_sta->is_vht = false;
2310 } else { 2348 } else {
2311 int highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 1); 2349 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; 2350 lq_sta->is_vht = true;
2333 } 2351 }
2334 2352
@@ -2341,15 +2359,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2341 /* These values will be overridden later */ 2359 /* These values will be overridden later */
2342 lq_sta->lq.single_stream_ant_msk = 2360 lq_sta->lq.single_stream_ant_msk =
2343 first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); 2361 first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
2344 lq_sta->lq.dual_stream_ant_msk = 2362 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 2363
2354 /* as default allow aggregation for all tids */ 2364 /* as default allow aggregation for all tids */
2355 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; 2365 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
@@ -2364,16 +2374,33 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2364 lq_sta->dbg_fixed_rate = 0; 2374 lq_sta->dbg_fixed_rate = 0;
2365#endif 2375#endif
2366 2376
2367 rs_initialize_lq(mvm, sta, lq_sta, band); 2377 rs_initialize_lq(mvm, sta, lq_sta, band, init);
2378}
2379
2380static void rs_rate_update(void *mvm_r,
2381 struct ieee80211_supported_band *sband,
2382 struct cfg80211_chan_def *chandef,
2383 struct ieee80211_sta *sta, void *priv_sta,
2384 u32 changed)
2385{
2386 u8 tid;
2387 struct iwl_op_mode *op_mode =
2388 (struct iwl_op_mode *)mvm_r;
2389 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
2390
2391 /* Stop any ongoing aggregations as rs starts off assuming no agg */
2392 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
2393 ieee80211_stop_tx_ba_session(sta, tid);
2394
2395 iwl_mvm_rs_rate_init(mvm, sta, sband->band, false);
2368} 2396}
2369 2397
2370static void rs_fill_link_cmd(struct iwl_mvm *mvm, 2398static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2371 struct ieee80211_sta *sta, 2399 struct ieee80211_sta *sta,
2372 struct iwl_lq_sta *lq_sta, u32 new_rate) 2400 struct iwl_lq_sta *lq_sta, u32 new_rate)
2373{ 2401{
2374 struct iwl_scale_tbl_info tbl_type; 2402 struct rs_rate rate;
2375 int index = 0; 2403 int index = 0;
2376 int rate_idx;
2377 int repeat_rate = 0; 2404 int repeat_rate = 0;
2378 u8 ant_toggle_cnt = 0; 2405 u8 ant_toggle_cnt = 0;
2379 u8 use_ht_possible = 1; 2406 u8 use_ht_possible = 1;
@@ -2383,12 +2410,10 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2383 /* Override starting rate (index 0) if needed for debug purposes */ 2410 /* Override starting rate (index 0) if needed for debug purposes */
2384 rs_dbgfs_set_mcs(lq_sta, &new_rate); 2411 rs_dbgfs_set_mcs(lq_sta, &new_rate);
2385 2412
2386 /* Interpret new_rate (rate_n_flags) */ 2413 rs_rate_from_ucode_rate(new_rate, lq_sta->band, &rate);
2387 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
2388 &tbl_type, &rate_idx);
2389 2414
2390 /* How many times should we repeat the initial rate? */ 2415 /* How many times should we repeat the initial rate? */
2391 if (is_legacy(tbl_type.lq_type)) { 2416 if (is_legacy(&rate)) {
2392 ant_toggle_cnt = 1; 2417 ant_toggle_cnt = 1;
2393 repeat_rate = IWL_NUMBER_TRY; 2418 repeat_rate = IWL_NUMBER_TRY;
2394 } else { 2419 } else {
@@ -2396,15 +2421,13 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2396 LINK_QUAL_AGG_DISABLE_START_DEF - 1); 2421 LINK_QUAL_AGG_DISABLE_START_DEF - 1);
2397 } 2422 }
2398 2423
2399 lq_cmd->mimo_delim = is_mimo(tbl_type.lq_type) ? 1 : 0; 2424 lq_cmd->mimo_delim = is_mimo(&rate) ? 1 : 0;
2400 2425
2401 /* Fill 1st table entry (index 0) */ 2426 /* Fill 1st table entry (index 0) */
2402 lq_cmd->rs_table[index] = cpu_to_le32(new_rate); 2427 lq_cmd->rs_table[index] = cpu_to_le32(new_rate);
2403 2428
2404 if (num_of_ant(tbl_type.ant_type) == 1) 2429 if (num_of_ant(rate.ant) == 1)
2405 lq_cmd->single_stream_ant_msk = tbl_type.ant_type; 2430 lq_cmd->single_stream_ant_msk = rate.ant;
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 */ 2431 /* otherwise we don't modify the existing value */
2409 2432
2410 index++; 2433 index++;
@@ -2418,12 +2441,12 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2418 * For legacy IWL_NUMBER_TRY == 1, this loop will not execute. 2441 * For legacy IWL_NUMBER_TRY == 1, this loop will not execute.
2419 * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */ 2442 * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */
2420 while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) { 2443 while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {
2421 if (is_legacy(tbl_type.lq_type)) { 2444 if (is_legacy(&rate)) {
2422 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) 2445 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
2423 ant_toggle_cnt++; 2446 ant_toggle_cnt++;
2424 else if (mvm && 2447 else if (mvm &&
2425 rs_toggle_antenna(valid_tx_ant, 2448 rs_toggle_antenna(valid_tx_ant,
2426 &new_rate, &tbl_type)) 2449 &new_rate, &rate))
2427 ant_toggle_cnt = 1; 2450 ant_toggle_cnt = 1;
2428 } 2451 }
2429 2452
@@ -2437,26 +2460,25 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2437 index++; 2460 index++;
2438 } 2461 }
2439 2462
2440 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, 2463 rs_rate_from_ucode_rate(new_rate, lq_sta->band, &rate);
2441 &rate_idx);
2442 2464
2443 /* Indicate to uCode which entries might be MIMO. 2465 /* Indicate to uCode which entries might be MIMO.
2444 * If initial rate was MIMO, this will finally end up 2466 * If initial rate was MIMO, this will finally end up
2445 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */ 2467 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
2446 if (is_mimo(tbl_type.lq_type)) 2468 if (is_mimo(&rate))
2447 lq_cmd->mimo_delim = index; 2469 lq_cmd->mimo_delim = index;
2448 2470
2449 /* Get next rate */ 2471 /* Get next rate */
2450 new_rate = rs_get_lower_rate(lq_sta, &tbl_type, rate_idx, 2472 new_rate = rs_get_lower_rate(lq_sta, &rate, rate.index,
2451 use_ht_possible); 2473 use_ht_possible);
2452 2474
2453 /* How many times should we repeat the next rate? */ 2475 /* How many times should we repeat the next rate? */
2454 if (is_legacy(tbl_type.lq_type)) { 2476 if (is_legacy(&rate)) {
2455 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) 2477 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
2456 ant_toggle_cnt++; 2478 ant_toggle_cnt++;
2457 else if (mvm && 2479 else if (mvm &&
2458 rs_toggle_antenna(valid_tx_ant, 2480 rs_toggle_antenna(valid_tx_ant,
2459 &new_rate, &tbl_type)) 2481 &new_rate, &rate))
2460 ant_toggle_cnt = 1; 2482 ant_toggle_cnt = 1;
2461 2483
2462 repeat_rate = IWL_NUMBER_TRY; 2484 repeat_rate = IWL_NUMBER_TRY;
@@ -2527,7 +2549,6 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
2527 >> RATE_MCS_ANT_POS); 2549 >> RATE_MCS_ANT_POS);
2528 if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) { 2550 if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) {
2529 *rate_n_flags = lq_sta->dbg_fixed_rate; 2551 *rate_n_flags = lq_sta->dbg_fixed_rate;
2530 IWL_DEBUG_RATE(mvm, "Fixed rate ON\n");
2531 } else { 2552 } else {
2532 lq_sta->dbg_fixed_rate = 0; 2553 lq_sta->dbg_fixed_rate = 0;
2533 IWL_ERR(mvm, 2554 IWL_ERR(mvm,
@@ -2535,9 +2556,60 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
2535 ant_sel_tx, valid_tx_ant); 2556 ant_sel_tx, valid_tx_ant);
2536 IWL_DEBUG_RATE(mvm, "Fixed rate OFF\n"); 2557 IWL_DEBUG_RATE(mvm, "Fixed rate OFF\n");
2537 } 2558 }
2559 }
2560}
2561
2562static int rs_pretty_print_rate(char *buf, const u32 rate)
2563{
2564
2565 char *type, *bw;
2566 u8 mcs = 0, nss = 0;
2567 u8 ant = (rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS;
2568
2569 if (!(rate & RATE_MCS_HT_MSK) &&
2570 !(rate & RATE_MCS_VHT_MSK)) {
2571 int index = iwl_hwrate_to_plcp_idx(rate);
2572
2573 return sprintf(buf, "Legacy | ANT: %s Rate: %s Mbps\n",
2574 rs_pretty_ant(ant), iwl_rate_mcs[index].mbps);
2575 }
2576
2577 if (rate & RATE_MCS_VHT_MSK) {
2578 type = "VHT";
2579 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;
2580 nss = ((rate & RATE_VHT_MCS_NSS_MSK)
2581 >> RATE_VHT_MCS_NSS_POS) + 1;
2582 } else if (rate & RATE_MCS_HT_MSK) {
2583 type = "HT";
2584 mcs = rate & RATE_HT_MCS_INDEX_MSK;
2538 } else { 2585 } else {
2539 IWL_DEBUG_RATE(mvm, "Fixed rate OFF\n"); 2586 type = "Unknown"; /* shouldn't happen */
2587 }
2588
2589 switch (rate & RATE_MCS_CHAN_WIDTH_MSK) {
2590 case RATE_MCS_CHAN_WIDTH_20:
2591 bw = "20Mhz";
2592 break;
2593 case RATE_MCS_CHAN_WIDTH_40:
2594 bw = "40Mhz";
2595 break;
2596 case RATE_MCS_CHAN_WIDTH_80:
2597 bw = "80Mhz";
2598 break;
2599 case RATE_MCS_CHAN_WIDTH_160:
2600 bw = "160Mhz";
2601 break;
2602 default:
2603 bw = "BAD BW";
2540 } 2604 }
2605
2606 return sprintf(buf, "%s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s\n",
2607 type, rs_pretty_ant(ant), bw, mcs, nss,
2608 (rate & RATE_MCS_SGI_MSK) ? "SGI " : "NGI ",
2609 (rate & RATE_MCS_STBC_MSK) ? "STBC " : "",
2610 (rate & RATE_MCS_LDPC_MSK) ? "LDPC " : "",
2611 (rate & RATE_MCS_BF_MSK) ? "BF " : "",
2612 (rate & RATE_MCS_ZLF_MSK) ? "ZLF " : "");
2541} 2613}
2542 2614
2543static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, 2615static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
@@ -2572,15 +2644,14 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2572 char *buff; 2644 char *buff;
2573 int desc = 0; 2645 int desc = 0;
2574 int i = 0; 2646 int i = 0;
2575 int index = 0;
2576 ssize_t ret; 2647 ssize_t ret;
2577 2648
2578 struct iwl_lq_sta *lq_sta = file->private_data; 2649 struct iwl_lq_sta *lq_sta = file->private_data;
2579 struct iwl_mvm *mvm; 2650 struct iwl_mvm *mvm;
2580 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 2651 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2581 2652 struct rs_rate *rate = &tbl->rate;
2582 mvm = lq_sta->drv; 2653 mvm = lq_sta->drv;
2583 buff = kmalloc(1024, GFP_KERNEL); 2654 buff = kmalloc(2048, GFP_KERNEL);
2584 if (!buff) 2655 if (!buff)
2585 return -ENOMEM; 2656 return -ENOMEM;
2586 2657
@@ -2595,23 +2666,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," : "", 2666 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "",
2596 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : ""); 2667 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : "");
2597 desc += sprintf(buff+desc, "lq type %s\n", 2668 desc += sprintf(buff+desc, "lq type %s\n",
2598 (is_legacy(tbl->lq_type)) ? "legacy" : 2669 (is_legacy(rate)) ? "legacy" :
2599 is_vht(tbl->lq_type) ? "VHT" : "HT"); 2670 is_vht(rate) ? "VHT" : "HT");
2600 if (is_ht(tbl->lq_type)) { 2671 if (!is_legacy(rate)) {
2601 desc += sprintf(buff+desc, " %s", 2672 desc += sprintf(buff+desc, " %s",
2602 (is_siso(tbl->lq_type)) ? "SISO" : "MIMO2"); 2673 (is_siso(rate)) ? "SISO" : "MIMO2");
2603 desc += sprintf(buff+desc, " %s", 2674 desc += sprintf(buff+desc, " %s",
2604 (is_ht20(tbl)) ? "20MHz" : 2675 (is_ht20(rate)) ? "20MHz" :
2605 (is_ht40(tbl)) ? "40MHz" : 2676 (is_ht40(rate)) ? "40MHz" :
2606 (is_ht80(tbl)) ? "80Mhz" : "BAD BW"); 2677 (is_ht80(rate)) ? "80Mhz" : "BAD BW");
2607 desc += sprintf(buff+desc, " %s %s\n", 2678 desc += sprintf(buff+desc, " %s %s\n",
2608 (tbl->is_SGI) ? "SGI" : "", 2679 (rate->sgi) ? "SGI" : "NGI",
2609 (lq_sta->is_agg) ? "AGG on" : ""); 2680 (lq_sta->is_agg) ? "AGG on" : "");
2610 } 2681 }
2611 desc += sprintf(buff+desc, "last tx rate=0x%X\n", 2682 desc += sprintf(buff+desc, "last tx rate=0x%X\n",
2612 lq_sta->last_rate_n_flags); 2683 lq_sta->last_rate_n_flags);
2613 desc += sprintf(buff+desc, 2684 desc += sprintf(buff+desc,
2614 "general: flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n", 2685 "general: flags=0x%X mimo-d=%d s-ant=0x%x d-ant=0x%x\n",
2615 lq_sta->lq.flags, 2686 lq_sta->lq.flags,
2616 lq_sta->lq.mimo_delim, 2687 lq_sta->lq.mimo_delim,
2617 lq_sta->lq.single_stream_ant_msk, 2688 lq_sta->lq.single_stream_ant_msk,
@@ -2631,19 +2702,12 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2631 lq_sta->lq.initial_rate_index[3]); 2702 lq_sta->lq.initial_rate_index[3]);
2632 2703
2633 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { 2704 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
2634 index = iwl_hwrate_to_plcp_idx( 2705 u32 rate = le32_to_cpu(lq_sta->lq.rs_table[i]);
2635 le32_to_cpu(lq_sta->lq.rs_table[i])); 2706 desc += sprintf(buff+desc,
2636 if (is_legacy(tbl->lq_type)) { 2707 " rate[%d] 0x%X ",
2637 desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n", 2708 i, rate);
2638 i, le32_to_cpu(lq_sta->lq.rs_table[i]), 2709
2639 iwl_rate_mcs[index].mbps); 2710 desc += rs_pretty_print_rate(buff+desc, rate);
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 } 2711 }
2648 2712
2649 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); 2713 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
@@ -2665,6 +2729,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2665 int i, j; 2729 int i, j;
2666 ssize_t ret; 2730 ssize_t ret;
2667 struct iwl_scale_tbl_info *tbl; 2731 struct iwl_scale_tbl_info *tbl;
2732 struct rs_rate *rate;
2668 struct iwl_lq_sta *lq_sta = file->private_data; 2733 struct iwl_lq_sta *lq_sta = file->private_data;
2669 2734
2670 buff = kmalloc(1024, GFP_KERNEL); 2735 buff = kmalloc(1024, GFP_KERNEL);
@@ -2673,15 +2738,16 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2673 2738
2674 for (i = 0; i < LQ_SIZE; i++) { 2739 for (i = 0; i < LQ_SIZE; i++) {
2675 tbl = &(lq_sta->lq_info[i]); 2740 tbl = &(lq_sta->lq_info[i]);
2741 rate = &tbl->rate;
2676 desc += sprintf(buff+desc, 2742 desc += sprintf(buff+desc,
2677 "%s type=%d SGI=%d BW=%s DUP=0\n" 2743 "%s type=%d SGI=%d BW=%s DUP=0\n"
2678 "rate=0x%X\n", 2744 "rate=0x%X\n",
2679 lq_sta->active_tbl == i ? "*" : "x", 2745 lq_sta->active_tbl == i ? "*" : "x",
2680 tbl->lq_type, 2746 rate->type,
2681 tbl->is_SGI, 2747 rate->sgi,
2682 is_ht20(tbl) ? "20Mhz" : 2748 is_ht20(rate) ? "20Mhz" :
2683 is_ht40(tbl) ? "40Mhz" : 2749 is_ht40(rate) ? "40Mhz" :
2684 is_ht80(tbl) ? "80Mhz" : "ERR", 2750 is_ht80(rate) ? "80Mhz" : "ERR",
2685 tbl->current_rate); 2751 tbl->current_rate);
2686 for (j = 0; j < IWL_RATE_COUNT; j++) { 2752 for (j = 0; j < IWL_RATE_COUNT; j++) {
2687 desc += sprintf(buff+desc, 2753 desc += sprintf(buff+desc,
@@ -2746,6 +2812,7 @@ static struct rate_control_ops rs_mvm_ops = {
2746 .free = rs_free, 2812 .free = rs_free,
2747 .alloc_sta = rs_alloc_sta, 2813 .alloc_sta = rs_alloc_sta,
2748 .free_sta = rs_free_sta, 2814 .free_sta = rs_free_sta,
2815 .rate_update = rs_rate_update,
2749#ifdef CONFIG_MAC80211_DEBUGFS 2816#ifdef CONFIG_MAC80211_DEBUGFS
2750 .add_sta_debugfs = rs_add_debugfs, 2817 .add_sta_debugfs = rs_add_debugfs,
2751 .remove_sta_debugfs = rs_remove_debugfs, 2818 .remove_sta_debugfs = rs_remove_debugfs,
@@ -2778,13 +2845,13 @@ int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
2778 2845
2779 if (enable) { 2846 if (enable) {
2780 if (mvmsta->tx_protection == 0) 2847 if (mvmsta->tx_protection == 0)
2781 lq->flags |= LQ_FLAG_SET_STA_TLC_RTS_MSK; 2848 lq->flags |= LQ_FLAG_USE_RTS_MSK;
2782 mvmsta->tx_protection++; 2849 mvmsta->tx_protection++;
2783 } else { 2850 } else {
2784 mvmsta->tx_protection--; 2851 mvmsta->tx_protection--;
2785 if (mvmsta->tx_protection == 0) 2852 if (mvmsta->tx_protection == 0)
2786 lq->flags &= ~LQ_FLAG_SET_STA_TLC_RTS_MSK; 2853 lq->flags &= ~LQ_FLAG_USE_RTS_MSK;
2787 } 2854 }
2788 2855
2789 return iwl_mvm_send_lq_cmd(mvm, lq, CMD_ASYNC, false); 2856 return iwl_mvm_send_lq_cmd(mvm, lq, false);
2790} 2857}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 5d5344f7070b..b32960796384 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -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,19 @@ 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 */ 281 u32 current_rate; /* rate_n_flags, uCode API format */
278 struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ 282 struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
279}; 283};
280 284
285enum {
286 RS_STATE_SEARCH_CYCLE_STARTED,
287 RS_STATE_SEARCH_CYCLE_ENDED,
288 RS_STATE_STAY_IN_COLUMN,
289};
290
281/** 291/**
282 * struct iwl_lq_sta -- driver's rate scaling private structure 292 * struct iwl_lq_sta -- driver's rate scaling private structure
283 * 293 *
@@ -285,8 +295,7 @@ struct iwl_scale_tbl_info {
285 */ 295 */
286struct iwl_lq_sta { 296struct iwl_lq_sta {
287 u8 active_tbl; /* index of active table, range 0-1 */ 297 u8 active_tbl; /* index of active table, range 0-1 */
288 u8 enable_counter; /* indicates HT mode */ 298 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 */ 299 u8 search_better_tbl; /* 1: currently trying alternate mode */
291 s32 last_tpt; 300 s32 last_tpt;
292 301
@@ -299,7 +308,9 @@ struct iwl_lq_sta {
299 u32 total_success; /* total successful frames, any/all rates */ 308 u32 total_success; /* total successful frames, any/all rates */
300 u64 flush_timer; /* time staying in mode before new search */ 309 u64 flush_timer; /* time staying in mode before new search */
301 310
302 u8 action_counter; /* # mode-switch actions tried */ 311 u32 visited_columns; /* Bitmask marking which Tx columns were
312 * explored during a search cycle
313 */
303 bool is_vht; 314 bool is_vht;
304 enum ieee80211_band band; 315 enum ieee80211_band band;
305 316
@@ -328,32 +339,11 @@ struct iwl_lq_sta {
328 u32 last_rate_n_flags; 339 u32 last_rate_n_flags;
329 /* packets destined for this STA are aggregated */ 340 /* packets destined for this STA are aggregated */
330 u8 is_agg; 341 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}; 342};
345 343
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 */ 344/* Initialize station's rate scaling information after adding station */
355void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 345void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
356 enum ieee80211_band band); 346 enum ieee80211_band band, bool init);
357 347
358/** 348/**
359 * iwl_rate_control_register - Register the rate control algorithm callbacks 349 * iwl_rate_control_register - Register the rate control algorithm callbacks
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index e0cd100b40cd..4ce9bb581144 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -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
@@ -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);
@@ -522,6 +541,12 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
522 struct cfg80211_sched_scan_request *req, 541 struct cfg80211_sched_scan_request *req,
523 struct iwl_scan_offload_cmd *scan) 542 struct iwl_scan_offload_cmd *scan)
524{ 543{
544 bool is_assoc = false;
545
546 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
547 IEEE80211_IFACE_ITER_NORMAL,
548 iwl_mvm_vif_assoc_iterator,
549 &is_assoc);
525 scan->channel_count = 550 scan->channel_count =
526 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels + 551 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels +
527 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; 552 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
@@ -529,8 +554,9 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
529 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); 554 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
530 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT; 555 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT;
531 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm); 556 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm);
532 scan->max_out_time = cpu_to_le32(200 * 1024); 557 scan->max_out_time = iwl_mvm_scan_max_out_time(vif, req->flags,
533 scan->suspend_time = iwl_mvm_scan_suspend_time(vif); 558 is_assoc);
559 scan->suspend_time = iwl_mvm_scan_suspend_time(vif, is_assoc);
534 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 560 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
535 MAC_FILTER_IN_BEACON); 561 MAC_FILTER_IN_BEACON);
536 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND); 562 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND);
@@ -817,11 +843,10 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
817 IWL_DEBUG_SCAN(mvm, 843 IWL_DEBUG_SCAN(mvm,
818 "Sending scheduled scan with filtering, filter len %d\n", 844 "Sending scheduled scan with filtering, filter len %d\n",
819 req->n_match_sets); 845 req->n_match_sets);
820 scan_req.flags |=
821 cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID);
822 } else { 846 } else {
823 IWL_DEBUG_SCAN(mvm, 847 IWL_DEBUG_SCAN(mvm,
824 "Sending Scheduled scan without filtering\n"); 848 "Sending Scheduled scan without filtering\n");
849 scan_req.flags |= cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_PASS_ALL);
825 } 850 }
826 851
827 return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, CMD_SYNC, 852 return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, CMD_SYNC,
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 329952363a54..7a5b7473eafa 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -840,7 +840,7 @@ static const u8 tid_to_ac[] = {
840int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 840int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
841 struct ieee80211_sta *sta, u16 tid, u16 *ssn) 841 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
842{ 842{
843 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 843 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
844 struct iwl_mvm_tid_data *tid_data; 844 struct iwl_mvm_tid_data *tid_data;
845 int txq_id; 845 int txq_id;
846 846
@@ -895,7 +895,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, 895int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
896 struct ieee80211_sta *sta, u16 tid, u8 buf_size) 896 struct ieee80211_sta *sta, u16 tid, u8 buf_size)
897{ 897{
898 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 898 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
899 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 899 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
900 int queue, fifo, ret; 900 int queue, fifo, ret;
901 u16 ssn; 901 u16 ssn;
@@ -945,13 +945,13 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
945 */ 945 */
946 } 946 }
947 947
948 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, CMD_ASYNC, false); 948 return iwl_mvm_send_lq_cmd(mvm, &mvmsta->lq_sta.lq, false);
949} 949}
950 950
951int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 951int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
952 struct ieee80211_sta *sta, u16 tid) 952 struct ieee80211_sta *sta, u16 tid)
953{ 953{
954 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 954 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
955 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 955 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
956 u16 txq_id; 956 u16 txq_id;
957 int err; 957 int err;
@@ -1023,7 +1023,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, 1023int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1024 struct ieee80211_sta *sta, u16 tid) 1024 struct ieee80211_sta *sta, u16 tid)
1025{ 1025{
1026 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1026 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1027 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 1027 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
1028 u16 txq_id; 1028 u16 txq_id;
1029 enum iwl_mvm_agg_state old_state; 1029 enum iwl_mvm_agg_state old_state;
@@ -1416,7 +1416,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
1416void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, 1416void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
1417 struct ieee80211_sta *sta) 1417 struct ieee80211_sta *sta)
1418{ 1418{
1419 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1419 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1420 struct iwl_mvm_add_sta_cmd_v6 cmd = { 1420 struct iwl_mvm_add_sta_cmd_v6 cmd = {
1421 .add_modify = STA_MODE_MODIFY, 1421 .add_modify = STA_MODE_MODIFY,
1422 .sta_id = mvmsta->sta_id, 1422 .sta_id = mvmsta->sta_id,
@@ -1438,7 +1438,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
1438 u16 sleep_state_flags = 1438 u16 sleep_state_flags =
1439 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ? 1439 (reason == IEEE80211_FRAME_RELEASE_UAPSD) ?
1440 STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL; 1440 STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL;
1441 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 1441 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1442 struct iwl_mvm_add_sta_cmd_v6 cmd = { 1442 struct iwl_mvm_add_sta_cmd_v6 cmd = {
1443 .add_modify = STA_MODE_MODIFY, 1443 .add_modify = STA_MODE_MODIFY,
1444 .sta_id = mvmsta->sta_id, 1444 .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..b34941148a98 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -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/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
index 1f3282dff513..18be04da8e3f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -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..d87649ac88e1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -276,6 +276,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
276 return NULL; 276 return NULL;
277 277
278 memset(dev_cmd, 0, sizeof(*dev_cmd)); 278 memset(dev_cmd, 0, sizeof(*dev_cmd));
279 dev_cmd->hdr.cmd = TX_CMD;
279 tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload; 280 tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;
280 281
281 if (info->control.hw_key) 282 if (info->control.hw_key)
@@ -361,7 +362,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
361 u8 txq_id = info->hw_queue; 362 u8 txq_id = info->hw_queue;
362 bool is_data_qos = false, is_ampdu = false; 363 bool is_data_qos = false, is_ampdu = false;
363 364
364 mvmsta = (void *)sta->drv_priv; 365 mvmsta = iwl_mvm_sta_from_mac80211(sta);
365 fc = hdr->frame_control; 366 fc = hdr->frame_control;
366 367
367 if (WARN_ON_ONCE(!mvmsta)) 368 if (WARN_ON_ONCE(!mvmsta))
@@ -432,7 +433,7 @@ drop:
432static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm, 433static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
433 struct ieee80211_sta *sta, u8 tid) 434 struct ieee80211_sta *sta, u8 tid)
434{ 435{
435 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 436 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
436 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 437 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
437 struct ieee80211_vif *vif = mvmsta->vif; 438 struct ieee80211_vif *vif = mvmsta->vif;
438 439
@@ -662,7 +663,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]); 663 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
663 664
664 if (!IS_ERR_OR_NULL(sta)) { 665 if (!IS_ERR_OR_NULL(sta)) {
665 mvmsta = (void *)sta->drv_priv; 666 mvmsta = iwl_mvm_sta_from_mac80211(sta);
666 667
667 if (tid != IWL_TID_NON_QOS) { 668 if (tid != IWL_TID_NON_QOS) {
668 struct iwl_mvm_tid_data *tid_data = 669 struct iwl_mvm_tid_data *tid_data =
@@ -793,7 +794,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]); 794 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
794 795
795 if (!WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) { 796 if (!WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) {
796 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; 797 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
797 mvmsta->tid_data[tid].rate_n_flags = 798 mvmsta->tid_data[tid].rate_n_flags =
798 le32_to_cpu(tx_resp->initial_rate); 799 le32_to_cpu(tx_resp->initial_rate);
799 } 800 }
@@ -849,7 +850,7 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
849 return 0; 850 return 0;
850 } 851 }
851 852
852 mvmsta = (void *)sta->drv_priv; 853 mvmsta = iwl_mvm_sta_from_mac80211(sta);
853 tid_data = &mvmsta->tid_data[tid]; 854 tid_data = &mvmsta->tid_data[tid];
854 855
855 if (WARN_ONCE(tid_data->txq_id != scd_flow, "Q %d, tid %d, flow %d", 856 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..56cf819bc0c7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -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
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 86605027c41d..2e97a3995333 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -297,6 +297,9 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
297 {IWL_PCI_DEVICE(0x08B2, 0x4370, iwl7260_2ac_cfg)}, 297 {IWL_PCI_DEVICE(0x08B2, 0x4370, iwl7260_2ac_cfg)},
298 {IWL_PCI_DEVICE(0x08B2, 0x4360, iwl7260_2n_cfg)}, 298 {IWL_PCI_DEVICE(0x08B2, 0x4360, iwl7260_2n_cfg)},
299 {IWL_PCI_DEVICE(0x08B1, 0x5070, iwl7260_2ac_cfg)}, 299 {IWL_PCI_DEVICE(0x08B1, 0x5070, iwl7260_2ac_cfg)},
300 {IWL_PCI_DEVICE(0x08B1, 0x5072, iwl7260_2ac_cfg)},
301 {IWL_PCI_DEVICE(0x08B1, 0x5170, iwl7260_2ac_cfg)},
302 {IWL_PCI_DEVICE(0x08B1, 0x5770, iwl7260_2ac_cfg)},
300 {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)}, 303 {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)},
301 {IWL_PCI_DEVICE(0x08B1, 0x402A, iwl7260_2n_cfg)}, 304 {IWL_PCI_DEVICE(0x08B1, 0x402A, iwl7260_2n_cfg)},
302 {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)}, 305 {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)},
@@ -350,6 +353,8 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
350 {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)}, 353 {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)},
351 {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)}, 354 {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)},
352 {IWL_PCI_DEVICE(0x08B3, 0x8570, iwl3160_2ac_cfg)}, 355 {IWL_PCI_DEVICE(0x08B3, 0x8570, iwl3160_2ac_cfg)},
356 {IWL_PCI_DEVICE(0x08B3, 0x1070, iwl3160_2ac_cfg)},
357 {IWL_PCI_DEVICE(0x08B3, 0x1170, iwl3160_2ac_cfg)},
353 358
354/* 7265 Series */ 359/* 7265 Series */
355 {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, 360 {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index be3995afa9d0..1d6bf7b98e2d 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -1126,7 +1126,6 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)
1126 struct iwl_trans *trans = data; 1126 struct iwl_trans *trans = data;
1127 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1127 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1128 u32 inta, inta_mask; 1128 u32 inta, inta_mask;
1129 irqreturn_t ret = IRQ_NONE;
1130 1129
1131 lockdep_assert_held(&trans_pcie->irq_lock); 1130 lockdep_assert_held(&trans_pcie->irq_lock);
1132 1131
@@ -1155,7 +1154,16 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)
1155 * or due to sporadic interrupts thrown from our NIC. */ 1154 * or due to sporadic interrupts thrown from our NIC. */
1156 if (!inta) { 1155 if (!inta) {
1157 IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); 1156 IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n");
1158 goto none; 1157 /*
1158 * Re-enable interrupts here since we don't have anything to
1159 * service, but only in case the handler won't run. Note that
1160 * the handler can be scheduled because of a previous
1161 * interrupt.
1162 */
1163 if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
1164 !trans_pcie->inta)
1165 iwl_enable_interrupts(trans);
1166 return IRQ_NONE;
1159 } 1167 }
1160 1168
1161 if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) { 1169 if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
@@ -1173,19 +1181,7 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)
1173 1181
1174 trans_pcie->inta |= inta; 1182 trans_pcie->inta |= inta;
1175 /* the thread will service interrupts and re-enable them */ 1183 /* the thread will service interrupts and re-enable them */
1176 if (likely(inta)) 1184 return IRQ_WAKE_THREAD;
1177 return IRQ_WAKE_THREAD;
1178
1179 ret = IRQ_HANDLED;
1180
1181none:
1182 /* re-enable interrupts here since we don't have anything to service. */
1183 /* only Re-enable if disabled by irq and no schedules tasklet. */
1184 if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
1185 !trans_pcie->inta)
1186 iwl_enable_interrupts(trans);
1187
1188 return ret;
1189} 1185}
1190 1186
1191/* interrupt handler using ict table, with this interrupt driver will 1187/* interrupt handler using ict table, with this interrupt driver will
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 0adde919a258..a4ef5cc11100 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1542,30 +1542,24 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
1542 } 1542 }
1543 1543
1544 if (!ret) { 1544 if (!ret) {
1545 if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { 1545 struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue];
1546 struct iwl_txq *txq = 1546 struct iwl_queue *q = &txq->q;
1547 &trans_pcie->txq[trans_pcie->cmd_queue];
1548 struct iwl_queue *q = &txq->q;
1549 1547
1550 IWL_ERR(trans, 1548 IWL_ERR(trans, "Error sending %s: time out after %dms.\n",
1551 "Error sending %s: time out after %dms.\n", 1549 get_cmd_string(trans_pcie, cmd->id),
1552 get_cmd_string(trans_pcie, cmd->id), 1550 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
1553 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
1554 1551
1555 IWL_ERR(trans, 1552 IWL_ERR(trans, "Current CMD queue read_ptr %d write_ptr %d\n",
1556 "Current CMD queue read_ptr %d write_ptr %d\n", 1553 q->read_ptr, q->write_ptr);
1557 q->read_ptr, q->write_ptr);
1558 1554
1559 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); 1555 clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status);
1560 IWL_DEBUG_INFO(trans, 1556 IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
1561 "Clearing HCMD_ACTIVE for command %s\n", 1557 get_cmd_string(trans_pcie, cmd->id));
1562 get_cmd_string(trans_pcie, cmd->id)); 1558 ret = -ETIMEDOUT;
1563 ret = -ETIMEDOUT;
1564 1559
1565 iwl_nic_error(trans); 1560 iwl_nic_error(trans);
1566 1561
1567 goto cancel; 1562 goto cancel;
1568 }
1569 } 1563 }
1570 1564
1571 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) { 1565 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) {
@@ -1674,7 +1668,6 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1674 txq->entries[q->write_ptr].skb = skb; 1668 txq->entries[q->write_ptr].skb = skb;
1675 txq->entries[q->write_ptr].cmd = dev_cmd; 1669 txq->entries[q->write_ptr].cmd = dev_cmd;
1676 1670
1677 dev_cmd->hdr.cmd = REPLY_TX;
1678 dev_cmd->hdr.sequence = 1671 dev_cmd->hdr.sequence =
1679 cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | 1672 cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
1680 INDEX_TO_SEQ(q->write_ptr))); 1673 INDEX_TO_SEQ(q->write_ptr)));