aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig11
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h8
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/calib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/calib.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/commands.h3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/debugfs.c26
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c27
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c7
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rxon.c18
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/scan.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/sta.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/testmode.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c49
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c (renamed from drivers/net/wireless/iwlwifi/pcie/1000.c)1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c (renamed from drivers/net/wireless/iwlwifi/pcie/2000.c)1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c (renamed from drivers/net/wireless/iwlwifi/pcie/5000.c)1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c (renamed from drivers/net/wireless/iwlwifi/pcie/6000.c)1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c (renamed from drivers/net/wireless/iwlwifi/pcie/7000.c)63
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hw.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h49
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.h17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-read.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-read.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-notif-wait.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-notif-wait.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c51
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-op-mode.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.c27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-test.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-test.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-testmode.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h25
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/binding.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c589
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c371
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c257
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h319
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h53
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h66
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h101
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c168
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c75
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c129
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h66
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c145
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c66
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c9
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c117
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c50
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c39
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c105
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c50
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c32
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c4
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/cfg.h115
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c5
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h35
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c14
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c38
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c304
87 files changed, 2841 insertions, 1116 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index ba319cba3f1e..56c2040a955b 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -6,7 +6,6 @@ config IWLWIFI
6 select LEDS_CLASS 6 select LEDS_CLASS
7 select LEDS_TRIGGERS 7 select LEDS_TRIGGERS
8 select MAC80211_LEDS 8 select MAC80211_LEDS
9 select IWLDVM
10 ---help--- 9 ---help---
11 Select to build the driver supporting the: 10 Select to build the driver supporting the:
12 11
@@ -45,6 +44,7 @@ config IWLWIFI
45config IWLDVM 44config IWLDVM
46 tristate "Intel Wireless WiFi DVM Firmware support" 45 tristate "Intel Wireless WiFi DVM Firmware support"
47 depends on IWLWIFI 46 depends on IWLWIFI
47 default IWLWIFI
48 help 48 help
49 This is the driver supporting the DVM firmware which is 49 This is the driver supporting the DVM firmware which is
50 currently the only firmware available for existing devices. 50 currently the only firmware available for existing devices.
@@ -58,6 +58,15 @@ config IWLMVM
58 58
59 Say yes if you have such a device. 59 Say yes if you have such a device.
60 60
61# don't call it _MODULE -- will confuse Kconfig/fixdep/...
62config IWLWIFI_OPMODE_MODULAR
63 bool
64 default y if IWLDVM=m
65 default y if IWLMVM=m
66
67comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM"
68 depends on IWLWIFI && IWLDVM=n && IWLMVM=n
69
61menu "Debugging Options" 70menu "Debugging Options"
62 depends on IWLWIFI 71 depends on IWLWIFI
63 72
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 6c7800044a04..3b5613ea458b 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -7,8 +7,7 @@ iwlwifi-objs += iwl-notif-wait.o
7iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o 7iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o
8iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o 8iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o
9iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o 9iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o
10iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o 10iwlwifi-objs += iwl-1000.o iwl-2000.o iwl-5000.o iwl-6000.o iwl-7000.o
11iwlwifi-objs += pcie/7000.o
12 11
13iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 12iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
14iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o 13iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h
index 41ec27cb6efe..e575b9b0cda8 100644
--- a/drivers/net/wireless/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/iwlwifi/dvm/agn.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -73,6 +73,8 @@
73/* AUX (TX during scan dwell) queue */ 73/* AUX (TX during scan dwell) queue */
74#define IWL_AUX_QUEUE 10 74#define IWL_AUX_QUEUE 10
75 75
76#define IWL_INVALID_STATION 255
77
76/* device operations */ 78/* device operations */
77extern struct iwl_lib_ops iwl1000_lib; 79extern struct iwl_lib_ops iwl1000_lib;
78extern struct iwl_lib_ops iwl2000_lib; 80extern struct iwl_lib_ops iwl2000_lib;
@@ -176,7 +178,7 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr);
176/* lib */ 178/* lib */
177int iwlagn_send_tx_power(struct iwl_priv *priv); 179int iwlagn_send_tx_power(struct iwl_priv *priv);
178void iwlagn_temperature(struct iwl_priv *priv); 180void iwlagn_temperature(struct iwl_priv *priv);
179int iwlagn_txfifo_flush(struct iwl_priv *priv); 181int iwlagn_txfifo_flush(struct iwl_priv *priv, u32 scd_q_msk);
180void iwlagn_dev_txfifo_flush(struct iwl_priv *priv); 182void iwlagn_dev_txfifo_flush(struct iwl_priv *priv);
181int iwlagn_send_beacon_cmd(struct iwl_priv *priv); 183int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
182int iwl_send_statistics_request(struct iwl_priv *priv, 184int iwl_send_statistics_request(struct iwl_priv *priv,
@@ -210,6 +212,8 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
210 struct ieee80211_sta *sta, u16 tid, u8 buf_size); 212 struct ieee80211_sta *sta, u16 tid, u8 buf_size);
211int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, 213int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
212 struct ieee80211_sta *sta, u16 tid); 214 struct ieee80211_sta *sta, u16 tid);
215int iwlagn_tx_agg_flush(struct iwl_priv *priv, struct ieee80211_vif *vif,
216 struct ieee80211_sta *sta, u16 tid);
213int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, 217int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
214 struct iwl_rx_cmd_buffer *rxb, 218 struct iwl_rx_cmd_buffer *rxb,
215 struct iwl_device_cmd *cmd); 219 struct iwl_device_cmd *cmd);
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c
index 6468de8634b0..d6c4cf2ad7c5 100644
--- a/drivers/net/wireless/iwlwifi/dvm/calib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/calib.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.h b/drivers/net/wireless/iwlwifi/dvm/calib.h
index 65e920cab2b7..cfddde194940 100644
--- a/drivers/net/wireless/iwlwifi/dvm/calib.h
+++ b/drivers/net/wireless/iwlwifi/dvm/calib.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h
index 84e2c0fcfef6..95ca026ecc9d 100644
--- a/drivers/net/wireless/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/iwlwifi/dvm/commands.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -1526,6 +1526,7 @@ struct iwl_compressed_ba_resp {
1526 __le16 scd_ssn; 1526 __le16 scd_ssn;
1527 u8 txed; /* number of frames sent */ 1527 u8 txed; /* number of frames sent */
1528 u8 txed_2_done; /* number of frames acked */ 1528 u8 txed_2_done; /* number of frames acked */
1529 __le16 reserved1;
1529} __packed; 1530} __packed;
1530 1531
1531/* 1532/*
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
index 20806cae11b7..7b8178be119f 100644
--- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
@@ -19,7 +19,7 @@
19 * USA 19 * USA
20 * 20 *
21 * The full GNU General Public License is included in this distribution 21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL. 22 * in the file called COPYING.
23 * 23 *
24 * Contact Information: 24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com> 25 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -2324,6 +2324,28 @@ static ssize_t iwl_dbgfs_calib_disabled_write(struct file *file,
2324 return count; 2324 return count;
2325} 2325}
2326 2326
2327static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
2328 const char __user *user_buf,
2329 size_t count, loff_t *ppos)
2330{
2331 struct iwl_priv *priv = file->private_data;
2332 bool restart_fw = iwlwifi_mod_params.restart_fw;
2333 int ret;
2334
2335 iwlwifi_mod_params.restart_fw = true;
2336
2337 mutex_lock(&priv->mutex);
2338
2339 /* take the return value to make compiler happy - it will fail anyway */
2340 ret = iwl_dvm_send_cmd_pdu(priv, REPLY_ERROR, CMD_SYNC, 0, NULL);
2341
2342 mutex_unlock(&priv->mutex);
2343
2344 iwlwifi_mod_params.restart_fw = restart_fw;
2345
2346 return count;
2347}
2348
2327DEBUGFS_READ_FILE_OPS(ucode_rx_stats); 2349DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
2328DEBUGFS_READ_FILE_OPS(ucode_tx_stats); 2350DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
2329DEBUGFS_READ_FILE_OPS(ucode_general_stats); 2351DEBUGFS_READ_FILE_OPS(ucode_general_stats);
@@ -2343,6 +2365,7 @@ DEBUGFS_READ_FILE_OPS(bt_traffic);
2343DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); 2365DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
2344DEBUGFS_READ_FILE_OPS(reply_tx_error); 2366DEBUGFS_READ_FILE_OPS(reply_tx_error);
2345DEBUGFS_WRITE_FILE_OPS(echo_test); 2367DEBUGFS_WRITE_FILE_OPS(echo_test);
2368DEBUGFS_WRITE_FILE_OPS(fw_restart);
2346#ifdef CONFIG_IWLWIFI_DEBUG 2369#ifdef CONFIG_IWLWIFI_DEBUG
2347DEBUGFS_READ_WRITE_FILE_OPS(log_event); 2370DEBUGFS_READ_WRITE_FILE_OPS(log_event);
2348#endif 2371#endif
@@ -2400,6 +2423,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir)
2400 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); 2423 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
2401 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); 2424 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
2402 DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); 2425 DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR);
2426 DEBUGFS_ADD_FILE(fw_restart, dir_debug, S_IWUSR);
2403#ifdef CONFIG_IWLWIFI_DEBUG 2427#ifdef CONFIG_IWLWIFI_DEBUG
2404 DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); 2428 DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR);
2405#endif 2429#endif
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index 86ea5f4c3939..54f553380aa8 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -19,7 +19,7 @@
19 * USA 19 * USA
20 * 20 *
21 * The full GNU General Public License is included in this distribution 21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL. 22 * in the file called COPYING.
23 * 23 *
24 * Contact Information: 24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com> 25 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -136,7 +136,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
136 * 1. acquire mutex before calling 136 * 1. acquire mutex before calling
137 * 2. make sure rf is on and not in exit state 137 * 2. make sure rf is on and not in exit state
138 */ 138 */
139int iwlagn_txfifo_flush(struct iwl_priv *priv) 139int iwlagn_txfifo_flush(struct iwl_priv *priv, u32 scd_q_msk)
140{ 140{
141 struct iwl_txfifo_flush_cmd flush_cmd; 141 struct iwl_txfifo_flush_cmd flush_cmd;
142 struct iwl_host_cmd cmd = { 142 struct iwl_host_cmd cmd = {
@@ -162,6 +162,9 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv)
162 if (priv->nvm_data->sku_cap_11n_enable) 162 if (priv->nvm_data->sku_cap_11n_enable)
163 flush_cmd.queue_control |= IWL_AGG_TX_QUEUE_MSK; 163 flush_cmd.queue_control |= IWL_AGG_TX_QUEUE_MSK;
164 164
165 if (scd_q_msk)
166 flush_cmd.queue_control = cpu_to_le32(scd_q_msk);
167
165 IWL_DEBUG_INFO(priv, "queue control: 0x%x\n", 168 IWL_DEBUG_INFO(priv, "queue control: 0x%x\n",
166 flush_cmd.queue_control); 169 flush_cmd.queue_control);
167 flush_cmd.flush_control = cpu_to_le16(IWL_DROP_ALL); 170 flush_cmd.flush_control = cpu_to_le16(IWL_DROP_ALL);
@@ -173,7 +176,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv)
173{ 176{
174 mutex_lock(&priv->mutex); 177 mutex_lock(&priv->mutex);
175 ieee80211_stop_queues(priv->hw); 178 ieee80211_stop_queues(priv->hw);
176 if (iwlagn_txfifo_flush(priv)) { 179 if (iwlagn_txfifo_flush(priv, 0)) {
177 IWL_ERR(priv, "flush request fail\n"); 180 IWL_ERR(priv, "flush request fail\n");
178 goto done; 181 goto done;
179 } 182 }
@@ -1084,7 +1087,14 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan)
1084 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 1087 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
1085 struct iwlagn_wowlan_kek_kck_material_cmd kek_kck_cmd; 1088 struct iwlagn_wowlan_kek_kck_material_cmd kek_kck_cmd;
1086 struct iwlagn_wowlan_tkip_params_cmd tkip_cmd = {}; 1089 struct iwlagn_wowlan_tkip_params_cmd tkip_cmd = {};
1087 struct iwlagn_d3_config_cmd d3_cfg_cmd = {}; 1090 struct iwlagn_d3_config_cmd d3_cfg_cmd = {
1091 /*
1092 * Program the minimum sleep time to 10 seconds, as many
1093 * platforms have issues processing a wakeup signal while
1094 * still being in the process of suspending.
1095 */
1096 .min_sleep_time = cpu_to_le32(10 * 1000 * 1000),
1097 };
1088 struct wowlan_key_data key_data = { 1098 struct wowlan_key_data key_data = {
1089 .ctx = ctx, 1099 .ctx = ctx,
1090 .bssid = ctx->active.bssid_addr, 1100 .bssid = ctx->active.bssid_addr,
@@ -1262,6 +1272,15 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1262 } 1272 }
1263 1273
1264 /* 1274 /*
1275 * This can happen upon FW ASSERT: we clear the STATUS_FW_ERROR flag
1276 * in iwl_down but cancel the workers only later.
1277 */
1278 if (!priv->ucode_loaded) {
1279 IWL_ERR(priv, "Fw not loaded - dropping CMD: %x\n", cmd->id);
1280 return -EIO;
1281 }
1282
1283 /*
1265 * Synchronous commands from this op-mode must hold 1284 * Synchronous commands from this op-mode must hold
1266 * the mutex, this ensures we don't try to send two 1285 * the mutex, this ensures we don't try to send two
1267 * (or more) synchronous commands at a time. 1286 * (or more) synchronous commands at a time.
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 2dc101fe0d24..cab23af0be9e 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -777,9 +777,12 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
777 IWL_DEBUG_HT(priv, "start Tx\n"); 777 IWL_DEBUG_HT(priv, "start Tx\n");
778 ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); 778 ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn);
779 break; 779 break;
780 case IEEE80211_AMPDU_TX_STOP_CONT:
781 case IEEE80211_AMPDU_TX_STOP_FLUSH: 780 case IEEE80211_AMPDU_TX_STOP_FLUSH:
782 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: 781 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
782 IWL_DEBUG_HT(priv, "Flush Tx\n");
783 ret = iwlagn_tx_agg_flush(priv, vif, sta, tid);
784 break;
785 case IEEE80211_AMPDU_TX_STOP_CONT:
783 IWL_DEBUG_HT(priv, "stop Tx\n"); 786 IWL_DEBUG_HT(priv, "stop Tx\n");
784 ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); 787 ret = iwlagn_tx_agg_stop(priv, vif, sta, tid);
785 if ((ret == 0) && (priv->agg_tids_count > 0)) { 788 if ((ret == 0) && (priv->agg_tids_count > 0)) {
@@ -1132,7 +1135,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1132 */ 1135 */
1133 if (drop) { 1136 if (drop) {
1134 IWL_DEBUG_MAC80211(priv, "send flush command\n"); 1137 IWL_DEBUG_MAC80211(priv, "send flush command\n");
1135 if (iwlagn_txfifo_flush(priv)) { 1138 if (iwlagn_txfifo_flush(priv, 0)) {
1136 IWL_ERR(priv, "flush request fail\n"); 1139 IWL_ERR(priv, "flush request fail\n");
1137 goto done; 1140 goto done;
1138 } 1141 }
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c
index acbb50b5f1e8..707446fa00bd 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rxon.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c
@@ -1420,6 +1420,14 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
1420 1420
1421 mutex_lock(&priv->mutex); 1421 mutex_lock(&priv->mutex);
1422 1422
1423 if (changes & BSS_CHANGED_IDLE && bss_conf->idle) {
1424 /*
1425 * If we go idle, then clearly no "passive-no-rx"
1426 * workaround is needed any more, this is a reset.
1427 */
1428 iwlagn_lift_passive_no_rx(priv);
1429 }
1430
1423 if (unlikely(!iwl_is_ready(priv))) { 1431 if (unlikely(!iwl_is_ready(priv))) {
1424 IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); 1432 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
1425 mutex_unlock(&priv->mutex); 1433 mutex_unlock(&priv->mutex);
@@ -1451,16 +1459,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
1451 priv->timestamp = bss_conf->sync_tsf; 1459 priv->timestamp = bss_conf->sync_tsf;
1452 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; 1460 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
1453 } else { 1461 } else {
1454 /*
1455 * If we disassociate while there are pending
1456 * frames, just wake up the queues and let the
1457 * frames "escape" ... This shouldn't really
1458 * be happening to start with, but we should
1459 * not get stuck in this case either since it
1460 * can happen if userspace gets confused.
1461 */
1462 iwlagn_lift_passive_no_rx(priv);
1463
1464 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 1462 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1465 1463
1466 if (ctx->ctxid == IWL_RXON_CTX_BSS) 1464 if (ctx->ctxid == IWL_RXON_CTX_BSS)
diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c
index 3a4aa5239c45..d69b55866714 100644
--- a/drivers/net/wireless/iwlwifi/dvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/dvm/scan.c
@@ -19,7 +19,7 @@
19 * USA 19 * USA
20 * 20 *
21 * The full GNU General Public License is included in this distribution 21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL. 22 * in the file called COPYING.
23 * 23 *
24 * Contact Information: 24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com> 25 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c
index 94ef33838bc6..b775769f8322 100644
--- a/drivers/net/wireless/iwlwifi/dvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/dvm/sta.c
@@ -151,7 +151,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
151 sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : ""); 151 sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : "");
152 152
153 if (!(flags & CMD_ASYNC)) { 153 if (!(flags & CMD_ASYNC)) {
154 cmd.flags |= CMD_WANT_SKB | CMD_WANT_HCMD; 154 cmd.flags |= CMD_WANT_SKB;
155 might_sleep(); 155 might_sleep();
156 } 156 }
157 157
diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c
index dc6f965a123a..b89b9d9b9969 100644
--- a/drivers/net/wireless/iwlwifi/dvm/testmode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/testmode.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index d499a0366fa6..a900aaf47790 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -19,7 +19,7 @@
19 * USA 19 * USA
20 * 20 *
21 * The full GNU General Public License is included in this distribution 21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL. 22 * in the file called COPYING.
23 * 23 *
24 * Contact Information: 24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com> 25 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -674,6 +674,51 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
674 return ret; 674 return ret;
675} 675}
676 676
677int iwlagn_tx_agg_flush(struct iwl_priv *priv, struct ieee80211_vif *vif,
678 struct ieee80211_sta *sta, u16 tid)
679{
680 struct iwl_tid_data *tid_data;
681 enum iwl_agg_state agg_state;
682 int sta_id, txq_id;
683 sta_id = iwl_sta_id(sta);
684
685 /*
686 * First set the agg state to OFF to avoid calling
687 * ieee80211_stop_tx_ba_cb in iwlagn_check_ratid_empty.
688 */
689 spin_lock_bh(&priv->sta_lock);
690
691 tid_data = &priv->tid_data[sta_id][tid];
692 txq_id = tid_data->agg.txq_id;
693 agg_state = tid_data->agg.state;
694 IWL_DEBUG_TX_QUEUES(priv, "Flush AGG: sta %d tid %d q %d state %d\n",
695 sta_id, tid, txq_id, tid_data->agg.state);
696
697 tid_data->agg.state = IWL_AGG_OFF;
698
699 spin_unlock_bh(&priv->sta_lock);
700
701 if (iwlagn_txfifo_flush(priv, BIT(txq_id)))
702 IWL_ERR(priv, "Couldn't flush the AGG queue\n");
703
704 if (test_bit(txq_id, priv->agg_q_alloc)) {
705 /*
706 * If the transport didn't know that we wanted to start
707 * agreggation, don't tell it that we want to stop them.
708 * This can happen when we don't get the addBA response on
709 * time, or we hadn't time to drain the AC queues.
710 */
711 if (agg_state == IWL_AGG_ON)
712 iwl_trans_txq_disable(priv->trans, txq_id);
713 else
714 IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n",
715 agg_state);
716 iwlagn_dealloc_agg_txq(priv, txq_id);
717 }
718
719 return 0;
720}
721
677int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, 722int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
678 struct ieee80211_sta *sta, u16 tid, u8 buf_size) 723 struct ieee80211_sta *sta, u16 tid, u8 buf_size)
679{ 724{
@@ -1193,7 +1238,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
1193 memset(&info->status, 0, sizeof(info->status)); 1238 memset(&info->status, 0, sizeof(info->status));
1194 1239
1195 if (status == TX_STATUS_FAIL_PASSIVE_NO_RX && 1240 if (status == TX_STATUS_FAIL_PASSIVE_NO_RX &&
1196 iwl_is_associated_ctx(ctx) && ctx->vif && 1241 ctx->vif &&
1197 ctx->vif->type == NL80211_IFTYPE_STATION) { 1242 ctx->vif->type == NL80211_IFTYPE_STATION) {
1198 /* block and stop all queues */ 1243 /* block and stop all queues */
1199 priv->passive_no_rx = true; 1244 priv->passive_no_rx = true;
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index 736fe9bb140e..0a1cdc5e856b 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -19,7 +19,7 @@
19 * USA 19 * USA
20 * 20 *
21 * The full GNU General Public License is included in this distribution 21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL. 22 * in the file called COPYING.
23 * 23 *
24 * Contact Information: 24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com> 25 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -367,6 +367,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
367 return -EIO; 367 return -EIO;
368 } 368 }
369 369
370 priv->ucode_loaded = true;
371
370 if (ucode_type != IWL_UCODE_WOWLAN) { 372 if (ucode_type != IWL_UCODE_WOWLAN) {
371 /* delay a bit to give rfkill time to run */ 373 /* delay a bit to give rfkill time to run */
372 msleep(5); 374 msleep(5);
@@ -380,8 +382,6 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
380 return ret; 382 return ret;
381 } 383 }
382 384
383 priv->ucode_loaded = true;
384
385 return 0; 385 return 0;
386} 386}
387 387
diff --git a/drivers/net/wireless/iwlwifi/pcie/1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index ff3389757281..c080ae3070b2 100644
--- a/drivers/net/wireless/iwlwifi/pcie/1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -29,7 +29,6 @@
29#include "iwl-config.h" 29#include "iwl-config.h"
30#include "iwl-csr.h" 30#include "iwl-csr.h"
31#include "iwl-agn-hw.h" 31#include "iwl-agn-hw.h"
32#include "cfg.h"
33 32
34/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
35#define IWL1000_UCODE_API_MAX 5 34#define IWL1000_UCODE_API_MAX 5
diff --git a/drivers/net/wireless/iwlwifi/pcie/2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index e7de33128b16..a6ddd2f9fba0 100644
--- a/drivers/net/wireless/iwlwifi/pcie/2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -28,7 +28,6 @@
28#include <linux/stringify.h> 28#include <linux/stringify.h>
29#include "iwl-config.h" 29#include "iwl-config.h"
30#include "iwl-agn-hw.h" 30#include "iwl-agn-hw.h"
31#include "cfg.h"
32#include "dvm/commands.h" /* needed for BT for now */ 31#include "dvm/commands.h" /* needed for BT for now */
33 32
34/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
diff --git a/drivers/net/wireless/iwlwifi/pcie/5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 5096f7c96ab6..403f3f224bf6 100644
--- a/drivers/net/wireless/iwlwifi/pcie/5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -29,7 +29,6 @@
29#include "iwl-config.h" 29#include "iwl-config.h"
30#include "iwl-agn-hw.h" 30#include "iwl-agn-hw.h"
31#include "iwl-csr.h" 31#include "iwl-csr.h"
32#include "cfg.h"
33 32
34/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
35#define IWL5000_UCODE_API_MAX 5 34#define IWL5000_UCODE_API_MAX 5
diff --git a/drivers/net/wireless/iwlwifi/pcie/6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 801ff49796dd..b5ab8d1bcac0 100644
--- a/drivers/net/wireless/iwlwifi/pcie/6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -28,7 +28,6 @@
28#include <linux/stringify.h> 28#include <linux/stringify.h>
29#include "iwl-config.h" 29#include "iwl-config.h"
30#include "iwl-agn-hw.h" 30#include "iwl-agn-hw.h"
31#include "cfg.h"
32#include "dvm/commands.h" /* needed for BT for now */ 31#include "dvm/commands.h" /* needed for BT for now */
33 32
34/* Highest firmware API version supported */ 33/* Highest firmware API version supported */
diff --git a/drivers/net/wireless/iwlwifi/pcie/7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 6e35b2b72332..50263e87fe15 100644
--- a/drivers/net/wireless/iwlwifi/pcie/7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -1,34 +1,70 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. 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.
4 * 5 *
5 * This program is free software; you can redistribute it and/or modify it 6 * GPL LICENSE SUMMARY
6 * under the terms of version 2 of the GNU General Public License as 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
7 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
8 * 13 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT 14 * This program is distributed in the hope that it will be useful, but
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * more details. 17 * General Public License for more details.
13 * 18 *
14 * You should have received a copy of the GNU General Public License along with 19 * You should have received a copy of the GNU General Public License
15 * this program; if not, write to the Free Software Foundation, Inc., 20 * along with this program; if not, write to the Free Software
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
17 * 23 *
18 * The full GNU General Public License is included in this distribution in the 24 * The full GNU General Public License is included in this distribution
19 * file called LICENSE. 25 * in the file called COPYING.
20 * 26 *
21 * Contact Information: 27 * Contact Information:
22 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 * 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 *
25 *****************************************************************************/ 62 *****************************************************************************/
26 63
27#include <linux/module.h> 64#include <linux/module.h>
28#include <linux/stringify.h> 65#include <linux/stringify.h>
29#include "iwl-config.h" 66#include "iwl-config.h"
30#include "iwl-agn-hw.h" 67#include "iwl-agn-hw.h"
31#include "cfg.h"
32 68
33/* Highest firmware API version supported */ 69/* Highest firmware API version supported */
34#define IWL7260_UCODE_API_MAX 6 70#define IWL7260_UCODE_API_MAX 6
@@ -70,7 +106,6 @@ static const struct iwl_base_params iwl7000_base_params = {
70}; 106};
71 107
72static const struct iwl_ht_params iwl7000_ht_params = { 108static const struct iwl_ht_params iwl7000_ht_params = {
73 .ht_greenfield_support = true,
74 .use_rts_for_aggregation = true, /* use rts/cts protection */ 109 .use_rts_for_aggregation = true, /* use rts/cts protection */
75 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), 110 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
76}; 111};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
index e9975c54c276..6d73f943cefa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 743b48343358..c38aa8f77554 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -275,4 +275,51 @@ struct iwl_cfg {
275 const bool temp_offset_v2; 275 const bool temp_offset_v2;
276}; 276};
277 277
278/*
279 * This list declares the config structures for all devices.
280 */
281extern const struct iwl_cfg iwl5300_agn_cfg;
282extern const struct iwl_cfg iwl5100_agn_cfg;
283extern const struct iwl_cfg iwl5350_agn_cfg;
284extern const struct iwl_cfg iwl5100_bgn_cfg;
285extern const struct iwl_cfg iwl5100_abg_cfg;
286extern const struct iwl_cfg iwl5150_agn_cfg;
287extern const struct iwl_cfg iwl5150_abg_cfg;
288extern const struct iwl_cfg iwl6005_2agn_cfg;
289extern const struct iwl_cfg iwl6005_2abg_cfg;
290extern const struct iwl_cfg iwl6005_2bg_cfg;
291extern const struct iwl_cfg iwl6005_2agn_sff_cfg;
292extern const struct iwl_cfg iwl6005_2agn_d_cfg;
293extern const struct iwl_cfg iwl6005_2agn_mow1_cfg;
294extern const struct iwl_cfg iwl6005_2agn_mow2_cfg;
295extern const struct iwl_cfg iwl1030_bgn_cfg;
296extern const struct iwl_cfg iwl1030_bg_cfg;
297extern const struct iwl_cfg iwl6030_2agn_cfg;
298extern const struct iwl_cfg iwl6030_2abg_cfg;
299extern const struct iwl_cfg iwl6030_2bgn_cfg;
300extern const struct iwl_cfg iwl6030_2bg_cfg;
301extern const struct iwl_cfg iwl6000i_2agn_cfg;
302extern const struct iwl_cfg iwl6000i_2abg_cfg;
303extern const struct iwl_cfg iwl6000i_2bg_cfg;
304extern const struct iwl_cfg iwl6000_3agn_cfg;
305extern const struct iwl_cfg iwl6050_2agn_cfg;
306extern const struct iwl_cfg iwl6050_2abg_cfg;
307extern const struct iwl_cfg iwl6150_bgn_cfg;
308extern const struct iwl_cfg iwl6150_bg_cfg;
309extern const struct iwl_cfg iwl1000_bgn_cfg;
310extern const struct iwl_cfg iwl1000_bg_cfg;
311extern const struct iwl_cfg iwl100_bgn_cfg;
312extern const struct iwl_cfg iwl100_bg_cfg;
313extern const struct iwl_cfg iwl130_bgn_cfg;
314extern const struct iwl_cfg iwl130_bg_cfg;
315extern const struct iwl_cfg iwl2000_2bgn_cfg;
316extern const struct iwl_cfg iwl2000_2bgn_d_cfg;
317extern const struct iwl_cfg iwl2030_2bgn_cfg;
318extern const struct iwl_cfg iwl6035_2agn_cfg;
319extern const struct iwl_cfg iwl105_bgn_cfg;
320extern const struct iwl_cfg iwl105_bgn_d_cfg;
321extern const struct iwl_cfg iwl135_bgn_cfg;
322extern const struct iwl_cfg iwl7260_2ac_cfg;
323extern const struct iwl_cfg iwl3160_ac_cfg;
324
278#endif /* __IWL_CONFIG_H__ */ 325#endif /* __IWL_CONFIG_H__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index df3463a38704..20e845d4da04 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c
index 87535a67de76..8a44f594528d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -66,6 +66,7 @@
66#include <linux/device.h> 66#include <linux/device.h>
67#include <linux/interrupt.h> 67#include <linux/interrupt.h>
68#include <linux/export.h> 68#include <linux/export.h>
69#include "iwl-drv.h"
69#include "iwl-debug.h" 70#include "iwl-debug.h"
70#include "iwl-devtrace.h" 71#include "iwl-devtrace.h"
71 72
@@ -85,11 +86,11 @@ void __iwl_ ##fn(struct device *dev, const char *fmt, ...) \
85} 86}
86 87
87__iwl_fn(warn) 88__iwl_fn(warn)
88EXPORT_SYMBOL_GPL(__iwl_warn); 89IWL_EXPORT_SYMBOL(__iwl_warn);
89__iwl_fn(info) 90__iwl_fn(info)
90EXPORT_SYMBOL_GPL(__iwl_info); 91IWL_EXPORT_SYMBOL(__iwl_info);
91__iwl_fn(crit) 92__iwl_fn(crit)
92EXPORT_SYMBOL_GPL(__iwl_crit); 93IWL_EXPORT_SYMBOL(__iwl_crit);
93 94
94void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, 95void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only,
95 const char *fmt, ...) 96 const char *fmt, ...)
@@ -110,7 +111,7 @@ void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only,
110 trace_iwlwifi_err(&vaf); 111 trace_iwlwifi_err(&vaf);
111 va_end(args); 112 va_end(args);
112} 113}
113EXPORT_SYMBOL_GPL(__iwl_err); 114IWL_EXPORT_SYMBOL(__iwl_err);
114 115
115#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) 116#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
116void __iwl_dbg(struct device *dev, 117void __iwl_dbg(struct device *dev,
@@ -133,5 +134,5 @@ void __iwl_dbg(struct device *dev,
133 trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf); 134 trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf);
134 va_end(args); 135 va_end(args);
135} 136}
136EXPORT_SYMBOL_GPL(__iwl_dbg); 137IWL_EXPORT_SYMBOL(__iwl_dbg);
137#endif 138#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 9a0f45ec9e01..4491c1c72cc7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -298,7 +298,7 @@ TRACE_EVENT(iwlwifi_dbg,
298 MAX_MSG_LEN, vaf->fmt, 298 MAX_MSG_LEN, vaf->fmt,
299 *vaf->va) >= MAX_MSG_LEN); 299 *vaf->va) >= MAX_MSG_LEN);
300 ), 300 ),
301 TP_printk("%s", (char *)__get_dynamic_array(msg)) 301 TP_printk("%s", __get_str(msg))
302); 302);
303 303
304#undef TRACE_SYSTEM 304#undef TRACE_SYSTEM
@@ -349,25 +349,23 @@ TRACE_EVENT(iwlwifi_dev_rx_data,
349TRACE_EVENT(iwlwifi_dev_hcmd, 349TRACE_EVENT(iwlwifi_dev_hcmd,
350 TP_PROTO(const struct device *dev, 350 TP_PROTO(const struct device *dev,
351 struct iwl_host_cmd *cmd, u16 total_size, 351 struct iwl_host_cmd *cmd, u16 total_size,
352 const void *hdr, size_t hdr_len), 352 struct iwl_cmd_header *hdr),
353 TP_ARGS(dev, cmd, total_size, hdr, hdr_len), 353 TP_ARGS(dev, cmd, total_size, hdr),
354 TP_STRUCT__entry( 354 TP_STRUCT__entry(
355 DEV_ENTRY 355 DEV_ENTRY
356 __dynamic_array(u8, hcmd, total_size) 356 __dynamic_array(u8, hcmd, total_size)
357 __field(u32, flags) 357 __field(u32, flags)
358 ), 358 ),
359 TP_fast_assign( 359 TP_fast_assign(
360 int i, offset = hdr_len; 360 int i, offset = sizeof(*hdr);
361 361
362 DEV_ASSIGN; 362 DEV_ASSIGN;
363 __entry->flags = cmd->flags; 363 __entry->flags = cmd->flags;
364 memcpy(__get_dynamic_array(hcmd), hdr, hdr_len); 364 memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr));
365 365
366 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { 366 for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
367 if (!cmd->len[i]) 367 if (!cmd->len[i])
368 continue; 368 continue;
369 if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
370 continue;
371 memcpy((u8 *)__get_dynamic_array(hcmd) + offset, 369 memcpy((u8 *)__get_dynamic_array(hcmd) + offset,
372 cmd->data[i], cmd->len[i]); 370 cmd->data[i], cmd->len[i]);
373 offset += cmd->len[i]; 371 offset += cmd->len[i];
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 6f228bb2b844..39aad9893e0b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -912,8 +912,6 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
912 } 912 }
913 } 913 }
914 914
915 IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version);
916
917 /* 915 /*
918 * In mvm uCode there is no difference between data and instructions 916 * In mvm uCode there is no difference between data and instructions
919 * sections. 917 * sections.
@@ -970,6 +968,9 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
970 else 968 else
971 op = &iwlwifi_opmode_table[DVM_OP_MODE]; 969 op = &iwlwifi_opmode_table[DVM_OP_MODE];
972 970
971 IWL_INFO(drv, "loaded firmware version %s op_mode %s\n",
972 drv->fw.fw_version, op->name);
973
973 /* add this device to the list of devices using this op_mode */ 974 /* add this device to the list of devices using this op_mode */
974 list_add_tail(&drv->list, &op->drv); 975 list_add_tail(&drv->list, &op->drv);
975 976
@@ -997,8 +998,13 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
997 * else from proceeding if the module fails to load 998 * else from proceeding if the module fails to load
998 * or hangs loading. 999 * or hangs loading.
999 */ 1000 */
1000 if (load_module) 1001 if (load_module) {
1001 request_module("%s", op->name); 1002 err = request_module("%s", op->name);
1003 if (err)
1004 IWL_ERR(drv,
1005 "failed to load module %s (error %d), is dynamic loading enabled?\n",
1006 op->name, err);
1007 }
1002 return; 1008 return;
1003 1009
1004 try_again: 1010 try_again:
@@ -1102,8 +1108,7 @@ void iwl_drv_stop(struct iwl_drv *drv)
1102 1108
1103/* shared module parameters */ 1109/* shared module parameters */
1104struct iwl_mod_params iwlwifi_mod_params = { 1110struct iwl_mod_params iwlwifi_mod_params = {
1105 .amsdu_size_8K = 1, 1111 .restart_fw = true,
1106 .restart_fw = 1,
1107 .plcp_check = true, 1112 .plcp_check = true,
1108 .bt_coex_active = true, 1113 .bt_coex_active = true,
1109 .power_level = IWL_POWER_INDEX_1, 1114 .power_level = IWL_POWER_INDEX_1,
@@ -1112,7 +1117,7 @@ struct iwl_mod_params iwlwifi_mod_params = {
1112 .wd_disable = true, 1117 .wd_disable = true,
1113 /* the rest are 0 by default */ 1118 /* the rest are 0 by default */
1114}; 1119};
1115EXPORT_SYMBOL_GPL(iwlwifi_mod_params); 1120IWL_EXPORT_SYMBOL(iwlwifi_mod_params);
1116 1121
1117int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) 1122int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops)
1118{ 1123{
@@ -1136,7 +1141,7 @@ int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops)
1136 mutex_unlock(&iwlwifi_opmode_table_mtx); 1141 mutex_unlock(&iwlwifi_opmode_table_mtx);
1137 return -EIO; 1142 return -EIO;
1138} 1143}
1139EXPORT_SYMBOL_GPL(iwl_opmode_register); 1144IWL_EXPORT_SYMBOL(iwl_opmode_register);
1140 1145
1141void iwl_opmode_deregister(const char *name) 1146void iwl_opmode_deregister(const char *name)
1142{ 1147{
@@ -1158,7 +1163,7 @@ void iwl_opmode_deregister(const char *name)
1158 } 1163 }
1159 mutex_unlock(&iwlwifi_opmode_table_mtx); 1164 mutex_unlock(&iwlwifi_opmode_table_mtx);
1160} 1165}
1161EXPORT_SYMBOL_GPL(iwl_opmode_deregister); 1166IWL_EXPORT_SYMBOL(iwl_opmode_deregister);
1162 1167
1163static int __init iwl_drv_init(void) 1168static int __init iwl_drv_init(void)
1164{ 1169{
@@ -1207,9 +1212,9 @@ MODULE_PARM_DESC(11n_disable,
1207 "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); 1212 "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX");
1208module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, 1213module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K,
1209 int, S_IRUGO); 1214 int, S_IRUGO);
1210MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); 1215MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)");
1211module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO); 1216module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, bool, S_IRUGO);
1212MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); 1217MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)");
1213 1218
1214module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling, 1219module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling,
1215 int, S_IRUGO); 1220 int, S_IRUGO);
@@ -1267,7 +1272,3 @@ module_param_named(auto_agg, iwlwifi_mod_params.auto_agg,
1267 bool, S_IRUGO); 1272 bool, S_IRUGO);
1268MODULE_PARM_DESC(auto_agg, 1273MODULE_PARM_DESC(auto_agg,
1269 "enable agg w/o check traffic load (default: enable)"); 1274 "enable agg w/o check traffic load (default: enable)");
1270
1271module_param_named(5ghz_disable, iwlwifi_mod_params.disable_5ghz,
1272 bool, S_IRUGO);
1273MODULE_PARM_DESC(5ghz_disable, "disable 5GHz band (default: 0 [enabled])");
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h
index 594a5c71b272..7d1450916308 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.h
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -63,6 +63,8 @@
63#ifndef __iwl_drv_h__ 63#ifndef __iwl_drv_h__
64#define __iwl_drv_h__ 64#define __iwl_drv_h__
65 65
66#include <linux/module.h>
67
66/* for all modules */ 68/* for all modules */
67#define DRV_NAME "iwlwifi" 69#define DRV_NAME "iwlwifi"
68#define IWLWIFI_VERSION "in-tree:" 70#define IWLWIFI_VERSION "in-tree:"
@@ -123,4 +125,17 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans,
123 */ 125 */
124void iwl_drv_stop(struct iwl_drv *drv); 126void iwl_drv_stop(struct iwl_drv *drv);
125 127
128/*
129 * exported symbol management
130 *
131 * The driver can be split into multiple modules, in which case some symbols
132 * must be exported for the sub-modules. However, if it's not split and
133 * everything is built-in, then we can avoid that.
134 */
135#ifdef CONFIG_IWLWIFI_OPMODE_MODULAR
136#define IWL_EXPORT_SYMBOL(sym) EXPORT_SYMBOL_GPL(sym)
137#else
138#define IWL_EXPORT_SYMBOL(sym)
139#endif
140
126#endif /* __iwl_drv_h__ */ 141#endif /* __iwl_drv_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
index 034f2ff4f43d..600c9fdd7f71 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -62,6 +62,7 @@
62#include <linux/types.h> 62#include <linux/types.h>
63#include <linux/slab.h> 63#include <linux/slab.h>
64#include <linux/export.h> 64#include <linux/export.h>
65#include "iwl-drv.h"
65#include "iwl-modparams.h" 66#include "iwl-modparams.h"
66#include "iwl-eeprom-parse.h" 67#include "iwl-eeprom-parse.h"
67 68
@@ -749,7 +750,7 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
749 } 750 }
750 751
751 ht_info->ht_supported = true; 752 ht_info->ht_supported = true;
752 ht_info->cap = 0; 753 ht_info->cap = IEEE80211_HT_CAP_DSSSCCK40;
753 754
754 if (iwlwifi_mod_params.amsdu_size_8K) 755 if (iwlwifi_mod_params.amsdu_size_8K)
755 ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; 756 ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
@@ -909,7 +910,7 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
909 kfree(data); 910 kfree(data);
910 return NULL; 911 return NULL;
911} 912}
912EXPORT_SYMBOL_GPL(iwl_parse_eeprom_data); 913IWL_EXPORT_SYMBOL(iwl_parse_eeprom_data);
913 914
914/* helper functions */ 915/* helper functions */
915int iwl_nvm_check_version(struct iwl_nvm_data *data, 916int iwl_nvm_check_version(struct iwl_nvm_data *data,
@@ -928,4 +929,4 @@ int iwl_nvm_check_version(struct iwl_nvm_data *data,
928 data->calib_version, trans->cfg->nvm_calib_ver); 929 data->calib_version, trans->cfg->nvm_calib_ver);
929 return -EINVAL; 930 return -EINVAL;
930} 931}
931EXPORT_SYMBOL_GPL(iwl_nvm_check_version); 932IWL_EXPORT_SYMBOL(iwl_nvm_check_version);
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
index 683fe6a8c58f..37f115390b19 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
index ef4806f27cf8..e5f2e362ab0b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -63,6 +63,7 @@
63#include <linux/slab.h> 63#include <linux/slab.h>
64#include <linux/export.h> 64#include <linux/export.h>
65 65
66#include "iwl-drv.h"
66#include "iwl-debug.h" 67#include "iwl-debug.h"
67#include "iwl-eeprom-read.h" 68#include "iwl-eeprom-read.h"
68#include "iwl-io.h" 69#include "iwl-io.h"
@@ -460,4 +461,4 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size)
460 461
461 return ret; 462 return ret;
462} 463}
463EXPORT_SYMBOL_GPL(iwl_read_eeprom); 464IWL_EXPORT_SYMBOL(iwl_read_eeprom);
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
index b2588c5cbf93..8e941f8bd7d6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index f5592fb3b1ed..484d318245fb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index 90873eca35f7..8b6c6fd95ed0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index b545178e46e3..c4c446d41eb0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -73,12 +73,14 @@
73 * treats good CRC threshold as a boolean 73 * treats good CRC threshold as a boolean
74 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). 74 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
75 * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. 75 * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
76 * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS
76 */ 77 */
77enum iwl_ucode_tlv_flag { 78enum iwl_ucode_tlv_flag {
78 IWL_UCODE_TLV_FLAGS_PAN = BIT(0), 79 IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
79 IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), 80 IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1),
80 IWL_UCODE_TLV_FLAGS_MFP = BIT(2), 81 IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
81 IWL_UCODE_TLV_FLAGS_P2P = BIT(3), 82 IWL_UCODE_TLV_FLAGS_P2P = BIT(3),
83 IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4),
82}; 84};
83 85
84/* The default calibrate table size if not specified by firmware file */ 86/* The default calibrate table size if not specified by firmware file */
@@ -152,6 +154,19 @@ struct iwl_tlv_calib_ctrl {
152 __le32 event_trigger; 154 __le32 event_trigger;
153} __packed; 155} __packed;
154 156
157enum iwl_fw_phy_cfg {
158 FW_PHY_CFG_RADIO_TYPE_POS = 0,
159 FW_PHY_CFG_RADIO_TYPE = 0x3 << FW_PHY_CFG_RADIO_TYPE_POS,
160 FW_PHY_CFG_RADIO_STEP_POS = 2,
161 FW_PHY_CFG_RADIO_STEP = 0x3 << FW_PHY_CFG_RADIO_STEP_POS,
162 FW_PHY_CFG_RADIO_DASH_POS = 4,
163 FW_PHY_CFG_RADIO_DASH = 0x3 << FW_PHY_CFG_RADIO_DASH_POS,
164 FW_PHY_CFG_TX_CHAIN_POS = 16,
165 FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS,
166 FW_PHY_CFG_RX_CHAIN_POS = 20,
167 FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS,
168};
169
155/** 170/**
156 * struct iwl_fw - variables associated with the firmware 171 * struct iwl_fw - variables associated with the firmware
157 * 172 *
@@ -188,4 +203,16 @@ struct iwl_fw {
188 bool mvm_fw; 203 bool mvm_fw;
189}; 204};
190 205
206static inline u8 iwl_fw_valid_tx_ant(const struct iwl_fw *fw)
207{
208 return (fw->phy_config & FW_PHY_CFG_TX_CHAIN) >>
209 FW_PHY_CFG_TX_CHAIN_POS;
210}
211
212static inline u8 iwl_fw_valid_rx_ant(const struct iwl_fw *fw)
213{
214 return (fw->phy_config & FW_PHY_CFG_RX_CHAIN) >>
215 FW_PHY_CFG_RX_CHAIN_POS;
216}
217
191#endif /* __iwl_fw_h__ */ 218#endif /* __iwl_fw_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index 276410d82de4..305c81f2c2b4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -29,6 +29,7 @@
29#include <linux/device.h> 29#include <linux/device.h>
30#include <linux/export.h> 30#include <linux/export.h>
31 31
32#include "iwl-drv.h"
32#include "iwl-io.h" 33#include "iwl-io.h"
33#include "iwl-csr.h" 34#include "iwl-csr.h"
34#include "iwl-debug.h" 35#include "iwl-debug.h"
@@ -49,7 +50,7 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr,
49 50
50 return -ETIMEDOUT; 51 return -ETIMEDOUT;
51} 52}
52EXPORT_SYMBOL_GPL(iwl_poll_bit); 53IWL_EXPORT_SYMBOL(iwl_poll_bit);
53 54
54u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) 55u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
55{ 56{
@@ -62,7 +63,7 @@ u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
62 63
63 return value; 64 return value;
64} 65}
65EXPORT_SYMBOL_GPL(iwl_read_direct32); 66IWL_EXPORT_SYMBOL(iwl_read_direct32);
66 67
67void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) 68void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
68{ 69{
@@ -73,7 +74,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
73 iwl_trans_release_nic_access(trans, &flags); 74 iwl_trans_release_nic_access(trans, &flags);
74 } 75 }
75} 76}
76EXPORT_SYMBOL_GPL(iwl_write_direct32); 77IWL_EXPORT_SYMBOL(iwl_write_direct32);
77 78
78int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, 79int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
79 int timeout) 80 int timeout)
@@ -89,7 +90,7 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
89 90
90 return -ETIMEDOUT; 91 return -ETIMEDOUT;
91} 92}
92EXPORT_SYMBOL_GPL(iwl_poll_direct_bit); 93IWL_EXPORT_SYMBOL(iwl_poll_direct_bit);
93 94
94static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs) 95static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs)
95{ 96{
@@ -115,7 +116,7 @@ u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs)
115 } 116 }
116 return val; 117 return val;
117} 118}
118EXPORT_SYMBOL_GPL(iwl_read_prph); 119IWL_EXPORT_SYMBOL(iwl_read_prph);
119 120
120void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) 121void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
121{ 122{
@@ -126,7 +127,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
126 iwl_trans_release_nic_access(trans, &flags); 127 iwl_trans_release_nic_access(trans, &flags);
127 } 128 }
128} 129}
129EXPORT_SYMBOL_GPL(iwl_write_prph); 130IWL_EXPORT_SYMBOL(iwl_write_prph);
130 131
131void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) 132void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
132{ 133{
@@ -138,7 +139,7 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
138 iwl_trans_release_nic_access(trans, &flags); 139 iwl_trans_release_nic_access(trans, &flags);
139 } 140 }
140} 141}
141EXPORT_SYMBOL_GPL(iwl_set_bits_prph); 142IWL_EXPORT_SYMBOL(iwl_set_bits_prph);
142 143
143void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, 144void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
144 u32 bits, u32 mask) 145 u32 bits, u32 mask)
@@ -151,7 +152,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
151 iwl_trans_release_nic_access(trans, &flags); 152 iwl_trans_release_nic_access(trans, &flags);
152 } 153 }
153} 154}
154EXPORT_SYMBOL_GPL(iwl_set_bits_mask_prph); 155IWL_EXPORT_SYMBOL(iwl_set_bits_mask_prph);
155 156
156void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) 157void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
157{ 158{
@@ -164,4 +165,4 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
164 iwl_trans_release_nic_access(trans, &flags); 165 iwl_trans_release_nic_access(trans, &flags);
165 } 166 }
166} 167}
167EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); 168IWL_EXPORT_SYMBOL(iwl_clear_bits_prph);
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index e5e3a79eae2f..d6f6c37c09fd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -91,7 +91,7 @@ enum iwl_power_level {
91 * @sw_crypto: using hardware encryption, default = 0 91 * @sw_crypto: using hardware encryption, default = 0
92 * @disable_11n: disable 11n capabilities, default = 0, 92 * @disable_11n: disable 11n capabilities, default = 0,
93 * use IWL_DISABLE_HT_* constants 93 * use IWL_DISABLE_HT_* constants
94 * @amsdu_size_8K: enable 8K amsdu size, default = 1 94 * @amsdu_size_8K: enable 8K amsdu size, default = 0
95 * @restart_fw: restart firmware, default = 1 95 * @restart_fw: restart firmware, default = 1
96 * @plcp_check: enable plcp health check, default = true 96 * @plcp_check: enable plcp health check, default = true
97 * @wd_disable: enable stuck queue check, default = 0 97 * @wd_disable: enable stuck queue check, default = 0
@@ -103,13 +103,12 @@ enum iwl_power_level {
103 * @ant_coupling: antenna coupling in dB, default = 0 103 * @ant_coupling: antenna coupling in dB, default = 0
104 * @bt_ch_announce: BT channel inhibition, default = enable 104 * @bt_ch_announce: BT channel inhibition, default = enable
105 * @auto_agg: enable agg. without check, default = true 105 * @auto_agg: enable agg. without check, default = true
106 * @disable_5ghz: disable 5GHz capability, default = false
107 */ 106 */
108struct iwl_mod_params { 107struct iwl_mod_params {
109 int sw_crypto; 108 int sw_crypto;
110 unsigned int disable_11n; 109 unsigned int disable_11n;
111 int amsdu_size_8K; 110 int amsdu_size_8K;
112 int restart_fw; 111 bool restart_fw;
113 bool plcp_check; 112 bool plcp_check;
114 int wd_disable; 113 int wd_disable;
115 bool bt_coex_active; 114 bool bt_coex_active;
@@ -120,7 +119,6 @@ struct iwl_mod_params {
120 int ant_coupling; 119 int ant_coupling;
121 bool bt_ch_announce; 120 bool bt_ch_announce;
122 bool auto_agg; 121 bool auto_agg;
123 bool disable_5ghz;
124}; 122};
125 123
126#endif /* #__iwl_modparams_h__ */ 124#endif /* #__iwl_modparams_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
index c3affbc62cdf..940b8a9d5285 100644
--- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
+++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -63,6 +63,7 @@
63#include <linux/sched.h> 63#include <linux/sched.h>
64#include <linux/export.h> 64#include <linux/export.h>
65 65
66#include "iwl-drv.h"
66#include "iwl-notif-wait.h" 67#include "iwl-notif-wait.h"
67 68
68 69
@@ -72,7 +73,7 @@ void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait)
72 INIT_LIST_HEAD(&notif_wait->notif_waits); 73 INIT_LIST_HEAD(&notif_wait->notif_waits);
73 init_waitqueue_head(&notif_wait->notif_waitq); 74 init_waitqueue_head(&notif_wait->notif_waitq);
74} 75}
75EXPORT_SYMBOL_GPL(iwl_notification_wait_init); 76IWL_EXPORT_SYMBOL(iwl_notification_wait_init);
76 77
77void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, 78void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait,
78 struct iwl_rx_packet *pkt) 79 struct iwl_rx_packet *pkt)
@@ -117,7 +118,7 @@ void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait,
117 if (triggered) 118 if (triggered)
118 wake_up_all(&notif_wait->notif_waitq); 119 wake_up_all(&notif_wait->notif_waitq);
119} 120}
120EXPORT_SYMBOL_GPL(iwl_notification_wait_notify); 121IWL_EXPORT_SYMBOL(iwl_notification_wait_notify);
121 122
122void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) 123void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait)
123{ 124{
@@ -130,7 +131,7 @@ void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait)
130 131
131 wake_up_all(&notif_wait->notif_waitq); 132 wake_up_all(&notif_wait->notif_waitq);
132} 133}
133EXPORT_SYMBOL_GPL(iwl_abort_notification_waits); 134IWL_EXPORT_SYMBOL(iwl_abort_notification_waits);
134 135
135void 136void
136iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, 137iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait,
@@ -154,7 +155,7 @@ iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait,
154 list_add(&wait_entry->list, &notif_wait->notif_waits); 155 list_add(&wait_entry->list, &notif_wait->notif_waits);
155 spin_unlock_bh(&notif_wait->notif_wait_lock); 156 spin_unlock_bh(&notif_wait->notif_wait_lock);
156} 157}
157EXPORT_SYMBOL_GPL(iwl_init_notification_wait); 158IWL_EXPORT_SYMBOL(iwl_init_notification_wait);
158 159
159int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, 160int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
160 struct iwl_notification_wait *wait_entry, 161 struct iwl_notification_wait *wait_entry,
@@ -178,7 +179,7 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait,
178 return -ETIMEDOUT; 179 return -ETIMEDOUT;
179 return 0; 180 return 0;
180} 181}
181EXPORT_SYMBOL_GPL(iwl_wait_notification); 182IWL_EXPORT_SYMBOL(iwl_wait_notification);
182 183
183void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, 184void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait,
184 struct iwl_notification_wait *wait_entry) 185 struct iwl_notification_wait *wait_entry)
@@ -187,4 +188,4 @@ void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait,
187 list_del(&wait_entry->list); 188 list_del(&wait_entry->list);
188 spin_unlock_bh(&notif_wait->notif_wait_lock); 189 spin_unlock_bh(&notif_wait->notif_wait_lock);
189} 190}
190EXPORT_SYMBOL_GPL(iwl_remove_notification); 191IWL_EXPORT_SYMBOL(iwl_remove_notification);
diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
index c2ce764463a3..2e2f1c8c99f9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
+++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index a70213bdb83c..6199a0a597a6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -62,6 +62,7 @@
62#include <linux/types.h> 62#include <linux/types.h>
63#include <linux/slab.h> 63#include <linux/slab.h>
64#include <linux/export.h> 64#include <linux/export.h>
65#include "iwl-drv.h"
65#include "iwl-modparams.h" 66#include "iwl-modparams.h"
66#include "iwl-nvm-parse.h" 67#include "iwl-nvm-parse.h"
67 68
@@ -149,6 +150,8 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = {
149 * @NVM_CHANNEL_DFS: dynamic freq selection candidate 150 * @NVM_CHANNEL_DFS: dynamic freq selection candidate
150 * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?) 151 * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
151 * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?) 152 * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
153 * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
154 * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
152 */ 155 */
153enum iwl_nvm_channel_flags { 156enum iwl_nvm_channel_flags {
154 NVM_CHANNEL_VALID = BIT(0), 157 NVM_CHANNEL_VALID = BIT(0),
@@ -158,6 +161,8 @@ enum iwl_nvm_channel_flags {
158 NVM_CHANNEL_DFS = BIT(7), 161 NVM_CHANNEL_DFS = BIT(7),
159 NVM_CHANNEL_WIDE = BIT(8), 162 NVM_CHANNEL_WIDE = BIT(8),
160 NVM_CHANNEL_40MHZ = BIT(9), 163 NVM_CHANNEL_40MHZ = BIT(9),
164 NVM_CHANNEL_80MHZ = BIT(10),
165 NVM_CHANNEL_160MHZ = BIT(11),
161}; 166};
162 167
163#define CHECK_AND_PRINT_I(x) \ 168#define CHECK_AND_PRINT_I(x) \
@@ -210,6 +215,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
210 else 215 else
211 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; 216 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
212 } 217 }
218 if (!(ch_flags & NVM_CHANNEL_80MHZ))
219 channel->flags |= IEEE80211_CHAN_NO_80MHZ;
220 if (!(ch_flags & NVM_CHANNEL_160MHZ))
221 channel->flags |= IEEE80211_CHAN_NO_160MHZ;
213 222
214 if (!(ch_flags & NVM_CHANNEL_IBSS)) 223 if (!(ch_flags & NVM_CHANNEL_IBSS))
215 channel->flags |= IEEE80211_CHAN_NO_IBSS; 224 channel->flags |= IEEE80211_CHAN_NO_IBSS;
@@ -245,6 +254,43 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
245 return n_channels; 254 return n_channels;
246} 255}
247 256
257static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
258 struct iwl_nvm_data *data,
259 struct ieee80211_sta_vht_cap *vht_cap)
260{
261 /* For now, assume new devices with NVM are VHT capable */
262
263 vht_cap->vht_supported = true;
264
265 vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
266 IEEE80211_VHT_CAP_RXSTBC_1 |
267 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
268 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
269
270 if (iwlwifi_mod_params.amsdu_size_8K)
271 vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
272
273 vht_cap->vht_mcs.rx_mcs_map =
274 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
275 IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
276 IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
277 IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
278 IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
279 IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
280 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
281 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
282
283 if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) {
284 vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
285 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
286 /* this works because NOT_SUPPORTED == 3 */
287 vht_cap->vht_mcs.rx_mcs_map |=
288 cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2);
289 }
290
291 vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
292}
293
248static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, 294static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
249 struct iwl_nvm_data *data, const __le16 *nvm_sw) 295 struct iwl_nvm_data *data, const __le16 *nvm_sw)
250{ 296{
@@ -268,6 +314,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
268 n_used += iwl_init_sband_channels(data, sband, n_channels, 314 n_used += iwl_init_sband_channels(data, sband, n_channels,
269 IEEE80211_BAND_5GHZ); 315 IEEE80211_BAND_5GHZ);
270 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); 316 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ);
317 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap);
271 318
272 if (n_channels != n_used) 319 if (n_channels != n_used)
273 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n", 320 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
@@ -343,4 +390,4 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
343 390
344 return data; 391 return data;
345} 392}
346EXPORT_SYMBOL_GPL(iwl_parse_nvm_data); 393IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
index b2692bd287fa..e57fb989661e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
index 4a680019e117..98c7aa7346da 100644
--- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
index 14fc8d39fc28..25745daa0d5d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -65,6 +65,7 @@
65#include <linux/string.h> 65#include <linux/string.h>
66#include <linux/export.h> 66#include <linux/export.h>
67 67
68#include "iwl-drv.h"
68#include "iwl-phy-db.h" 69#include "iwl-phy-db.h"
69#include "iwl-debug.h" 70#include "iwl-debug.h"
70#include "iwl-op-mode.h" 71#include "iwl-op-mode.h"
@@ -136,12 +137,6 @@ struct iwl_calib_res_notif_phy_db {
136 u8 data[]; 137 u8 data[];
137} __packed; 138} __packed;
138 139
139#define IWL_PHY_DB_STATIC_PIC cpu_to_le32(0x21436587)
140static inline void iwl_phy_db_test_pic(__le32 pic)
141{
142 WARN_ON(IWL_PHY_DB_STATIC_PIC != pic);
143}
144
145struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans) 140struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans)
146{ 141{
147 struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db), 142 struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db),
@@ -155,7 +150,7 @@ struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans)
155 /* TODO: add default values of the phy db. */ 150 /* TODO: add default values of the phy db. */
156 return phy_db; 151 return phy_db;
157} 152}
158EXPORT_SYMBOL(iwl_phy_db_init); 153IWL_EXPORT_SYMBOL(iwl_phy_db_init);
159 154
160/* 155/*
161 * get phy db section: returns a pointer to a phy db section specified by 156 * get phy db section: returns a pointer to a phy db section specified by
@@ -221,7 +216,7 @@ void iwl_phy_db_free(struct iwl_phy_db *phy_db)
221 216
222 kfree(phy_db); 217 kfree(phy_db);
223} 218}
224EXPORT_SYMBOL(iwl_phy_db_free); 219IWL_EXPORT_SYMBOL(iwl_phy_db_free);
225 220
226int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt, 221int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt,
227 gfp_t alloc_ctx) 222 gfp_t alloc_ctx)
@@ -260,18 +255,13 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt,
260 (size - CHANNEL_NUM_SIZE) / phy_db->channel_num; 255 (size - CHANNEL_NUM_SIZE) / phy_db->channel_num;
261 } 256 }
262 257
263 /* Test PIC */
264 if (type != IWL_PHY_DB_CFG)
265 iwl_phy_db_test_pic(*(((__le32 *)phy_db_notif->data) +
266 (size / sizeof(__le32)) - 1));
267
268 IWL_DEBUG_INFO(phy_db->trans, 258 IWL_DEBUG_INFO(phy_db->trans,
269 "%s(%d): [PHYDB]SET: Type %d , Size: %d\n", 259 "%s(%d): [PHYDB]SET: Type %d , Size: %d\n",
270 __func__, __LINE__, type, size); 260 __func__, __LINE__, type, size);
271 261
272 return 0; 262 return 0;
273} 263}
274EXPORT_SYMBOL(iwl_phy_db_set_section); 264IWL_EXPORT_SYMBOL(iwl_phy_db_set_section);
275 265
276static int is_valid_channel(u16 ch_id) 266static int is_valid_channel(u16 ch_id)
277{ 267{
@@ -372,11 +362,6 @@ int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db,
372 *size = entry->size; 362 *size = entry->size;
373 } 363 }
374 364
375 /* Test PIC */
376 if (type != IWL_PHY_DB_CFG)
377 iwl_phy_db_test_pic(*(((__le32 *)*data) +
378 (*size / sizeof(__le32)) - 1));
379
380 IWL_DEBUG_INFO(phy_db->trans, 365 IWL_DEBUG_INFO(phy_db->trans,
381 "%s(%d): [PHYDB] GET: Type %d , Size: %d\n", 366 "%s(%d): [PHYDB] GET: Type %d , Size: %d\n",
382 __func__, __LINE__, type, *size); 367 __func__, __LINE__, type, *size);
@@ -511,4 +496,4 @@ int iwl_send_phy_db_data(struct iwl_phy_db *phy_db)
511 "Finished sending phy db non channel data\n"); 496 "Finished sending phy db non channel data\n");
512 return 0; 497 return 0;
513} 498}
514EXPORT_SYMBOL(iwl_send_phy_db_data); 499IWL_EXPORT_SYMBOL(iwl_send_phy_db_data);
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/iwlwifi/iwl-phy-db.h
index d0e43d96ab38..ce983af79644 100644
--- a/drivers/net/wireless/iwlwifi/iwl-phy-db.h
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index f76e9cad7757..386f2a7c87cb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c
index ce0c67b425ee..5cfd55b86ed3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-test.c
+++ b/drivers/net/wireless/iwlwifi/iwl-test.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -64,6 +64,7 @@
64#include <linux/export.h> 64#include <linux/export.h>
65#include <net/netlink.h> 65#include <net/netlink.h>
66 66
67#include "iwl-drv.h"
67#include "iwl-io.h" 68#include "iwl-io.h"
68#include "iwl-fh.h" 69#include "iwl-fh.h"
69#include "iwl-prph.h" 70#include "iwl-prph.h"
@@ -271,7 +272,7 @@ static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb)
271 272
272 reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; 273 reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
273 skb = iwl_test_alloc_reply(tst, reply_len + 20); 274 skb = iwl_test_alloc_reply(tst, reply_len + 20);
274 reply_buf = kmalloc(reply_len, GFP_KERNEL); 275 reply_buf = kmemdup(&pkt->hdr, reply_len, GFP_KERNEL);
275 if (!skb || !reply_buf) { 276 if (!skb || !reply_buf) {
276 kfree_skb(skb); 277 kfree_skb(skb);
277 kfree(reply_buf); 278 kfree(reply_buf);
@@ -279,7 +280,6 @@ static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb)
279 } 280 }
280 281
281 /* The reply is in a page, that we cannot send to user space. */ 282 /* The reply is in a page, that we cannot send to user space. */
282 memcpy(reply_buf, &(pkt->hdr), reply_len);
283 iwl_free_resp(&cmd); 283 iwl_free_resp(&cmd);
284 284
285 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, 285 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
@@ -653,7 +653,7 @@ int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb,
653 } 653 }
654 return 0; 654 return 0;
655} 655}
656EXPORT_SYMBOL_GPL(iwl_test_parse); 656IWL_EXPORT_SYMBOL(iwl_test_parse);
657 657
658/* 658/*
659 * Handle test commands. 659 * Handle test commands.
@@ -715,7 +715,7 @@ int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb)
715 } 715 }
716 return result; 716 return result;
717} 717}
718EXPORT_SYMBOL_GPL(iwl_test_handle_cmd); 718IWL_EXPORT_SYMBOL(iwl_test_handle_cmd);
719 719
720static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb, 720static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb,
721 struct netlink_callback *cb) 721 struct netlink_callback *cb)
@@ -803,7 +803,7 @@ int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb,
803 } 803 }
804 return result; 804 return result;
805} 805}
806EXPORT_SYMBOL_GPL(iwl_test_dump); 806IWL_EXPORT_SYMBOL(iwl_test_dump);
807 807
808/* 808/*
809 * Multicast a spontaneous messages from the device to the user space. 809 * Multicast a spontaneous messages from the device to the user space.
@@ -849,4 +849,4 @@ void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb)
849 if (tst->notify) 849 if (tst->notify)
850 iwl_test_send_rx(tst, rxb); 850 iwl_test_send_rx(tst, rxb);
851} 851}
852EXPORT_SYMBOL_GPL(iwl_test_rx); 852IWL_EXPORT_SYMBOL(iwl_test_rx);
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.h b/drivers/net/wireless/iwlwifi/iwl-test.h
index 7fbf4d717caa..8fbd21704840 100644
--- a/drivers/net/wireless/iwlwifi/iwl-test.h
+++ b/drivers/net/wireless/iwlwifi/iwl-test.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h
index a963f45c6849..98f48a9afc98 100644
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 00bdc5b00af3..7a13790b5bfe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -183,19 +183,13 @@ struct iwl_rx_packet {
183 * @CMD_ASYNC: Return right away and don't want for the response 183 * @CMD_ASYNC: Return right away and don't want for the response
184 * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the 184 * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the
185 * response. The caller needs to call iwl_free_resp when done. 185 * response. The caller needs to call iwl_free_resp when done.
186 * @CMD_WANT_HCMD: The caller needs to get the HCMD that was sent in the
187 * response handler. Chunks flagged by %IWL_HCMD_DFL_NOCOPY won't be
188 * copied. The pointer passed to the response handler is in the transport
189 * ownership and don't need to be freed by the op_mode. This also means
190 * that the pointer is invalidated after the op_mode's handler returns.
191 * @CMD_ON_DEMAND: This command is sent by the test mode pipe. 186 * @CMD_ON_DEMAND: This command is sent by the test mode pipe.
192 */ 187 */
193enum CMD_MODE { 188enum CMD_MODE {
194 CMD_SYNC = 0, 189 CMD_SYNC = 0,
195 CMD_ASYNC = BIT(0), 190 CMD_ASYNC = BIT(0),
196 CMD_WANT_SKB = BIT(1), 191 CMD_WANT_SKB = BIT(1),
197 CMD_WANT_HCMD = BIT(2), 192 CMD_ON_DEMAND = BIT(2),
198 CMD_ON_DEMAND = BIT(3),
199}; 193};
200 194
201#define DEF_CMD_PAYLOAD_SIZE 320 195#define DEF_CMD_PAYLOAD_SIZE 320
@@ -214,7 +208,11 @@ struct iwl_device_cmd {
214 208
215#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) 209#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
216 210
217#define IWL_MAX_CMD_TFDS 2 211/*
212 * number of transfer buffers (fragments) per transmit frame descriptor;
213 * this is just the driver's idea, the hardware supports 20
214 */
215#define IWL_MAX_CMD_TBS_PER_TFD 2
218 216
219/** 217/**
220 * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command 218 * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command
@@ -251,15 +249,15 @@ enum iwl_hcmd_dataflag {
251 * @id: id of the host command 249 * @id: id of the host command
252 */ 250 */
253struct iwl_host_cmd { 251struct iwl_host_cmd {
254 const void *data[IWL_MAX_CMD_TFDS]; 252 const void *data[IWL_MAX_CMD_TBS_PER_TFD];
255 struct iwl_rx_packet *resp_pkt; 253 struct iwl_rx_packet *resp_pkt;
256 unsigned long _rx_page_addr; 254 unsigned long _rx_page_addr;
257 u32 _rx_page_order; 255 u32 _rx_page_order;
258 int handler_status; 256 int handler_status;
259 257
260 u32 flags; 258 u32 flags;
261 u16 len[IWL_MAX_CMD_TFDS]; 259 u16 len[IWL_MAX_CMD_TBS_PER_TFD];
262 u8 dataflags[IWL_MAX_CMD_TFDS]; 260 u8 dataflags[IWL_MAX_CMD_TBS_PER_TFD];
263 u8 id; 261 u8 id;
264}; 262};
265 263
@@ -307,7 +305,6 @@ static inline void iwl_free_rxb(struct iwl_rx_cmd_buffer *r)
307 * currently supports 305 * currently supports
308 */ 306 */
309#define IWL_MAX_HW_QUEUES 32 307#define IWL_MAX_HW_QUEUES 32
310#define IWL_INVALID_STATION 255
311#define IWL_MAX_TID_COUNT 8 308#define IWL_MAX_TID_COUNT 8
312#define IWL_FRAME_LIMIT 64 309#define IWL_FRAME_LIMIT 64
313 310
@@ -684,7 +681,7 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
684static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, 681static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue,
685 int fifo) 682 int fifo)
686{ 683{
687 iwl_trans_txq_enable(trans, queue, fifo, IWL_INVALID_STATION, 684 iwl_trans_txq_enable(trans, queue, fifo, -1,
688 IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0); 685 IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0);
689} 686}
690 687
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index 807b250ec396..2acc44b40986 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_IWLMVM) += iwlmvm.o
2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o 2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o 3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o
4iwlmvm-y += scan.o time-event.o rs.o 4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o 5iwlmvm-y += power.o bt-coex.o
6iwlmvm-y += led.o 6iwlmvm-y += led.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o 7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o 8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
diff --git a/drivers/net/wireless/iwlwifi/mvm/binding.c b/drivers/net/wireless/iwlwifi/mvm/binding.c
index 73d24aacb90a..93fd1457954b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/binding.c
+++ b/drivers/net/wireless/iwlwifi/mvm/binding.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
new file mode 100644
index 000000000000..810bfa5f6de0
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -0,0 +1,589 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2013 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#include <net/mac80211.h>
65
66#include "fw-api-bt-coex.h"
67#include "iwl-modparams.h"
68#include "mvm.h"
69#include "iwl-debug.h"
70
71#define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \
72 [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \
73 ((_shrd_ant) << BT_COEX_PRIO_TBL_SHRD_ANT_POS))
74
75static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
76 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB1,
77 BT_COEX_PRIO_TBL_PRIO_BYPASS, 0),
78 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB2,
79 BT_COEX_PRIO_TBL_PRIO_BYPASS, 1),
80 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1,
81 BT_COEX_PRIO_TBL_PRIO_LOW, 0),
82 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2,
83 BT_COEX_PRIO_TBL_PRIO_LOW, 1),
84 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1,
85 BT_COEX_PRIO_TBL_PRIO_HIGH, 0),
86 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2,
87 BT_COEX_PRIO_TBL_PRIO_HIGH, 1),
88 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_DTIM,
89 BT_COEX_PRIO_TBL_DISABLED, 0),
90 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN52,
91 BT_COEX_PRIO_TBL_PRIO_COEX_OFF, 0),
92 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN24,
93 BT_COEX_PRIO_TBL_PRIO_COEX_ON, 0),
94 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_IDLE,
95 BT_COEX_PRIO_TBL_PRIO_COEX_IDLE, 0),
96 0, 0, 0, 0, 0, 0,
97};
98
99#undef EVENT_PRIO_ANT
100
101/* BT Antenna Coupling Threshold (dB) */
102#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35)
103#define IWL_BT_LOAD_FORCE_SISO_THRESHOLD (3)
104
105#define BT_ENABLE_REDUCED_TXPOWER_THRESHOLD (-62)
106#define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65)
107#define BT_REDUCED_TX_POWER_BIT BIT(7)
108
109static inline bool is_loose_coex(void)
110{
111 return iwlwifi_mod_params.ant_coupling >
112 IWL_BT_ANTENNA_COUPLING_THRESHOLD;
113}
114
115int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm)
116{
117 return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC,
118 sizeof(struct iwl_bt_coex_prio_tbl_cmd),
119 &iwl_bt_prio_tbl);
120}
121
122static int iwl_send_bt_env(struct iwl_mvm *mvm, u8 action, u8 type)
123{
124 struct iwl_bt_coex_prot_env_cmd env_cmd;
125 int ret;
126
127 env_cmd.action = action;
128 env_cmd.type = type;
129 ret = iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PROT_ENV, CMD_SYNC,
130 sizeof(env_cmd), &env_cmd);
131 if (ret)
132 IWL_ERR(mvm, "failed to send BT env command\n");
133 return ret;
134}
135
136enum iwl_bt_kill_msk {
137 BT_KILL_MSK_DEFAULT,
138 BT_KILL_MSK_SCO_HID_A2DP,
139 BT_KILL_MSK_REDUCED_TXPOW,
140 BT_KILL_MSK_MAX,
141};
142
143static const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = {
144 [BT_KILL_MSK_DEFAULT] = 0xffff0000,
145 [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff,
146 [BT_KILL_MSK_REDUCED_TXPOW] = 0,
147};
148
149static const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = {
150 [BT_KILL_MSK_DEFAULT] = 0xffff0000,
151 [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff,
152 [BT_KILL_MSK_REDUCED_TXPOW] = 0,
153};
154
155#define IWL_BT_DEFAULT_BOOST (0xf0f0f0f0)
156
157/* Tight Coex */
158static const __le32 iwl_tight_lookup[BT_COEX_LUT_SIZE] = {
159 cpu_to_le32(0xaaaaaaaa),
160 cpu_to_le32(0xaaaaaaaa),
161 cpu_to_le32(0xaeaaaaaa),
162 cpu_to_le32(0xaaaaaaaa),
163 cpu_to_le32(0xcc00ff28),
164 cpu_to_le32(0x0000aaaa),
165 cpu_to_le32(0xcc00aaaa),
166 cpu_to_le32(0x0000aaaa),
167 cpu_to_le32(0xc0004000),
168 cpu_to_le32(0x00000000),
169 cpu_to_le32(0xf0005000),
170 cpu_to_le32(0xf0005000),
171};
172
173/* Loose Coex */
174static const __le32 iwl_loose_lookup[BT_COEX_LUT_SIZE] = {
175 cpu_to_le32(0xaaaaaaaa),
176 cpu_to_le32(0xaaaaaaaa),
177 cpu_to_le32(0xaeaaaaaa),
178 cpu_to_le32(0xaaaaaaaa),
179 cpu_to_le32(0xcc00ff28),
180 cpu_to_le32(0x0000aaaa),
181 cpu_to_le32(0xcc00aaaa),
182 cpu_to_le32(0x0000aaaa),
183 cpu_to_le32(0x00000000),
184 cpu_to_le32(0x00000000),
185 cpu_to_le32(0xf0005000),
186 cpu_to_le32(0xf0005000),
187};
188
189/* Full concurrency */
190static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = {
191 cpu_to_le32(0xaaaaaaaa),
192 cpu_to_le32(0xaaaaaaaa),
193 cpu_to_le32(0xaaaaaaaa),
194 cpu_to_le32(0xaaaaaaaa),
195 cpu_to_le32(0xaaaaaaaa),
196 cpu_to_le32(0xaaaaaaaa),
197 cpu_to_le32(0xaaaaaaaa),
198 cpu_to_le32(0xaaaaaaaa),
199 cpu_to_le32(0x00000000),
200 cpu_to_le32(0x00000000),
201 cpu_to_le32(0x00000000),
202 cpu_to_le32(0x00000000),
203};
204
205int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
206{
207 struct iwl_bt_coex_cmd cmd = {
208 .max_kill = 5,
209 .bt3_time_t7_value = 1,
210 .bt3_prio_sample_time = 2,
211 .bt3_timer_t2_value = 0xc,
212 };
213 int ret;
214
215 cmd.flags = iwlwifi_mod_params.bt_coex_active ?
216 BT_COEX_NW : BT_COEX_DISABLE;
217 cmd.flags |= BT_CH_PRIMARY_EN | BT_SYNC_2_BT_DISABLE;
218
219 cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE |
220 BT_VALID_BT_PRIO_BOOST |
221 BT_VALID_MAX_KILL |
222 BT_VALID_3W_TMRS |
223 BT_VALID_KILL_ACK |
224 BT_VALID_KILL_CTS |
225 BT_VALID_REDUCED_TX_POWER |
226 BT_VALID_LUT);
227
228 if (is_loose_coex())
229 memcpy(&cmd.decision_lut, iwl_loose_lookup,
230 sizeof(iwl_tight_lookup));
231 else
232 memcpy(&cmd.decision_lut, iwl_tight_lookup,
233 sizeof(iwl_tight_lookup));
234
235 cmd.bt_prio_boost = cpu_to_le32(IWL_BT_DEFAULT_BOOST);
236 cmd.kill_ack_msk =
237 cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]);
238 cmd.kill_cts_msk =
239 cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]);
240
241 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
242
243 /* go to CALIB state in internal BT-Coex state machine */
244 ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN,
245 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
246 if (ret)
247 return ret;
248
249 ret = iwl_send_bt_env(mvm, BT_COEX_ENV_CLOSE,
250 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
251 if (ret)
252 return ret;
253
254 return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC,
255 sizeof(cmd), &cmd);
256}
257
258static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm,
259 bool reduced_tx_power)
260{
261 enum iwl_bt_kill_msk bt_kill_msk;
262 struct iwl_bt_coex_cmd cmd = {};
263 struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif;
264
265 lockdep_assert_held(&mvm->mutex);
266
267 if (reduced_tx_power) {
268 /* Reduced Tx power has precedence on the type of the profile */
269 bt_kill_msk = BT_KILL_MSK_REDUCED_TXPOW;
270 } else {
271 /* Low latency BT profile is active: give higher prio to BT */
272 if (BT_MBOX_MSG(notif, 3, SCO_STATE) ||
273 BT_MBOX_MSG(notif, 3, A2DP_STATE) ||
274 BT_MBOX_MSG(notif, 3, SNIFF_STATE))
275 bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP;
276 else
277 bt_kill_msk = BT_KILL_MSK_DEFAULT;
278 }
279
280 IWL_DEBUG_COEX(mvm,
281 "Update kill_msk: %d - SCO %sactive A2DP %sactive SNIFF %sactive\n",
282 bt_kill_msk,
283 BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in",
284 BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in",
285 BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in");
286
287 /* Don't send HCMD if there is no update */
288 if (bt_kill_msk == mvm->bt_kill_msk)
289 return 0;
290
291 mvm->bt_kill_msk = bt_kill_msk;
292 cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]);
293 cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]);
294 cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS);
295
296 IWL_DEBUG_COEX(mvm, "bt_kill_msk = %d\n", bt_kill_msk);
297 return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC,
298 sizeof(cmd), &cmd);
299}
300
301static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
302 bool enable)
303{
304 struct iwl_bt_coex_cmd cmd = {
305 .valid_bit_msk = cpu_to_le16(BT_VALID_REDUCED_TX_POWER),
306 .bt_reduced_tx_power = sta_id,
307 };
308 struct ieee80211_sta *sta;
309 struct iwl_mvm_sta *mvmsta;
310
311 /* This can happen if the station has been removed right now */
312 if (sta_id == IWL_MVM_STATION_COUNT)
313 return 0;
314
315 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
316 lockdep_is_held(&mvm->mutex));
317 mvmsta = (void *)sta->drv_priv;
318
319 /* nothing to do */
320 if (mvmsta->bt_reduced_txpower == enable)
321 return 0;
322
323 if (enable)
324 cmd.bt_reduced_tx_power |= BT_REDUCED_TX_POWER_BIT;
325
326 IWL_DEBUG_COEX(mvm, "%sable reduced Tx Power for sta %d\n",
327 enable ? "en" : "dis", sta_id);
328
329 mvmsta->bt_reduced_txpower = enable;
330
331 /* Send ASYNC since this can be sent from an atomic context */
332 return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_ASYNC,
333 sizeof(cmd), &cmd);
334}
335
336struct iwl_bt_iterator_data {
337 struct iwl_bt_coex_profile_notif *notif;
338 struct iwl_mvm *mvm;
339 u32 num_bss_ifaces;
340 bool reduced_tx_power;
341};
342
343static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
344 struct ieee80211_vif *vif)
345{
346 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
347 struct iwl_bt_iterator_data *data = _data;
348 struct iwl_mvm *mvm = data->mvm;
349 struct ieee80211_chanctx_conf *chanctx_conf;
350 enum ieee80211_smps_mode smps_mode;
351 enum ieee80211_band band;
352 int ave_rssi;
353
354 if (vif->type != NL80211_IFTYPE_STATION)
355 return;
356
357 rcu_read_lock();
358 chanctx_conf = rcu_dereference(vif->chanctx_conf);
359 if (chanctx_conf && chanctx_conf->def.chan)
360 band = chanctx_conf->def.chan->band;
361 else
362 band = -1;
363 rcu_read_unlock();
364
365 smps_mode = IEEE80211_SMPS_AUTOMATIC;
366
367 if (band != IEEE80211_BAND_2GHZ) {
368 ieee80211_request_smps(vif, smps_mode);
369 return;
370 }
371
372 if (data->notif->bt_status)
373 smps_mode = IEEE80211_SMPS_DYNAMIC;
374
375 if (data->notif->bt_traffic_load >= IWL_BT_LOAD_FORCE_SISO_THRESHOLD)
376 smps_mode = IEEE80211_SMPS_STATIC;
377
378 IWL_DEBUG_COEX(data->mvm,
379 "mac %d: bt_status %d traffic_load %d smps_req %d\n",
380 mvmvif->id, data->notif->bt_status,
381 data->notif->bt_traffic_load, smps_mode);
382
383 ieee80211_request_smps(vif, smps_mode);
384
385 /* don't reduce the Tx power if in loose scheme */
386 if (is_loose_coex())
387 return;
388
389 data->num_bss_ifaces++;
390
391 /* reduced Txpower only if there are open BT connections, so ...*/
392 if (!BT_MBOX_MSG(data->notif, 3, OPEN_CON_2)) {
393 /* ... cancel reduced Tx power ... */
394 if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false))
395 IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
396 data->reduced_tx_power = false;
397
398 /* ... and there is no need to get reports on RSSI any more. */
399 ieee80211_disable_rssi_reports(vif);
400 return;
401 }
402
403 ave_rssi = ieee80211_ave_rssi(vif);
404
405 /* if the RSSI isn't valid, fake it is very low */
406 if (!ave_rssi)
407 ave_rssi = -100;
408 if (ave_rssi > BT_ENABLE_REDUCED_TXPOWER_THRESHOLD) {
409 if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true))
410 IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
411
412 /*
413 * bt_kill_msk can be BT_KILL_MSK_REDUCED_TXPOW only if all the
414 * BSS / P2P clients have rssi above threshold.
415 * We set the bt_kill_msk to BT_KILL_MSK_REDUCED_TXPOW before
416 * the iteration, if one interface's rssi isn't good enough,
417 * bt_kill_msk will be set to default values.
418 */
419 } else if (ave_rssi < BT_DISABLE_REDUCED_TXPOWER_THRESHOLD) {
420 if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false))
421 IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
422
423 /*
424 * One interface hasn't rssi above threshold, bt_kill_msk must
425 * be set to default values.
426 */
427 data->reduced_tx_power = false;
428 }
429
430 /* Begin to monitor the RSSI: it may influence the reduced Tx power */
431 ieee80211_enable_rssi_reports(vif, BT_DISABLE_REDUCED_TXPOWER_THRESHOLD,
432 BT_ENABLE_REDUCED_TXPOWER_THRESHOLD);
433}
434
435static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
436{
437 struct iwl_bt_iterator_data data = {
438 .mvm = mvm,
439 .notif = &mvm->last_bt_notif,
440 .reduced_tx_power = true,
441 };
442
443 ieee80211_iterate_active_interfaces_atomic(
444 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
445 iwl_mvm_bt_notif_iterator, &data);
446
447 /*
448 * If there are no BSS / P2P client interfaces, reduced Tx Power is
449 * irrelevant since it is based on the RSSI coming from the beacon.
450 * Use BT_KILL_MSK_DEFAULT in that case.
451 */
452 data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces;
453
454 if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power))
455 IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
456}
457
458/* upon association, the fw will send in BT Coex notification */
459int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
460 struct iwl_rx_cmd_buffer *rxb,
461 struct iwl_device_cmd *dev_cmd)
462{
463 struct iwl_rx_packet *pkt = rxb_addr(rxb);
464 struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data;
465
466
467 IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
468 IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not ");
469 IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn);
470 IWL_DEBUG_COEX(mvm, "\tBT traffic load %d\n", notif->bt_traffic_load);
471 IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n",
472 notif->bt_agg_traffic_load);
473 IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
474
475 /* remember this notification for future use: rssi fluctuations */
476 memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif));
477
478 iwl_mvm_bt_coex_notif_handle(mvm);
479
480 /*
481 * This is an async handler for a notification, returning anything other
482 * than 0 doesn't make sense even if HCMD failed.
483 */
484 return 0;
485}
486
487static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
488 struct ieee80211_vif *vif)
489{
490 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
491 struct iwl_bt_iterator_data *data = _data;
492 struct iwl_mvm *mvm = data->mvm;
493
494 struct ieee80211_sta *sta;
495 struct iwl_mvm_sta *mvmsta;
496
497 if (vif->type != NL80211_IFTYPE_STATION ||
498 mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)
499 return;
500
501 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
502 lockdep_is_held(&mvm->mutex));
503 mvmsta = (void *)sta->drv_priv;
504
505 /*
506 * This interface doesn't support reduced Tx power (because of low
507 * RSSI probably), then set bt_kill_msk to default values.
508 */
509 if (!mvmsta->bt_reduced_txpower)
510 data->reduced_tx_power = false;
511 /* else - possibly leave it to BT_KILL_MSK_REDUCED_TXPOW */
512}
513
514void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
515 enum ieee80211_rssi_event rssi_event)
516{
517 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
518 struct iwl_bt_iterator_data data = {
519 .mvm = mvm,
520 .reduced_tx_power = true,
521 };
522 int ret;
523
524 mutex_lock(&mvm->mutex);
525
526 /* Rssi update while not associated ?! */
527 if (WARN_ON_ONCE(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT))
528 goto out_unlock;
529
530 /* No open connection - reports should be disabled */
531 if (!BT_MBOX_MSG(&mvm->last_bt_notif, 3, OPEN_CON_2))
532 goto out_unlock;
533
534 IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid,
535 rssi_event == RSSI_EVENT_HIGH ? "HIGH" : "LOW");
536
537 /*
538 * Check if rssi is good enough for reduced Tx power, but not in loose
539 * scheme.
540 */
541 if (rssi_event == RSSI_EVENT_LOW || is_loose_coex())
542 ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id,
543 false);
544 else
545 ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true);
546
547 if (ret)
548 IWL_ERR(mvm, "couldn't send BT_CONFIG HCMD upon RSSI event\n");
549
550 ieee80211_iterate_active_interfaces_atomic(
551 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
552 iwl_mvm_bt_rssi_iterator, &data);
553
554 /*
555 * If there are no BSS / P2P client interfaces, reduced Tx Power is
556 * irrelevant since it is based on the RSSI coming from the beacon.
557 * Use BT_KILL_MSK_DEFAULT in that case.
558 */
559 data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces;
560
561 if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power))
562 IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
563
564 out_unlock:
565 mutex_unlock(&mvm->mutex);
566}
567
568void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
569{
570 struct ieee80211_chanctx_conf *chanctx_conf;
571 enum ieee80211_band band;
572
573 rcu_read_lock();
574 chanctx_conf = rcu_dereference(vif->chanctx_conf);
575 if (chanctx_conf && chanctx_conf->def.chan)
576 band = chanctx_conf->def.chan->band;
577 else
578 band = -1;
579 rcu_read_unlock();
580
581 /* if we are in 2GHz we will get a notification from the fw */
582 if (band == IEEE80211_BAND_2GHZ)
583 return;
584
585 /* else, we can remove all the constraints */
586 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
587
588 iwl_mvm_bt_coex_notif_handle(mvm);
589}
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index c64d864799cd..16bbdcc8627a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -61,8 +61,11 @@
61 * 61 *
62 *****************************************************************************/ 62 *****************************************************************************/
63 63
64#include <linux/etherdevice.h>
65#include <linux/ip.h>
64#include <net/cfg80211.h> 66#include <net/cfg80211.h>
65#include <net/ipv6.h> 67#include <net/ipv6.h>
68#include <net/tcp.h>
66#include "iwl-modparams.h" 69#include "iwl-modparams.h"
67#include "fw-api.h" 70#include "fw-api.h"
68#include "mvm.h" 71#include "mvm.h"
@@ -192,6 +195,11 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
192 sizeof(wkc), &wkc); 195 sizeof(wkc), &wkc);
193 data->error = ret != 0; 196 data->error = ret != 0;
194 197
198 mvm->ptk_ivlen = key->iv_len;
199 mvm->ptk_icvlen = key->icv_len;
200 mvm->gtk_ivlen = key->iv_len;
201 mvm->gtk_icvlen = key->icv_len;
202
195 /* don't upload key again */ 203 /* don't upload key again */
196 goto out_unlock; 204 goto out_unlock;
197 } 205 }
@@ -304,9 +312,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
304 */ 312 */
305 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { 313 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
306 key->hw_key_idx = 0; 314 key->hw_key_idx = 0;
315 mvm->ptk_ivlen = key->iv_len;
316 mvm->ptk_icvlen = key->icv_len;
307 } else { 317 } else {
308 data->gtk_key_idx++; 318 data->gtk_key_idx++;
309 key->hw_key_idx = data->gtk_key_idx; 319 key->hw_key_idx = data->gtk_key_idx;
320 mvm->gtk_ivlen = key->iv_len;
321 mvm->gtk_icvlen = key->icv_len;
310 } 322 }
311 323
312 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true); 324 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true);
@@ -392,6 +404,233 @@ static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
392 sizeof(cmd), &cmd); 404 sizeof(cmd), &cmd);
393} 405}
394 406
407enum iwl_mvm_tcp_packet_type {
408 MVM_TCP_TX_SYN,
409 MVM_TCP_RX_SYNACK,
410 MVM_TCP_TX_DATA,
411 MVM_TCP_RX_ACK,
412 MVM_TCP_RX_WAKE,
413 MVM_TCP_TX_FIN,
414};
415
416static __le16 pseudo_hdr_check(int len, __be32 saddr, __be32 daddr)
417{
418 __sum16 check = tcp_v4_check(len, saddr, daddr, 0);
419 return cpu_to_le16(be16_to_cpu((__force __be16)check));
420}
421
422static void iwl_mvm_build_tcp_packet(struct iwl_mvm *mvm,
423 struct ieee80211_vif *vif,
424 struct cfg80211_wowlan_tcp *tcp,
425 void *_pkt, u8 *mask,
426 __le16 *pseudo_hdr_csum,
427 enum iwl_mvm_tcp_packet_type ptype)
428{
429 struct {
430 struct ethhdr eth;
431 struct iphdr ip;
432 struct tcphdr tcp;
433 u8 data[];
434 } __packed *pkt = _pkt;
435 u16 ip_tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr);
436 int i;
437
438 pkt->eth.h_proto = cpu_to_be16(ETH_P_IP),
439 pkt->ip.version = 4;
440 pkt->ip.ihl = 5;
441 pkt->ip.protocol = IPPROTO_TCP;
442
443 switch (ptype) {
444 case MVM_TCP_TX_SYN:
445 case MVM_TCP_TX_DATA:
446 case MVM_TCP_TX_FIN:
447 memcpy(pkt->eth.h_dest, tcp->dst_mac, ETH_ALEN);
448 memcpy(pkt->eth.h_source, vif->addr, ETH_ALEN);
449 pkt->ip.ttl = 128;
450 pkt->ip.saddr = tcp->src;
451 pkt->ip.daddr = tcp->dst;
452 pkt->tcp.source = cpu_to_be16(tcp->src_port);
453 pkt->tcp.dest = cpu_to_be16(tcp->dst_port);
454 /* overwritten for TX SYN later */
455 pkt->tcp.doff = sizeof(struct tcphdr) / 4;
456 pkt->tcp.window = cpu_to_be16(65000);
457 break;
458 case MVM_TCP_RX_SYNACK:
459 case MVM_TCP_RX_ACK:
460 case MVM_TCP_RX_WAKE:
461 memcpy(pkt->eth.h_dest, vif->addr, ETH_ALEN);
462 memcpy(pkt->eth.h_source, tcp->dst_mac, ETH_ALEN);
463 pkt->ip.saddr = tcp->dst;
464 pkt->ip.daddr = tcp->src;
465 pkt->tcp.source = cpu_to_be16(tcp->dst_port);
466 pkt->tcp.dest = cpu_to_be16(tcp->src_port);
467 break;
468 default:
469 WARN_ON(1);
470 return;
471 }
472
473 switch (ptype) {
474 case MVM_TCP_TX_SYN:
475 /* firmware assumes 8 option bytes - 8 NOPs for now */
476 memset(pkt->data, 0x01, 8);
477 ip_tot_len += 8;
478 pkt->tcp.doff = (sizeof(struct tcphdr) + 8) / 4;
479 pkt->tcp.syn = 1;
480 break;
481 case MVM_TCP_TX_DATA:
482 ip_tot_len += tcp->payload_len;
483 memcpy(pkt->data, tcp->payload, tcp->payload_len);
484 pkt->tcp.psh = 1;
485 pkt->tcp.ack = 1;
486 break;
487 case MVM_TCP_TX_FIN:
488 pkt->tcp.fin = 1;
489 pkt->tcp.ack = 1;
490 break;
491 case MVM_TCP_RX_SYNACK:
492 pkt->tcp.syn = 1;
493 pkt->tcp.ack = 1;
494 break;
495 case MVM_TCP_RX_ACK:
496 pkt->tcp.ack = 1;
497 break;
498 case MVM_TCP_RX_WAKE:
499 ip_tot_len += tcp->wake_len;
500 pkt->tcp.psh = 1;
501 pkt->tcp.ack = 1;
502 memcpy(pkt->data, tcp->wake_data, tcp->wake_len);
503 break;
504 }
505
506 switch (ptype) {
507 case MVM_TCP_TX_SYN:
508 case MVM_TCP_TX_DATA:
509 case MVM_TCP_TX_FIN:
510 pkt->ip.tot_len = cpu_to_be16(ip_tot_len);
511 pkt->ip.check = ip_fast_csum(&pkt->ip, pkt->ip.ihl);
512 break;
513 case MVM_TCP_RX_WAKE:
514 for (i = 0; i < DIV_ROUND_UP(tcp->wake_len, 8); i++) {
515 u8 tmp = tcp->wake_mask[i];
516 mask[i + 6] |= tmp << 6;
517 if (i + 1 < DIV_ROUND_UP(tcp->wake_len, 8))
518 mask[i + 7] = tmp >> 2;
519 }
520 /* fall through for ethernet/IP/TCP headers mask */
521 case MVM_TCP_RX_SYNACK:
522 case MVM_TCP_RX_ACK:
523 mask[0] = 0xff; /* match ethernet */
524 /*
525 * match ethernet, ip.version, ip.ihl
526 * the ip.ihl half byte is really masked out by firmware
527 */
528 mask[1] = 0x7f;
529 mask[2] = 0x80; /* match ip.protocol */
530 mask[3] = 0xfc; /* match ip.saddr, ip.daddr */
531 mask[4] = 0x3f; /* match ip.daddr, tcp.source, tcp.dest */
532 mask[5] = 0x80; /* match tcp flags */
533 /* leave rest (0 or set for MVM_TCP_RX_WAKE) */
534 break;
535 };
536
537 *pseudo_hdr_csum = pseudo_hdr_check(ip_tot_len - sizeof(struct iphdr),
538 pkt->ip.saddr, pkt->ip.daddr);
539}
540
541static int iwl_mvm_send_remote_wake_cfg(struct iwl_mvm *mvm,
542 struct ieee80211_vif *vif,
543 struct cfg80211_wowlan_tcp *tcp)
544{
545 struct iwl_wowlan_remote_wake_config *cfg;
546 struct iwl_host_cmd cmd = {
547 .id = REMOTE_WAKE_CONFIG_CMD,
548 .len = { sizeof(*cfg), },
549 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
550 .flags = CMD_SYNC,
551 };
552 int ret;
553
554 if (!tcp)
555 return 0;
556
557 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
558 if (!cfg)
559 return -ENOMEM;
560 cmd.data[0] = cfg;
561
562 cfg->max_syn_retries = 10;
563 cfg->max_data_retries = 10;
564 cfg->tcp_syn_ack_timeout = 1; /* seconds */
565 cfg->tcp_ack_timeout = 1; /* seconds */
566
567 /* SYN (TX) */
568 iwl_mvm_build_tcp_packet(
569 mvm, vif, tcp, cfg->syn_tx.data, NULL,
570 &cfg->syn_tx.info.tcp_pseudo_header_checksum,
571 MVM_TCP_TX_SYN);
572 cfg->syn_tx.info.tcp_payload_length = 0;
573
574 /* SYN/ACK (RX) */
575 iwl_mvm_build_tcp_packet(
576 mvm, vif, tcp, cfg->synack_rx.data, cfg->synack_rx.rx_mask,
577 &cfg->synack_rx.info.tcp_pseudo_header_checksum,
578 MVM_TCP_RX_SYNACK);
579 cfg->synack_rx.info.tcp_payload_length = 0;
580
581 /* KEEPALIVE/ACK (TX) */
582 iwl_mvm_build_tcp_packet(
583 mvm, vif, tcp, cfg->keepalive_tx.data, NULL,
584 &cfg->keepalive_tx.info.tcp_pseudo_header_checksum,
585 MVM_TCP_TX_DATA);
586 cfg->keepalive_tx.info.tcp_payload_length =
587 cpu_to_le16(tcp->payload_len);
588 cfg->sequence_number_offset = tcp->payload_seq.offset;
589 /* length must be 0..4, the field is little endian */
590 cfg->sequence_number_length = tcp->payload_seq.len;
591 cfg->initial_sequence_number = cpu_to_le32(tcp->payload_seq.start);
592 cfg->keepalive_interval = cpu_to_le16(tcp->data_interval);
593 if (tcp->payload_tok.len) {
594 cfg->token_offset = tcp->payload_tok.offset;
595 cfg->token_length = tcp->payload_tok.len;
596 cfg->num_tokens =
597 cpu_to_le16(tcp->tokens_size % tcp->payload_tok.len);
598 memcpy(cfg->tokens, tcp->payload_tok.token_stream,
599 tcp->tokens_size);
600 } else {
601 /* set tokens to max value to almost never run out */
602 cfg->num_tokens = cpu_to_le16(65535);
603 }
604
605 /* ACK (RX) */
606 iwl_mvm_build_tcp_packet(
607 mvm, vif, tcp, cfg->keepalive_ack_rx.data,
608 cfg->keepalive_ack_rx.rx_mask,
609 &cfg->keepalive_ack_rx.info.tcp_pseudo_header_checksum,
610 MVM_TCP_RX_ACK);
611 cfg->keepalive_ack_rx.info.tcp_payload_length = 0;
612
613 /* WAKEUP (RX) */
614 iwl_mvm_build_tcp_packet(
615 mvm, vif, tcp, cfg->wake_rx.data, cfg->wake_rx.rx_mask,
616 &cfg->wake_rx.info.tcp_pseudo_header_checksum,
617 MVM_TCP_RX_WAKE);
618 cfg->wake_rx.info.tcp_payload_length =
619 cpu_to_le16(tcp->wake_len);
620
621 /* FIN */
622 iwl_mvm_build_tcp_packet(
623 mvm, vif, tcp, cfg->fin_tx.data, NULL,
624 &cfg->fin_tx.info.tcp_pseudo_header_checksum,
625 MVM_TCP_TX_FIN);
626 cfg->fin_tx.info.tcp_payload_length = 0;
627
628 ret = iwl_mvm_send_cmd(mvm, &cmd);
629 kfree(cfg);
630
631 return ret;
632}
633
395struct iwl_d3_iter_data { 634struct iwl_d3_iter_data {
396 struct iwl_mvm *mvm; 635 struct iwl_mvm *mvm;
397 struct ieee80211_vif *vif; 636 struct ieee80211_vif *vif;
@@ -530,7 +769,14 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
530 struct iwl_wowlan_config_cmd wowlan_config_cmd = {}; 769 struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
531 struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {}; 770 struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {};
532 struct iwl_wowlan_tkip_params_cmd tkip_cmd = {}; 771 struct iwl_wowlan_tkip_params_cmd tkip_cmd = {};
533 struct iwl_d3_manager_config d3_cfg_cmd = {}; 772 struct iwl_d3_manager_config d3_cfg_cmd = {
773 /*
774 * Program the minimum sleep time to 10 seconds, as many
775 * platforms have issues processing a wakeup signal while
776 * still being in the process of suspending.
777 */
778 .min_sleep_time = cpu_to_le32(10 * 1000 * 1000),
779 };
534 struct wowlan_key_data key_data = { 780 struct wowlan_key_data key_data = {
535 .use_rsc_tsc = false, 781 .use_rsc_tsc = false,
536 .tkip = &tkip_cmd, 782 .tkip = &tkip_cmd,
@@ -627,9 +873,21 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
627 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH); 873 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
628 874
629 if (wowlan->rfkill_release) 875 if (wowlan->rfkill_release)
630 d3_cfg_cmd.wakeup_flags |= 876 wowlan_config_cmd.wakeup_filter |=
631 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); 877 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
632 878
879 if (wowlan->tcp) {
880 /*
881 * Set the "link change" (really "link lost") flag as well
882 * since that implies losing the TCP connection.
883 */
884 wowlan_config_cmd.wakeup_filter |=
885 cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS |
886 IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE |
887 IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET |
888 IWL_WOWLAN_WAKEUP_LINK_CHANGE);
889 }
890
633 iwl_mvm_cancel_scan(mvm); 891 iwl_mvm_cancel_scan(mvm);
634 892
635 iwl_trans_stop_device(mvm->trans); 893 iwl_trans_stop_device(mvm->trans);
@@ -649,6 +907,11 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
649 /* We reprogram keys and shouldn't allocate new key indices */ 907 /* We reprogram keys and shouldn't allocate new key indices */
650 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); 908 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
651 909
910 mvm->ptk_ivlen = 0;
911 mvm->ptk_icvlen = 0;
912 mvm->ptk_ivlen = 0;
913 mvm->ptk_icvlen = 0;
914
652 /* 915 /*
653 * The D3 firmware still hardcodes the AP station ID for the 916 * The D3 firmware still hardcodes the AP station ID for the
654 * BSS we're associated with as 0. As a result, we have to move 917 * BSS we're associated with as 0. As a result, we have to move
@@ -740,6 +1003,10 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
740 if (ret) 1003 if (ret)
741 goto out; 1004 goto out;
742 1005
1006 ret = iwl_mvm_send_remote_wake_cfg(mvm, vif, wowlan->tcp);
1007 if (ret)
1008 goto out;
1009
743 /* must be last -- this switches firmware state */ 1010 /* must be last -- this switches firmware state */
744 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC, 1011 ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC,
745 sizeof(d3_cfg_cmd), &d3_cfg_cmd); 1012 sizeof(d3_cfg_cmd), &d3_cfg_cmd);
@@ -783,7 +1050,6 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
783 struct iwl_wowlan_status *status; 1050 struct iwl_wowlan_status *status;
784 u32 reasons; 1051 u32 reasons;
785 int ret, len; 1052 int ret, len;
786 bool pkt8023 = false;
787 struct sk_buff *pkt = NULL; 1053 struct sk_buff *pkt = NULL;
788 1054
789 iwl_trans_read_mem_bytes(mvm->trans, base, 1055 iwl_trans_read_mem_bytes(mvm->trans, base,
@@ -824,7 +1090,8 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
824 status = (void *)cmd.resp_pkt->data; 1090 status = (void *)cmd.resp_pkt->data;
825 1091
826 if (len - sizeof(struct iwl_cmd_header) != 1092 if (len - sizeof(struct iwl_cmd_header) !=
827 sizeof(*status) + le32_to_cpu(status->wake_packet_bufsize)) { 1093 sizeof(*status) +
1094 ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) {
828 IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); 1095 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
829 goto out; 1096 goto out;
830 } 1097 }
@@ -836,61 +1103,105 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
836 goto report; 1103 goto report;
837 } 1104 }
838 1105
839 if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) { 1106 if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET)
840 wakeup.magic_pkt = true; 1107 wakeup.magic_pkt = true;
841 pkt8023 = true;
842 }
843 1108
844 if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) { 1109 if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN)
845 wakeup.pattern_idx = 1110 wakeup.pattern_idx =
846 le16_to_cpu(status->pattern_number); 1111 le16_to_cpu(status->pattern_number);
847 pkt8023 = true;
848 }
849 1112
850 if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | 1113 if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
851 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)) 1114 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH))
852 wakeup.disconnect = true; 1115 wakeup.disconnect = true;
853 1116
854 if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) { 1117 if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)
855 wakeup.gtk_rekey_failure = true; 1118 wakeup.gtk_rekey_failure = true;
856 pkt8023 = true;
857 }
858 1119
859 if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) { 1120 if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
860 wakeup.rfkill_release = true; 1121 wakeup.rfkill_release = true;
861 pkt8023 = true;
862 }
863 1122
864 if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) { 1123 if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST)
865 wakeup.eap_identity_req = true; 1124 wakeup.eap_identity_req = true;
866 pkt8023 = true;
867 }
868 1125
869 if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) { 1126 if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE)
870 wakeup.four_way_handshake = true; 1127 wakeup.four_way_handshake = true;
871 pkt8023 = true; 1128
872 } 1129 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS)
1130 wakeup.tcp_connlost = true;
1131
1132 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE)
1133 wakeup.tcp_nomoretokens = true;
1134
1135 if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET)
1136 wakeup.tcp_match = true;
873 1137
874 if (status->wake_packet_bufsize) { 1138 if (status->wake_packet_bufsize) {
875 u32 pktsize = le32_to_cpu(status->wake_packet_bufsize); 1139 int pktsize = le32_to_cpu(status->wake_packet_bufsize);
876 u32 pktlen = le32_to_cpu(status->wake_packet_length); 1140 int pktlen = le32_to_cpu(status->wake_packet_length);
1141 const u8 *pktdata = status->wake_packet;
1142 struct ieee80211_hdr *hdr = (void *)pktdata;
1143 int truncated = pktlen - pktsize;
1144
1145 /* this would be a firmware bug */
1146 if (WARN_ON_ONCE(truncated < 0))
1147 truncated = 0;
1148
1149 if (ieee80211_is_data(hdr->frame_control)) {
1150 int hdrlen = ieee80211_hdrlen(hdr->frame_control);
1151 int ivlen = 0, icvlen = 4; /* also FCS */
877 1152
878 if (pkt8023) {
879 pkt = alloc_skb(pktsize, GFP_KERNEL); 1153 pkt = alloc_skb(pktsize, GFP_KERNEL);
880 if (!pkt) 1154 if (!pkt)
881 goto report; 1155 goto report;
882 memcpy(skb_put(pkt, pktsize), status->wake_packet, 1156
883 pktsize); 1157 memcpy(skb_put(pkt, hdrlen), pktdata, hdrlen);
1158 pktdata += hdrlen;
1159 pktsize -= hdrlen;
1160
1161 if (ieee80211_has_protected(hdr->frame_control)) {
1162 if (is_multicast_ether_addr(hdr->addr1)) {
1163 ivlen = mvm->gtk_ivlen;
1164 icvlen += mvm->gtk_icvlen;
1165 } else {
1166 ivlen = mvm->ptk_ivlen;
1167 icvlen += mvm->ptk_icvlen;
1168 }
1169 }
1170
1171 /* if truncated, FCS/ICV is (partially) gone */
1172 if (truncated >= icvlen) {
1173 icvlen = 0;
1174 truncated -= icvlen;
1175 } else {
1176 icvlen -= truncated;
1177 truncated = 0;
1178 }
1179
1180 pktsize -= ivlen + icvlen;
1181 pktdata += ivlen;
1182
1183 memcpy(skb_put(pkt, pktsize), pktdata, pktsize);
1184
884 if (ieee80211_data_to_8023(pkt, vif->addr, vif->type)) 1185 if (ieee80211_data_to_8023(pkt, vif->addr, vif->type))
885 goto report; 1186 goto report;
886 wakeup.packet = pkt->data; 1187 wakeup.packet = pkt->data;
887 wakeup.packet_present_len = pkt->len; 1188 wakeup.packet_present_len = pkt->len;
888 wakeup.packet_len = pkt->len - (pktlen - pktsize); 1189 wakeup.packet_len = pkt->len - truncated;
889 wakeup.packet_80211 = false; 1190 wakeup.packet_80211 = false;
890 } else { 1191 } else {
1192 int fcslen = 4;
1193
1194 if (truncated >= 4) {
1195 truncated -= 4;
1196 fcslen = 0;
1197 } else {
1198 fcslen -= truncated;
1199 truncated = 0;
1200 }
1201 pktsize -= fcslen;
891 wakeup.packet = status->wake_packet; 1202 wakeup.packet = status->wake_packet;
892 wakeup.packet_present_len = pktsize; 1203 wakeup.packet_present_len = pktsize;
893 wakeup.packet_len = pktlen; 1204 wakeup.packet_len = pktlen - truncated;
894 wakeup.packet_80211 = true; 1205 wakeup.packet_80211 = true;
895 } 1206 }
896 } 1207 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index c1bdb5582126..2053dccefcd6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -69,12 +69,6 @@ struct iwl_dbgfs_mvm_ctx {
69 struct ieee80211_vif *vif; 69 struct ieee80211_vif *vif;
70}; 70};
71 71
72static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file)
73{
74 file->private_data = inode->i_private;
75 return 0;
76}
77
78static ssize_t iwl_dbgfs_tx_flush_write(struct file *file, 72static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,
79 const char __user *user_buf, 73 const char __user *user_buf,
80 size_t count, loff_t *ppos) 74 size_t count, loff_t *ppos)
@@ -306,10 +300,191 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file,
306 return count; 300 return count;
307} 301}
308 302
303static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
304 char __user *user_buf,
305 size_t count, loff_t *ppos)
306{
307 struct ieee80211_vif *vif = file->private_data;
308 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
309 struct iwl_mvm *mvm = mvmvif->dbgfs_data;
310 u8 ap_sta_id;
311 struct ieee80211_chanctx_conf *chanctx_conf;
312 char buf[512];
313 int bufsz = sizeof(buf);
314 int pos = 0;
315 int i;
316
317 mutex_lock(&mvm->mutex);
318
319 ap_sta_id = mvmvif->ap_sta_id;
320
321 pos += scnprintf(buf+pos, bufsz-pos, "mac id/color: %d / %d\n",
322 mvmvif->id, mvmvif->color);
323 pos += scnprintf(buf+pos, bufsz-pos, "bssid: %pM\n",
324 vif->bss_conf.bssid);
325 pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n");
326 for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++) {
327 pos += scnprintf(buf+pos, bufsz-pos,
328 "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n",
329 i, mvmvif->queue_params[i].txop,
330 mvmvif->queue_params[i].cw_min,
331 mvmvif->queue_params[i].cw_max,
332 mvmvif->queue_params[i].aifs,
333 mvmvif->queue_params[i].uapsd);
334 }
335
336 if (vif->type == NL80211_IFTYPE_STATION &&
337 ap_sta_id != IWL_MVM_STATION_COUNT) {
338 struct ieee80211_sta *sta;
339 struct iwl_mvm_sta *mvm_sta;
340
341 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[ap_sta_id],
342 lockdep_is_held(&mvm->mutex));
343 mvm_sta = (void *)sta->drv_priv;
344 pos += scnprintf(buf+pos, bufsz-pos,
345 "ap_sta_id %d - reduced Tx power %d\n",
346 ap_sta_id, mvm_sta->bt_reduced_txpower);
347 }
348
349 rcu_read_lock();
350 chanctx_conf = rcu_dereference(vif->chanctx_conf);
351 if (chanctx_conf) {
352 pos += scnprintf(buf+pos, bufsz-pos,
353 "idle rx chains %d, active rx chains: %d\n",
354 chanctx_conf->rx_chains_static,
355 chanctx_conf->rx_chains_dynamic);
356 }
357 rcu_read_unlock();
358
359 mutex_unlock(&mvm->mutex);
360
361 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
362}
363
364#define BT_MBOX_MSG(_notif, _num, _field) \
365 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
366 >> BT_MBOX##_num##_##_field##_POS)
367
368
369#define BT_MBOX_PRINT(_num, _field, _end) \
370 pos += scnprintf(buf + pos, bufsz - pos, \
371 "\t%s: %d%s", \
372 #_field, \
373 BT_MBOX_MSG(notif, _num, _field), \
374 true ? "\n" : ", ");
375
376static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
377 size_t count, loff_t *ppos)
378{
379 struct iwl_mvm *mvm = file->private_data;
380 struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif;
381 char *buf;
382 int ret, pos = 0, bufsz = sizeof(char) * 1024;
383
384 buf = kmalloc(bufsz, GFP_KERNEL);
385 if (!buf)
386 return -ENOMEM;
387
388 mutex_lock(&mvm->mutex);
389
390 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n");
391
392 BT_MBOX_PRINT(0, LE_SLAVE_LAT, false);
393 BT_MBOX_PRINT(0, LE_PROF1, false);
394 BT_MBOX_PRINT(0, LE_PROF2, false);
395 BT_MBOX_PRINT(0, LE_PROF_OTHER, false);
396 BT_MBOX_PRINT(0, CHL_SEQ_N, false);
397 BT_MBOX_PRINT(0, INBAND_S, false);
398 BT_MBOX_PRINT(0, LE_MIN_RSSI, false);
399 BT_MBOX_PRINT(0, LE_SCAN, false);
400 BT_MBOX_PRINT(0, LE_ADV, false);
401 BT_MBOX_PRINT(0, LE_MAX_TX_POWER, false);
402 BT_MBOX_PRINT(0, OPEN_CON_1, true);
403
404 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw1:\n");
405
406 BT_MBOX_PRINT(1, BR_MAX_TX_POWER, false);
407 BT_MBOX_PRINT(1, IP_SR, false);
408 BT_MBOX_PRINT(1, LE_MSTR, false);
409 BT_MBOX_PRINT(1, AGGR_TRFC_LD, false);
410 BT_MBOX_PRINT(1, MSG_TYPE, false);
411 BT_MBOX_PRINT(1, SSN, true);
412
413 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw2:\n");
414
415 BT_MBOX_PRINT(2, SNIFF_ACT, false);
416 BT_MBOX_PRINT(2, PAG, false);
417 BT_MBOX_PRINT(2, INQUIRY, false);
418 BT_MBOX_PRINT(2, CONN, false);
419 BT_MBOX_PRINT(2, SNIFF_INTERVAL, false);
420 BT_MBOX_PRINT(2, DISC, false);
421 BT_MBOX_PRINT(2, SCO_TX_ACT, false);
422 BT_MBOX_PRINT(2, SCO_RX_ACT, false);
423 BT_MBOX_PRINT(2, ESCO_RE_TX, false);
424 BT_MBOX_PRINT(2, SCO_DURATION, true);
425
426 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw3:\n");
427
428 BT_MBOX_PRINT(3, SCO_STATE, false);
429 BT_MBOX_PRINT(3, SNIFF_STATE, false);
430 BT_MBOX_PRINT(3, A2DP_STATE, false);
431 BT_MBOX_PRINT(3, ACL_STATE, false);
432 BT_MBOX_PRINT(3, MSTR_STATE, false);
433 BT_MBOX_PRINT(3, OBX_STATE, false);
434 BT_MBOX_PRINT(3, OPEN_CON_2, false);
435 BT_MBOX_PRINT(3, TRAFFIC_LOAD, false);
436 BT_MBOX_PRINT(3, CHL_SEQN_LSB, false);
437 BT_MBOX_PRINT(3, INBAND_P, false);
438 BT_MBOX_PRINT(3, MSG_TYPE_2, false);
439 BT_MBOX_PRINT(3, SSN_2, false);
440 BT_MBOX_PRINT(3, UPDATE_REQUEST, true);
441
442 pos += scnprintf(buf+pos, bufsz-pos, "bt_status = %d\n",
443 notif->bt_status);
444 pos += scnprintf(buf+pos, bufsz-pos, "bt_open_conn = %d\n",
445 notif->bt_open_conn);
446 pos += scnprintf(buf+pos, bufsz-pos, "bt_traffic_load = %d\n",
447 notif->bt_traffic_load);
448 pos += scnprintf(buf+pos, bufsz-pos, "bt_agg_traffic_load = %d\n",
449 notif->bt_agg_traffic_load);
450 pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n",
451 notif->bt_ci_compliance);
452
453 mutex_unlock(&mvm->mutex);
454
455 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
456 kfree(buf);
457
458 return ret;
459}
460#undef BT_MBOX_PRINT
461
462static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
463 const char __user *user_buf,
464 size_t count, loff_t *ppos)
465{
466 struct iwl_mvm *mvm = file->private_data;
467 bool restart_fw = iwlwifi_mod_params.restart_fw;
468 int ret;
469
470 iwlwifi_mod_params.restart_fw = true;
471
472 mutex_lock(&mvm->mutex);
473
474 /* take the return value to make compiler happy - it will fail anyway */
475 ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_ERROR, CMD_SYNC, 0, NULL);
476
477 mutex_unlock(&mvm->mutex);
478
479 iwlwifi_mod_params.restart_fw = restart_fw;
480
481 return count;
482}
483
309#define MVM_DEBUGFS_READ_FILE_OPS(name) \ 484#define MVM_DEBUGFS_READ_FILE_OPS(name) \
310static const struct file_operations iwl_dbgfs_##name##_ops = { \ 485static const struct file_operations iwl_dbgfs_##name##_ops = { \
311 .read = iwl_dbgfs_##name##_read, \ 486 .read = iwl_dbgfs_##name##_read, \
312 .open = iwl_dbgfs_open_file_generic, \ 487 .open = simple_open, \
313 .llseek = generic_file_llseek, \ 488 .llseek = generic_file_llseek, \
314} 489}
315 490
@@ -317,14 +492,14 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
317static const struct file_operations iwl_dbgfs_##name##_ops = { \ 492static const struct file_operations iwl_dbgfs_##name##_ops = { \
318 .write = iwl_dbgfs_##name##_write, \ 493 .write = iwl_dbgfs_##name##_write, \
319 .read = iwl_dbgfs_##name##_read, \ 494 .read = iwl_dbgfs_##name##_read, \
320 .open = iwl_dbgfs_open_file_generic, \ 495 .open = simple_open, \
321 .llseek = generic_file_llseek, \ 496 .llseek = generic_file_llseek, \
322}; 497};
323 498
324#define MVM_DEBUGFS_WRITE_FILE_OPS(name) \ 499#define MVM_DEBUGFS_WRITE_FILE_OPS(name) \
325static const struct file_operations iwl_dbgfs_##name##_ops = { \ 500static const struct file_operations iwl_dbgfs_##name##_ops = { \
326 .write = iwl_dbgfs_##name##_write, \ 501 .write = iwl_dbgfs_##name##_write, \
327 .open = iwl_dbgfs_open_file_generic, \ 502 .open = simple_open, \
328 .llseek = generic_file_llseek, \ 503 .llseek = generic_file_llseek, \
329}; 504};
330 505
@@ -345,8 +520,13 @@ MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush);
345MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); 520MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain);
346MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); 521MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram);
347MVM_DEBUGFS_READ_FILE_OPS(stations); 522MVM_DEBUGFS_READ_FILE_OPS(stations);
523MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
348MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); 524MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow);
349MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); 525MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow);
526MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart);
527
528/* Interface specific debugfs entries */
529MVM_DEBUGFS_READ_FILE_OPS(mac_params);
350 530
351int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) 531int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
352{ 532{
@@ -358,8 +538,10 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
358 MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); 538 MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR);
359 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); 539 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
360 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); 540 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
541 MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
361 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); 542 MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR);
362 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); 543 MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR);
544 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
363 545
364 /* 546 /*
365 * Create a symlink with mac80211. It will be removed when mac80211 547 * Create a symlink with mac80211. It will be removed when mac80211
@@ -376,3 +558,58 @@ err:
376 IWL_ERR(mvm, "Can't create the mvm debugfs directory\n"); 558 IWL_ERR(mvm, "Can't create the mvm debugfs directory\n");
377 return -ENOMEM; 559 return -ENOMEM;
378} 560}
561
562void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
563{
564 struct dentry *dbgfs_dir = vif->debugfs_dir;
565 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
566 char buf[100];
567
568 if (!dbgfs_dir)
569 return;
570
571 mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
572 mvmvif->dbgfs_data = mvm;
573
574 if (!mvmvif->dbgfs_dir) {
575 IWL_ERR(mvm, "Failed to create debugfs directory under %s\n",
576 dbgfs_dir->d_name.name);
577 return;
578 }
579
580 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir,
581 S_IRUSR);
582
583 /*
584 * Create symlink for convenience pointing to interface specific
585 * debugfs entries for the driver. For example, under
586 * /sys/kernel/debug/iwlwifi/0000\:02\:00.0/iwlmvm/
587 * find
588 * netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/
589 */
590 snprintf(buf, 100, "../../../%s/%s/%s/%s",
591 dbgfs_dir->d_parent->d_parent->d_name.name,
592 dbgfs_dir->d_parent->d_name.name,
593 dbgfs_dir->d_name.name,
594 mvmvif->dbgfs_dir->d_name.name);
595
596 mvmvif->dbgfs_slink = debugfs_create_symlink(dbgfs_dir->d_name.name,
597 mvm->debugfs_dir, buf);
598 if (!mvmvif->dbgfs_slink)
599 IWL_ERR(mvm, "Can't create debugfs symbolic link under %s\n",
600 dbgfs_dir->d_name.name);
601 return;
602err:
603 IWL_ERR(mvm, "Can't create debugfs entity\n");
604}
605
606void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
607{
608 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
609
610 debugfs_remove(mvmvif->dbgfs_slink);
611 mvmvif->dbgfs_slink = NULL;
612
613 debugfs_remove_recursive(mvmvif->dbgfs_dir);
614 mvmvif->dbgfs_dir = NULL;
615}
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
new file mode 100644
index 000000000000..05c61d6f384e
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h
@@ -0,0 +1,319 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2013 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#ifndef __fw_api_bt_coex_h__
64#define __fw_api_bt_coex_h__
65
66#include <linux/types.h>
67#include <linux/bitops.h>
68
69#define BITS(nb) (BIT(nb) - 1)
70
71/**
72 * enum iwl_bt_coex_flags - flags for BT_COEX command
73 * @BT_CH_PRIMARY_EN:
74 * @BT_CH_SECONDARY_EN:
75 * @BT_NOTIF_COEX_OFF:
76 * @BT_COEX_MODE_POS:
77 * @BT_COEX_MODE_MSK:
78 * @BT_COEX_DISABLE:
79 * @BT_COEX_2W:
80 * @BT_COEX_3W:
81 * @BT_COEX_NW:
82 * @BT_USE_DEFAULTS:
83 * @BT_SYNC_2_BT_DISABLE:
84 * @BT_COEX_CORUNNING_TBL_EN:
85 */
86enum iwl_bt_coex_flags {
87 BT_CH_PRIMARY_EN = BIT(0),
88 BT_CH_SECONDARY_EN = BIT(1),
89 BT_NOTIF_COEX_OFF = BIT(2),
90 BT_COEX_MODE_POS = 3,
91 BT_COEX_MODE_MSK = BITS(3) << BT_COEX_MODE_POS,
92 BT_COEX_DISABLE = 0x0 << BT_COEX_MODE_POS,
93 BT_COEX_2W = 0x1 << BT_COEX_MODE_POS,
94 BT_COEX_3W = 0x2 << BT_COEX_MODE_POS,
95 BT_COEX_NW = 0x3 << BT_COEX_MODE_POS,
96 BT_USE_DEFAULTS = BIT(6),
97 BT_SYNC_2_BT_DISABLE = BIT(7),
98 /*
99 * For future use - when the flags will be enlarged
100 * BT_COEX_CORUNNING_TBL_EN = BIT(8),
101 */
102};
103
104/*
105 * indicates what has changed in the BT_COEX command.
106 */
107enum iwl_bt_coex_valid_bit_msk {
108 BT_VALID_ENABLE = BIT(0),
109 BT_VALID_BT_PRIO_BOOST = BIT(1),
110 BT_VALID_MAX_KILL = BIT(2),
111 BT_VALID_3W_TMRS = BIT(3),
112 BT_VALID_KILL_ACK = BIT(4),
113 BT_VALID_KILL_CTS = BIT(5),
114 BT_VALID_REDUCED_TX_POWER = BIT(6),
115 BT_VALID_LUT = BIT(7),
116 BT_VALID_WIFI_RX_SW_PRIO_BOOST = BIT(8),
117 BT_VALID_WIFI_TX_SW_PRIO_BOOST = BIT(9),
118 BT_VALID_MULTI_PRIO_LUT = BIT(10),
119 BT_VALID_TRM_KICK_FILTER = BIT(11),
120 BT_VALID_CORUN_LUT_20 = BIT(12),
121 BT_VALID_CORUN_LUT_40 = BIT(13),
122 BT_VALID_ANT_ISOLATION = BIT(14),
123 BT_VALID_ANT_ISOLATION_THRS = BIT(15),
124 /*
125 * For future use - when the valid flags will be enlarged
126 * BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16),
127 * BT_VALID_TXRX_MAX_FREQ_0 = BIT(17),
128 */
129};
130
131/**
132 * enum iwl_bt_reduced_tx_power - allows to reduce txpower for WiFi frames.
133 * @BT_REDUCED_TX_POWER_CTL: reduce Tx power for control frames
134 * @BT_REDUCED_TX_POWER_DATA: reduce Tx power for data frames
135 *
136 * This mechanism allows to have BT and WiFi run concurrently. Since WiFi
137 * reduces its Tx power, it can work along with BT, hence reducing the amount
138 * of WiFi frames being killed by BT.
139 */
140enum iwl_bt_reduced_tx_power {
141 BT_REDUCED_TX_POWER_CTL = BIT(0),
142 BT_REDUCED_TX_POWER_DATA = BIT(1),
143};
144
145#define BT_COEX_LUT_SIZE (12)
146
147/**
148 * struct iwl_bt_coex_cmd - bt coex configuration command
149 * @flags:&enum iwl_bt_coex_flags
150 * @lead_time:
151 * @max_kill:
152 * @bt3_time_t7_value:
153 * @kill_ack_msk:
154 * @kill_cts_msk:
155 * @bt3_prio_sample_time:
156 * @bt3_timer_t2_value:
157 * @bt4_reaction_time:
158 * @decision_lut[12]:
159 * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power
160 * @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk
161 * @bt_prio_boost: values for PTA boost register
162 * @wifi_tx_prio_boost: SW boost of wifi tx priority
163 * @wifi_rx_prio_boost: SW boost of wifi rx priority
164 *
165 * The structure is used for the BT_COEX command.
166 */
167struct iwl_bt_coex_cmd {
168 u8 flags;
169 u8 lead_time;
170 u8 max_kill;
171 u8 bt3_time_t7_value;
172 __le32 kill_ack_msk;
173 __le32 kill_cts_msk;
174 u8 bt3_prio_sample_time;
175 u8 bt3_timer_t2_value;
176 __le16 bt4_reaction_time;
177 __le32 decision_lut[BT_COEX_LUT_SIZE];
178 u8 bt_reduced_tx_power;
179 u8 reserved;
180 __le16 valid_bit_msk;
181 __le32 bt_prio_boost;
182 u8 reserved2;
183 u8 wifi_tx_prio_boost;
184 __le16 wifi_rx_prio_boost;
185} __packed; /* BT_COEX_CMD_API_S_VER_3 */
186
187#define BT_MBOX(n_dw, _msg, _pos, _nbits) \
188 BT_MBOX##n_dw##_##_msg##_POS = (_pos), \
189 BT_MBOX##n_dw##_##_msg = BITS(_nbits) << BT_MBOX##n_dw##_##_msg##_POS
190
191enum iwl_bt_mxbox_dw0 {
192 BT_MBOX(0, LE_SLAVE_LAT, 0, 3),
193 BT_MBOX(0, LE_PROF1, 3, 1),
194 BT_MBOX(0, LE_PROF2, 4, 1),
195 BT_MBOX(0, LE_PROF_OTHER, 5, 1),
196 BT_MBOX(0, CHL_SEQ_N, 8, 4),
197 BT_MBOX(0, INBAND_S, 13, 1),
198 BT_MBOX(0, LE_MIN_RSSI, 16, 4),
199 BT_MBOX(0, LE_SCAN, 20, 1),
200 BT_MBOX(0, LE_ADV, 21, 1),
201 BT_MBOX(0, LE_MAX_TX_POWER, 24, 4),
202 BT_MBOX(0, OPEN_CON_1, 28, 2),
203};
204
205enum iwl_bt_mxbox_dw1 {
206 BT_MBOX(1, BR_MAX_TX_POWER, 0, 4),
207 BT_MBOX(1, IP_SR, 4, 1),
208 BT_MBOX(1, LE_MSTR, 5, 1),
209 BT_MBOX(1, AGGR_TRFC_LD, 8, 6),
210 BT_MBOX(1, MSG_TYPE, 16, 3),
211 BT_MBOX(1, SSN, 19, 2),
212};
213
214enum iwl_bt_mxbox_dw2 {
215 BT_MBOX(2, SNIFF_ACT, 0, 3),
216 BT_MBOX(2, PAG, 3, 1),
217 BT_MBOX(2, INQUIRY, 4, 1),
218 BT_MBOX(2, CONN, 5, 1),
219 BT_MBOX(2, SNIFF_INTERVAL, 8, 5),
220 BT_MBOX(2, DISC, 13, 1),
221 BT_MBOX(2, SCO_TX_ACT, 16, 2),
222 BT_MBOX(2, SCO_RX_ACT, 18, 2),
223 BT_MBOX(2, ESCO_RE_TX, 20, 2),
224 BT_MBOX(2, SCO_DURATION, 24, 6),
225};
226
227enum iwl_bt_mxbox_dw3 {
228 BT_MBOX(3, SCO_STATE, 0, 1),
229 BT_MBOX(3, SNIFF_STATE, 1, 1),
230 BT_MBOX(3, A2DP_STATE, 2, 1),
231 BT_MBOX(3, ACL_STATE, 3, 1),
232 BT_MBOX(3, MSTR_STATE, 4, 1),
233 BT_MBOX(3, OBX_STATE, 5, 1),
234 BT_MBOX(3, OPEN_CON_2, 8, 2),
235 BT_MBOX(3, TRAFFIC_LOAD, 10, 2),
236 BT_MBOX(3, CHL_SEQN_LSB, 12, 1),
237 BT_MBOX(3, INBAND_P, 13, 1),
238 BT_MBOX(3, MSG_TYPE_2, 16, 3),
239 BT_MBOX(3, SSN_2, 19, 2),
240 BT_MBOX(3, UPDATE_REQUEST, 21, 1),
241};
242
243#define BT_MBOX_MSG(_notif, _num, _field) \
244 ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
245 >> BT_MBOX##_num##_##_field##_POS)
246
247/**
248 * struct iwl_bt_coex_profile_notif - notification about BT coex
249 * @mbox_msg: message from BT to WiFi
250 * @:bt_status: 0 - off, 1 - on
251 * @:bt_open_conn: number of BT connections open
252 * @:bt_traffic_load: load of BT traffic
253 * @:bt_agg_traffic_load: aggregated load of BT traffic
254 * @:bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant
255 */
256struct iwl_bt_coex_profile_notif {
257 __le32 mbox_msg[4];
258 u8 bt_status;
259 u8 bt_open_conn;
260 u8 bt_traffic_load;
261 u8 bt_agg_traffic_load;
262 u8 bt_ci_compliance;
263 u8 reserved[3];
264} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_2 */
265
266enum iwl_bt_coex_prio_table_event {
267 BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0,
268 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2 = 1,
269 BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1 = 2,
270 BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2 = 3,
271 BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1 = 4,
272 BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2 = 5,
273 BT_COEX_PRIO_TBL_EVT_DTIM = 6,
274 BT_COEX_PRIO_TBL_EVT_SCAN52 = 7,
275 BT_COEX_PRIO_TBL_EVT_SCAN24 = 8,
276 BT_COEX_PRIO_TBL_EVT_IDLE = 9,
277 BT_COEX_PRIO_TBL_EVT_MAX = 16,
278}; /* BT_COEX_PRIO_TABLE_EVENTS_API_E_VER_1 */
279
280enum iwl_bt_coex_prio_table_prio {
281 BT_COEX_PRIO_TBL_DISABLED = 0,
282 BT_COEX_PRIO_TBL_PRIO_LOW = 1,
283 BT_COEX_PRIO_TBL_PRIO_HIGH = 2,
284 BT_COEX_PRIO_TBL_PRIO_BYPASS = 3,
285 BT_COEX_PRIO_TBL_PRIO_COEX_OFF = 4,
286 BT_COEX_PRIO_TBL_PRIO_COEX_ON = 5,
287 BT_COEX_PRIO_TBL_PRIO_COEX_IDLE = 6,
288 BT_COEX_PRIO_TBL_MAX = 8,
289}; /* BT_COEX_PRIO_TABLE_PRIORITIES_API_E_VER_1 */
290
291#define BT_COEX_PRIO_TBL_SHRD_ANT_POS (0)
292#define BT_COEX_PRIO_TBL_PRIO_POS (1)
293#define BT_COEX_PRIO_TBL_RESERVED_POS (4)
294
295/**
296 * struct iwl_bt_coex_prio_tbl_cmd - priority table for BT coex
297 * @prio_tbl:
298 */
299struct iwl_bt_coex_prio_tbl_cmd {
300 u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX];
301} __packed;
302
303enum iwl_bt_coex_env_action {
304 BT_COEX_ENV_CLOSE = 0,
305 BT_COEX_ENV_OPEN = 1,
306}; /* BT_COEX_PROT_ENV_ACTION_API_E_VER_1 */
307
308/**
309 * struct iwl_bt_coex_prot_env_cmd - BT Protection Envelope
310 * @action: enum %iwl_bt_coex_env_action
311 * @type: enum %iwl_bt_coex_prio_table_event
312 */
313struct iwl_bt_coex_prot_env_cmd {
314 u8 action; /* 0 = closed, 1 = open */
315 u8 type; /* 0 .. 15 */
316 u8 reserved[2];
317} __packed;
318
319#endif /* __fw_api_bt_coex_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
index cf6f9a02fb74..51e015d1dfb2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -258,7 +258,7 @@ enum iwl_wowlan_wakeup_reason {
258 IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE = BIT(8), 258 IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE = BIT(8),
259 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS = BIT(9), 259 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS = BIT(9),
260 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE = BIT(10), 260 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE = BIT(10),
261 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_TCP_EXTERNAL = BIT(11), 261 /* BIT(11) reserved */
262 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12), 262 IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12),
263}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */ 263}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */
264 264
@@ -277,6 +277,55 @@ struct iwl_wowlan_status {
277 u8 wake_packet[]; /* can be truncated from _length to _bufsize */ 277 u8 wake_packet[]; /* can be truncated from _length to _bufsize */
278} __packed; /* WOWLAN_STATUSES_API_S_VER_4 */ 278} __packed; /* WOWLAN_STATUSES_API_S_VER_4 */
279 279
280#define IWL_WOWLAN_TCP_MAX_PACKET_LEN 64
281#define IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN 128
282#define IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS 2048
283
284struct iwl_tcp_packet_info {
285 __le16 tcp_pseudo_header_checksum;
286 __le16 tcp_payload_length;
287} __packed; /* TCP_PACKET_INFO_API_S_VER_2 */
288
289struct iwl_tcp_packet {
290 struct iwl_tcp_packet_info info;
291 u8 rx_mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8];
292 u8 data[IWL_WOWLAN_TCP_MAX_PACKET_LEN];
293} __packed; /* TCP_PROTOCOL_PACKET_API_S_VER_1 */
294
295struct iwl_remote_wake_packet {
296 struct iwl_tcp_packet_info info;
297 u8 rx_mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8];
298 u8 data[IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN];
299} __packed; /* TCP_PROTOCOL_PACKET_API_S_VER_1 */
300
301struct iwl_wowlan_remote_wake_config {
302 __le32 connection_max_time; /* unused */
303 /* TCP_PROTOCOL_CONFIG_API_S_VER_1 */
304 u8 max_syn_retries;
305 u8 max_data_retries;
306 u8 tcp_syn_ack_timeout;
307 u8 tcp_ack_timeout;
308
309 struct iwl_tcp_packet syn_tx;
310 struct iwl_tcp_packet synack_rx;
311 struct iwl_tcp_packet keepalive_ack_rx;
312 struct iwl_tcp_packet fin_tx;
313
314 struct iwl_remote_wake_packet keepalive_tx;
315 struct iwl_remote_wake_packet wake_rx;
316
317 /* REMOTE_WAKE_OFFSET_INFO_API_S_VER_1 */
318 u8 sequence_number_offset;
319 u8 sequence_number_length;
320 u8 token_offset;
321 u8 token_length;
322 /* REMOTE_WAKE_PROTOCOL_PARAMS_API_S_VER_1 */
323 __le32 initial_sequence_number;
324 __le16 keepalive_interval;
325 __le16 num_tokens;
326 u8 tokens[IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS];
327} __packed; /* REMOTE_WAKE_CONFIG_API_S_VER_2 */
328
280/* TODO: NetDetect API */ 329/* TODO: NetDetect API */
281 330
282#endif /* __fw_api_d3_h__ */ 331#endif /* __fw_api_d3_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
index ae39b7dfda7b..d68640ea41d4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index be36b7604b7f..81fe45f46be7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -68,73 +68,53 @@
68 68
69/** 69/**
70 * enum iwl_scan_flags - masks for power table command flags 70 * enum iwl_scan_flags - masks for power table command flags
71 * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off
72 * receiver and transmitter. '0' - does not allow.
71 * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management, 73 * @POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK: '0' Driver disables power management,
72 * '1' Driver enables PM (use rest of parameters) 74 * '1' Driver enables PM (use rest of parameters)
73 * @POWER_FLAGS_SLEEP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM, 75 * @POWER_FLAGS_SKIP_OVER_DTIM_MSK: '0' PM have to walk up every DTIM,
74 * '1' PM could sleep over DTIM till listen Interval. 76 * '1' PM could sleep over DTIM till listen Interval.
75 * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable.
76 * @POWER_FLAGS_SNOOZE_ENA_MSK: Enable snoozing only if uAPSD is enabled and all
77 * access categories are both delivery and trigger enabled.
78 * @POWER_FLAGS_BT_SCO_ENA: Enable BT SCO coex only if uAPSD and
79 * PBW Snoozing enabled
80 * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask 77 * @POWER_FLAGS_ADVANCE_PM_ENA_MSK: Advanced PM (uAPSD) enable mask
78 * @POWER_FLAGS_LPRX_ENA_MSK: Low Power RX enable.
81*/ 79*/
82enum iwl_power_flags { 80enum iwl_power_flags {
83 POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK = BIT(0), 81 POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0),
84 POWER_FLAGS_SLEEP_OVER_DTIM_MSK = BIT(1), 82 POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK = BIT(1),
85 POWER_FLAGS_LPRX_ENA_MSK = BIT(2), 83 POWER_FLAGS_SKIP_OVER_DTIM_MSK = BIT(2),
86 POWER_FLAGS_SNOOZE_ENA_MSK = BIT(3), 84 POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(9),
87 POWER_FLAGS_BT_SCO_ENA = BIT(4), 85 POWER_FLAGS_LPRX_ENA_MSK = BIT(11),
88 POWER_FLAGS_ADVANCE_PM_ENA_MSK = BIT(5)
89}; 86};
90 87
88#define IWL_POWER_VEC_SIZE 5
89
91/** 90/**
92 * struct iwl_powertable_cmd - Power Table Command 91 * struct iwl_powertable_cmd - Power Table Command
93 * POWER_TABLE_CMD = 0x77 (command, has simple generic response) 92 * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
94 * 93 *
95 * @id_and_color: MAC contex identifier
96 * @action: Action on context - no action, add new,
97 * modify existent, remove
98 * @flags: Power table command flags from POWER_FLAGS_* 94 * @flags: Power table command flags from POWER_FLAGS_*
99 * @keep_alive_seconds: Keep alive period in seconds. Default - 25 sec. 95 * @keep_alive_seconds: Keep alive period in seconds. Default - 25 sec.
100 * Minimum allowed:- 3 * DTIM 96 * Minimum allowed:- 3 * DTIM. Keep alive period must be
97 * set regardless of power scheme or current power state.
98 * FW use this value also when PM is disabled.
101 * @rx_data_timeout: Minimum time (usec) from last Rx packet for AM to 99 * @rx_data_timeout: Minimum time (usec) from last Rx packet for AM to
102 * PSM transition - legacy PM 100 * PSM transition - legacy PM
103 * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to 101 * @tx_data_timeout: Minimum time (usec) from last Tx packet for AM to
104 * PSM transition - legacy PM 102 * PSM transition - legacy PM
105 * @rx_data_timeout_uapsd: Minimum time (usec) from last Rx packet for AM to 103 * @sleep_interval: not in use
106 * PSM transition - uAPSD 104 * @keep_alive_beacons: not in use
107 * @tx_data_timeout_uapsd: Minimum time (usec) from last Tx packet for AM to
108 * PSM transition - uAPSD
109 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled. 105 * @lprx_rssi_threshold: Signal strength up to which LP RX can be enabled.
110 * Default: 80dbm 106 * Default: 80dbm
111 * @num_skip_dtim: Number of DTIMs to skip if Skip over DTIM flag is set
112 * @snooze_interval: TBD
113 * @snooze_window: TBD
114 * @snooze_step: TBD
115 * @qndp_tid: TBD
116 * @uapsd_ac_flags: TBD
117 * @uapsd_max_sp: TBD
118 */ 107 */
119struct iwl_powertable_cmd { 108struct iwl_powertable_cmd {
120 /* COMMON_INDEX_HDR_API_S_VER_1 */ 109 /* PM_POWER_TABLE_CMD_API_S_VER_5 */
121 __le32 id_and_color;
122 __le32 action;
123 __le16 flags; 110 __le16 flags;
124 u8 reserved; 111 u8 keep_alive_seconds;
125 __le16 keep_alive_seconds; 112 u8 debug_flags;
126 __le32 rx_data_timeout; 113 __le32 rx_data_timeout;
127 __le32 tx_data_timeout; 114 __le32 tx_data_timeout;
128 __le32 rx_data_timeout_uapsd; 115 __le32 sleep_interval[IWL_POWER_VEC_SIZE];
129 __le32 tx_data_timeout_uapsd; 116 __le32 keep_alive_beacons;
130 u8 lprx_rssi_threshold; 117 __le32 lprx_rssi_threshold;
131 u8 num_skip_dtim;
132 __le16 snooze_interval;
133 __le16 snooze_window;
134 u8 snooze_step;
135 u8 qndp_tid;
136 u8 uapsd_ac_flags;
137 u8 uapsd_max_sp;
138} __packed; 118} __packed;
139 119
140#endif 120#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
index aa3474d08231..fdd33bc0a594 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index 670ac8f95e26..b60d14151721 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
index 0acb53dda22d..a30691a8a85b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index 2677914bf0a6..007a93b25bd7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -537,6 +537,12 @@ struct iwl_mac_beacon_cmd {
537 struct ieee80211_hdr frame[0]; 537 struct ieee80211_hdr frame[0];
538} __packed; 538} __packed;
539 539
540struct iwl_beacon_notif {
541 struct iwl_mvm_tx_resp beacon_notify_hdr;
542 __le64 tsf;
543 __le32 ibss_mgr_status;
544} __packed;
545
540/** 546/**
541 * enum iwl_dump_control - dump (flush) control flags 547 * enum iwl_dump_control - dump (flush) control flags
542 * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty 548 * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 23eebda848b0..191dcae8ba47 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -70,6 +70,7 @@
70#include "fw-api-mac.h" 70#include "fw-api-mac.h"
71#include "fw-api-power.h" 71#include "fw-api-power.h"
72#include "fw-api-d3.h" 72#include "fw-api-d3.h"
73#include "fw-api-bt-coex.h"
73 74
74/* queue and FIFO numbers by usage */ 75/* queue and FIFO numbers by usage */
75enum { 76enum {
@@ -150,8 +151,10 @@ enum {
150 151
151 SET_CALIB_DEFAULT_CMD = 0x8e, 152 SET_CALIB_DEFAULT_CMD = 0x8e,
152 153
154 BEACON_NOTIFICATION = 0x90,
153 BEACON_TEMPLATE_CMD = 0x91, 155 BEACON_TEMPLATE_CMD = 0x91,
154 TX_ANT_CONFIGURATION_CMD = 0x98, 156 TX_ANT_CONFIGURATION_CMD = 0x98,
157 BT_CONFIG = 0x9b,
155 STATISTICS_NOTIFICATION = 0x9d, 158 STATISTICS_NOTIFICATION = 0x9d,
156 159
157 /* RF-KILL commands and notifications */ 160 /* RF-KILL commands and notifications */
@@ -162,6 +165,11 @@ enum {
162 REPLY_RX_MPDU_CMD = 0xc1, 165 REPLY_RX_MPDU_CMD = 0xc1,
163 BA_NOTIF = 0xc5, 166 BA_NOTIF = 0xc5,
164 167
168 /* BT Coex */
169 BT_COEX_PRIO_TABLE = 0xcc,
170 BT_COEX_PROT_ENV = 0xcd,
171 BT_PROFILE_NOTIFICATION = 0xce,
172
165 REPLY_DEBUG_CMD = 0xf0, 173 REPLY_DEBUG_CMD = 0xf0,
166 DEBUG_LOG_MSG = 0xf7, 174 DEBUG_LOG_MSG = 0xf7,
167 175
@@ -271,38 +279,7 @@ enum {
271 NVM_ACCESS_TARGET_EEPROM = 2, 279 NVM_ACCESS_TARGET_EEPROM = 2,
272}; 280};
273 281
274/** 282/* Section types for NVM_ACCESS_CMD */
275 * struct iwl_nvm_access_cmd_ver1 - Request the device to send the NVM.
276 * @op_code: 0 - read, 1 - write.
277 * @target: NVM_ACCESS_TARGET_*. should be 0 for read.
278 * @cache_refresh: 0 - None, 1- NVM.
279 * @offset: offset in the nvm data.
280 * @length: of the chunk.
281 * @data: empty on read, the NVM chunk on write
282 */
283struct iwl_nvm_access_cmd_ver1 {
284 u8 op_code;
285 u8 target;
286 u8 cache_refresh;
287 u8 reserved;
288 __le16 offset;
289 __le16 length;
290 u8 data[];
291} __packed; /* NVM_ACCESS_CMD_API_S_VER_1 */
292
293/**
294 * struct iwl_nvm_access_resp_ver1 - response to NVM_ACCESS_CMD
295 * @offset: the offset in the nvm data
296 * @length: of the chunk
297 * @data: the nvm chunk on when NVM_ACCESS_CMD was read, nothing on write
298 */
299struct iwl_nvm_access_resp_ver1 {
300 __le16 offset;
301 __le16 length;
302 u8 data[];
303} __packed; /* NVM_ACCESS_CMD_RESP_API_S_VER_1 */
304
305/* Section types for NVM_ACCESS_CMD version 2 */
306enum { 283enum {
307 NVM_SECTION_TYPE_HW = 0, 284 NVM_SECTION_TYPE_HW = 0,
308 NVM_SECTION_TYPE_SW, 285 NVM_SECTION_TYPE_SW,
@@ -323,7 +300,7 @@ enum {
323 * @length: in bytes, to read/write 300 * @length: in bytes, to read/write
324 * @data: if write operation, the data to write. On read its empty 301 * @data: if write operation, the data to write. On read its empty
325 */ 302 */
326struct iwl_nvm_access_cmd_ver2 { 303struct iwl_nvm_access_cmd {
327 u8 op_code; 304 u8 op_code;
328 u8 target; 305 u8 target;
329 __le16 type; 306 __le16 type;
@@ -340,7 +317,7 @@ struct iwl_nvm_access_cmd_ver2 {
340 * @status: 0 for success, fail otherwise 317 * @status: 0 for success, fail otherwise
341 * @data: if read operation, the data returned. Empty on write. 318 * @data: if read operation, the data returned. Empty on write.
342 */ 319 */
343struct iwl_nvm_access_resp_ver2 { 320struct iwl_nvm_access_resp {
344 __le16 offset; 321 __le16 offset;
345 __le16 length; 322 __le16 length;
346 __le16 type; 323 __le16 type;
@@ -503,15 +480,34 @@ enum {
503 TE_DEP_TSF = 2, 480 TE_DEP_TSF = 2,
504 TE_EVENT_SOCIOPATHIC = 4, 481 TE_EVENT_SOCIOPATHIC = 4,
505}; /* MAC_EVENT_DEPENDENCY_POLICY_API_E_VER_2 */ 482}; /* MAC_EVENT_DEPENDENCY_POLICY_API_E_VER_2 */
506 483/*
507/* When to send Time Event notifications and to whom (internal = FW) */ 484 * Supported Time event notifications configuration.
485 * A notification (both event and fragment) includes a status indicating weather
486 * the FW was able to schedule the event or not. For fragment start/end
487 * notification the status is always success. There is no start/end fragment
488 * notification for monolithic events.
489 *
490 * @TE_NOTIF_NONE: no notifications
491 * @TE_NOTIF_HOST_EVENT_START: request/receive notification on event start
492 * @TE_NOTIF_HOST_EVENT_END:request/receive notification on event end
493 * @TE_NOTIF_INTERNAL_EVENT_START: internal FW use
494 * @TE_NOTIF_INTERNAL_EVENT_END: internal FW use.
495 * @TE_NOTIF_HOST_FRAG_START: request/receive notification on frag start
496 * @TE_NOTIF_HOST_FRAG_END:request/receive notification on frag end
497 * @TE_NOTIF_INTERNAL_FRAG_START: internal FW use.
498 * @TE_NOTIF_INTERNAL_FRAG_END: internal FW use.
499 */
508enum { 500enum {
509 TE_NOTIF_NONE = 0, 501 TE_NOTIF_NONE = 0,
510 TE_NOTIF_HOST_START = 0x1, 502 TE_NOTIF_HOST_EVENT_START = 0x1,
511 TE_NOTIF_HOST_END = 0x2, 503 TE_NOTIF_HOST_EVENT_END = 0x2,
512 TE_NOTIF_INTERNAL_START = 0x4, 504 TE_NOTIF_INTERNAL_EVENT_START = 0x4,
513 TE_NOTIF_INTERNAL_END = 0x8 505 TE_NOTIF_INTERNAL_EVENT_END = 0x8,
514}; /* MAC_EVENT_ACTION_API_E_VER_1 */ 506 TE_NOTIF_HOST_FRAG_START = 0x10,
507 TE_NOTIF_HOST_FRAG_END = 0x20,
508 TE_NOTIF_INTERNAL_FRAG_START = 0x40,
509 TE_NOTIF_INTERNAL_FRAG_END = 0x80
510}; /* MAC_EVENT_ACTION_API_E_VER_2 */
515 511
516/* 512/*
517 * @TE_FRAG_NONE: fragmentation of the time event is NOT allowed. 513 * @TE_FRAG_NONE: fragmentation of the time event is NOT allowed.
@@ -762,18 +758,20 @@ struct iwl_phy_context_cmd {
762#define IWL_RX_INFO_PHY_CNT 8 758#define IWL_RX_INFO_PHY_CNT 8
763#define IWL_RX_INFO_AGC_IDX 1 759#define IWL_RX_INFO_AGC_IDX 1
764#define IWL_RX_INFO_RSSI_AB_IDX 2 760#define IWL_RX_INFO_RSSI_AB_IDX 2
765#define IWL_RX_INFO_RSSI_C_IDX 3 761#define IWL_OFDM_AGC_A_MSK 0x0000007f
766#define IWL_OFDM_AGC_DB_MSK 0xfe00 762#define IWL_OFDM_AGC_A_POS 0
767#define IWL_OFDM_AGC_DB_POS 9 763#define IWL_OFDM_AGC_B_MSK 0x00003f80
764#define IWL_OFDM_AGC_B_POS 7
765#define IWL_OFDM_AGC_CODE_MSK 0x3fe00000
766#define IWL_OFDM_AGC_CODE_POS 20
768#define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff 767#define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff
769#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00
770#define IWL_OFDM_RSSI_A_POS 0 768#define IWL_OFDM_RSSI_A_POS 0
769#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00
770#define IWL_OFDM_RSSI_ALLBAND_A_POS 8
771#define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000 771#define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000
772#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000
773#define IWL_OFDM_RSSI_B_POS 16 772#define IWL_OFDM_RSSI_B_POS 16
774#define IWL_OFDM_RSSI_INBAND_C_MSK 0x00ff 773#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000
775#define IWL_OFDM_RSSI_ALLBAND_C_MSK 0xff00 774#define IWL_OFDM_RSSI_ALLBAND_B_POS 24
776#define IWL_OFDM_RSSI_C_POS 0
777 775
778/** 776/**
779 * struct iwl_rx_phy_info - phy info 777 * struct iwl_rx_phy_info - phy info
@@ -792,6 +790,7 @@ struct iwl_phy_context_cmd {
792 * @byte_count: frame's byte-count 790 * @byte_count: frame's byte-count
793 * @frame_time: frame's time on the air, based on byte count and frame rate 791 * @frame_time: frame's time on the air, based on byte count and frame rate
794 * calculation 792 * calculation
793 * @mac_active_msk: what MACs were active when the frame was received
795 * 794 *
796 * Before each Rx, the device sends this data. It contains PHY information 795 * Before each Rx, the device sends this data. It contains PHY information
797 * about the reception of the packet. 796 * about the reception of the packet.
@@ -809,7 +808,7 @@ struct iwl_rx_phy_info {
809 __le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT]; 808 __le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT];
810 __le32 rate_n_flags; 809 __le32 rate_n_flags;
811 __le32 byte_count; 810 __le32 byte_count;
812 __le16 reserved2; 811 __le16 mac_active_msk;
813 __le16 frame_time; 812 __le16 frame_time;
814} __packed; 813} __packed;
815 814
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index d3d959db03a9..e18c92dd60ec 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -79,17 +79,8 @@
79#define UCODE_VALID_OK cpu_to_le32(0x1) 79#define UCODE_VALID_OK cpu_to_le32(0x1)
80 80
81/* Default calibration values for WkP - set to INIT image w/o running */ 81/* Default calibration values for WkP - set to INIT image w/o running */
82static const u8 wkp_calib_values_bb_filter[] = { 0xbf, 0x00, 0x5f, 0x00, 0x2f,
83 0x00, 0x18, 0x00 };
84static const u8 wkp_calib_values_rx_dc[] = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
85 0x7f, 0x7f, 0x7f };
86static const u8 wkp_calib_values_tx_lo[] = { 0x00, 0x00, 0x00, 0x00 };
87static const u8 wkp_calib_values_tx_iq[] = { 0xff, 0x00, 0xff, 0x00, 0x00,
88 0x00 };
89static const u8 wkp_calib_values_rx_iq[] = { 0xff, 0x00, 0x00, 0x00 };
90static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 }; 82static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 };
91static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 }; 83static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 };
92static const u8 wkp_calib_values_xtal[] = { 0xd2, 0xd2 };
93 84
94struct iwl_calib_default_data { 85struct iwl_calib_default_data {
95 u16 size; 86 u16 size;
@@ -99,12 +90,7 @@ struct iwl_calib_default_data {
99#define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf} 90#define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf}
100 91
101static const struct iwl_calib_default_data wkp_calib_default_data[12] = { 92static const struct iwl_calib_default_data wkp_calib_default_data[12] = {
102 [5] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_dc),
103 [6] = CALIB_SIZE_N_DATA(wkp_calib_values_bb_filter),
104 [7] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_lo),
105 [8] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq),
106 [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew), 93 [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew),
107 [10] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq),
108 [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew), 94 [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew),
109}; 95};
110 96
@@ -128,7 +114,7 @@ static int iwl_send_tx_ant_cfg(struct iwl_mvm *mvm, u8 valid_tx_ant)
128 .valid = cpu_to_le32(valid_tx_ant), 114 .valid = cpu_to_le32(valid_tx_ant),
129 }; 115 };
130 116
131 IWL_DEBUG_HC(mvm, "select valid tx ant: %u\n", valid_tx_ant); 117 IWL_DEBUG_FW(mvm, "select valid tx ant: %u\n", valid_tx_ant);
132 return iwl_mvm_send_cmd_pdu(mvm, TX_ANT_CONFIGURATION_CMD, CMD_SYNC, 118 return iwl_mvm_send_cmd_pdu(mvm, TX_ANT_CONFIGURATION_CMD, CMD_SYNC,
133 sizeof(tx_ant_cmd), &tx_ant_cmd); 119 sizeof(tx_ant_cmd), &tx_ant_cmd);
134} 120}
@@ -148,9 +134,10 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
148 alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr); 134 alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr);
149 135
150 alive_data->valid = le16_to_cpu(palive->status) == IWL_ALIVE_STATUS_OK; 136 alive_data->valid = le16_to_cpu(palive->status) == IWL_ALIVE_STATUS_OK;
151 IWL_DEBUG_FW(mvm, "Alive ucode status 0x%04x revision 0x%01X 0x%01X\n", 137 IWL_DEBUG_FW(mvm,
138 "Alive ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
152 le16_to_cpu(palive->status), palive->ver_type, 139 le16_to_cpu(palive->status), palive->ver_type,
153 palive->ver_subtype); 140 palive->ver_subtype, palive->flags);
154 141
155 return true; 142 return true;
156} 143}
@@ -241,20 +228,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
241 228
242 return 0; 229 return 0;
243} 230}
244#define IWL_HW_REV_ID_RAINBOW 0x2
245#define IWL_PROJ_TYPE_LHP 0x5
246
247static u32 iwl_mvm_build_phy_cfg(struct iwl_mvm *mvm)
248{
249 struct iwl_nvm_data *data = mvm->nvm_data;
250 /* Temp calls to static definitions, will be changed to CSR calls */
251 u8 hw_rev_id = IWL_HW_REV_ID_RAINBOW;
252 u8 project_type = IWL_PROJ_TYPE_LHP;
253
254 return data->radio_cfg_dash | (data->radio_cfg_step << 2) |
255 (hw_rev_id << 4) | ((project_type & 0x7f) << 6) |
256 (data->valid_tx_ant << 16) | (data->valid_rx_ant << 20);
257}
258 231
259static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) 232static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
260{ 233{
@@ -262,7 +235,7 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
262 enum iwl_ucode_type ucode_type = mvm->cur_ucode; 235 enum iwl_ucode_type ucode_type = mvm->cur_ucode;
263 236
264 /* Set parameters */ 237 /* Set parameters */
265 phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_build_phy_cfg(mvm)); 238 phy_cfg_cmd.phy_cfg = cpu_to_le32(mvm->fw->phy_config);
266 phy_cfg_cmd.calib_control.event_trigger = 239 phy_cfg_cmd.calib_control.event_trigger =
267 mvm->fw->default_calib[ucode_type].event_trigger; 240 mvm->fw->default_calib[ucode_type].event_trigger;
268 phy_cfg_cmd.calib_control.flow_trigger = 241 phy_cfg_cmd.calib_control.flow_trigger =
@@ -275,103 +248,6 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
275 sizeof(phy_cfg_cmd), &phy_cfg_cmd); 248 sizeof(phy_cfg_cmd), &phy_cfg_cmd);
276} 249}
277 250
278/* Starting with the new PHY DB implementation - New calibs are enabled */
279/* Value - 0x405e7 */
280#define IWL_CALIB_DEFAULT_FLOW_INIT (IWL_CALIB_CFG_XTAL_IDX |\
281 IWL_CALIB_CFG_TEMPERATURE_IDX |\
282 IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
283 IWL_CALIB_CFG_DC_IDX |\
284 IWL_CALIB_CFG_BB_FILTER_IDX |\
285 IWL_CALIB_CFG_LO_LEAKAGE_IDX |\
286 IWL_CALIB_CFG_TX_IQ_IDX |\
287 IWL_CALIB_CFG_RX_IQ_IDX |\
288 IWL_CALIB_CFG_AGC_IDX)
289
290#define IWL_CALIB_DEFAULT_EVENT_INIT 0x0
291
292/* Value 0x41567 */
293#define IWL_CALIB_DEFAULT_FLOW_RUN (IWL_CALIB_CFG_XTAL_IDX |\
294 IWL_CALIB_CFG_TEMPERATURE_IDX |\
295 IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
296 IWL_CALIB_CFG_BB_FILTER_IDX |\
297 IWL_CALIB_CFG_DC_IDX |\
298 IWL_CALIB_CFG_TX_IQ_IDX |\
299 IWL_CALIB_CFG_RX_IQ_IDX |\
300 IWL_CALIB_CFG_SENSITIVITY_IDX |\
301 IWL_CALIB_CFG_AGC_IDX)
302
303#define IWL_CALIB_DEFAULT_EVENT_RUN (IWL_CALIB_CFG_XTAL_IDX |\
304 IWL_CALIB_CFG_TEMPERATURE_IDX |\
305 IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
306 IWL_CALIB_CFG_TX_PWR_IDX |\
307 IWL_CALIB_CFG_DC_IDX |\
308 IWL_CALIB_CFG_TX_IQ_IDX |\
309 IWL_CALIB_CFG_SENSITIVITY_IDX)
310
311/*
312 * Sets the calibrations trigger values that will be sent to the FW for runtime
313 * and init calibrations.
314 * The ones given in the FW TLV are not correct.
315 */
316static void iwl_set_default_calib_trigger(struct iwl_mvm *mvm)
317{
318 struct iwl_tlv_calib_ctrl default_calib;
319
320 /*
321 * WkP FW TLV calib bits are wrong, overwrite them.
322 * This defines the dynamic calibrations which are implemented in the
323 * uCode both for init(flow) calculation and event driven calibs.
324 */
325
326 /* Init Image */
327 default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_INIT);
328 default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_INIT);
329
330 if (default_calib.event_trigger !=
331 mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger)
332 IWL_ERR(mvm,
333 "Updating the event calib for INIT image: 0x%x -> 0x%x\n",
334 mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger,
335 default_calib.event_trigger);
336 if (default_calib.flow_trigger !=
337 mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger)
338 IWL_ERR(mvm,
339 "Updating the flow calib for INIT image: 0x%x -> 0x%x\n",
340 mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger,
341 default_calib.flow_trigger);
342
343 memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_INIT],
344 &default_calib, sizeof(struct iwl_tlv_calib_ctrl));
345 IWL_ERR(mvm,
346 "Setting uCode init calibrations event 0x%x, trigger 0x%x\n",
347 default_calib.event_trigger,
348 default_calib.flow_trigger);
349
350 /* Run time image */
351 default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_RUN);
352 default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_RUN);
353
354 if (default_calib.event_trigger !=
355 mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger)
356 IWL_ERR(mvm,
357 "Updating the event calib for RT image: 0x%x -> 0x%x\n",
358 mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger,
359 default_calib.event_trigger);
360 if (default_calib.flow_trigger !=
361 mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger)
362 IWL_ERR(mvm,
363 "Updating the flow calib for RT image: 0x%x -> 0x%x\n",
364 mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger,
365 default_calib.flow_trigger);
366
367 memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_REGULAR],
368 &default_calib, sizeof(struct iwl_tlv_calib_ctrl));
369 IWL_ERR(mvm,
370 "Setting uCode runtime calibs event 0x%x, trigger 0x%x\n",
371 default_calib.event_trigger,
372 default_calib.flow_trigger);
373}
374
375static int iwl_set_default_calibrations(struct iwl_mvm *mvm) 251static int iwl_set_default_calibrations(struct iwl_mvm *mvm)
376{ 252{
377 u8 cmd_raw[16]; /* holds the variable size commands */ 253 u8 cmd_raw[16]; /* holds the variable size commands */
@@ -434,6 +310,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
434 goto error; 310 goto error;
435 } 311 }
436 312
313 ret = iwl_send_bt_prio_tbl(mvm);
314 if (ret)
315 goto error;
316
437 if (read_nvm) { 317 if (read_nvm) {
438 /* Read nvm */ 318 /* Read nvm */
439 ret = iwl_nvm_init(mvm); 319 ret = iwl_nvm_init(mvm);
@@ -446,15 +326,15 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
446 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); 326 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
447 WARN_ON(ret); 327 WARN_ON(ret);
448 328
449 /* Override the calibrations from TLV and the const of fw */ 329 /* Send TX valid antennas before triggering calibrations */
450 iwl_set_default_calib_trigger(mvm); 330 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
331 if (ret)
332 goto error;
451 333
452 /* WkP doesn't have all calibrations, need to set default values */ 334 /* need to set default values */
453 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 335 ret = iwl_set_default_calibrations(mvm);
454 ret = iwl_set_default_calibrations(mvm); 336 if (ret)
455 if (ret) 337 goto error;
456 goto error;
457 }
458 338
459 /* 339 /*
460 * Send phy configurations command to init uCode 340 * Send phy configurations command to init uCode
@@ -533,7 +413,15 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
533 goto error; 413 goto error;
534 } 414 }
535 415
536 ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); 416 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
417 if (ret)
418 goto error;
419
420 ret = iwl_send_bt_prio_tbl(mvm);
421 if (ret)
422 goto error;
423
424 ret = iwl_send_bt_init_conf(mvm);
537 if (ret) 425 if (ret)
538 goto error; 426 goto error;
539 427
@@ -579,7 +467,7 @@ int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)
579 goto error; 467 goto error;
580 } 468 }
581 469
582 ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); 470 ret = iwl_send_tx_ant_cfg(mvm, iwl_fw_valid_tx_ant(mvm->fw));
583 if (ret) 471 if (ret)
584 goto error; 472 goto error;
585 473
diff --git a/drivers/net/wireless/iwlwifi/mvm/led.c b/drivers/net/wireless/iwlwifi/mvm/led.c
index 011906e73a05..2269a9e5cc67 100644
--- a/drivers/net/wireless/iwlwifi/mvm/led.c
+++ b/drivers/net/wireless/iwlwifi/mvm/led.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 1d20287b1120..e6eca4d66f6c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -196,7 +196,7 @@ u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
196 u32 qmask, ac; 196 u32 qmask, ac;
197 197
198 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) 198 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
199 return BIT(IWL_OFFCHANNEL_QUEUE); 199 return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
200 200
201 qmask = (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) ? 201 qmask = (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE) ?
202 BIT(vif->cab_queue) : 0; 202 BIT(vif->cab_queue) : 0;
@@ -553,9 +553,9 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
553 if (vif->bss_conf.qos) 553 if (vif->bss_conf.qos)
554 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); 554 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);
555 555
556 /* Don't use cts to self as the fw doesn't support it currently. */
556 if (vif->bss_conf.use_cts_prot) 557 if (vif->bss_conf.use_cts_prot)
557 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT | 558 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
558 MAC_PROT_FLG_SELF_CTS_EN);
559 559
560 /* 560 /*
561 * I think that we should enable these 2 flags regardless the HT PROT 561 * I think that we should enable these 2 flags regardless the HT PROT
@@ -651,6 +651,13 @@ static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm,
651 /* Fill the common data for all mac context types */ 651 /* Fill the common data for all mac context types */
652 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 652 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
653 653
654 /* Allow beacons to pass through as long as we are not associated,or we
655 * do not have dtim period information */
656 if (!vif->bss_conf.assoc || !vif->bss_conf.dtim_period)
657 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_BEACON);
658 else
659 cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON);
660
654 /* Fill the data specific for station mode */ 661 /* Fill the data specific for station mode */
655 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta); 662 iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta);
656 663
@@ -687,7 +694,12 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
687 WARN_ON(vif->type != NL80211_IFTYPE_MONITOR); 694 WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);
688 695
689 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 696 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
690 /* No other data to be filled */ 697
698 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC |
699 MAC_FILTER_IN_CONTROL_AND_MGMT |
700 MAC_FILTER_IN_BEACON |
701 MAC_FILTER_IN_PROBE_REQUEST);
702
691 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); 703 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
692} 704}
693 705
@@ -716,7 +728,9 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm,
716 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 728 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
717 729
718 cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); 730 cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
719 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROMISC); 731
732 /* Override the filter flags to accept only probe requests */
733 cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);
720 734
721 /* 735 /*
722 * This flag should be set to true when the P2P Device is 736 * This flag should be set to true when the P2P Device is
@@ -791,7 +805,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
791 TX_CMD_FLG_TSF); 805 TX_CMD_FLG_TSF);
792 806
793 mvm->mgmt_last_antenna_idx = 807 mvm->mgmt_last_antenna_idx =
794 iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant, 808 iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw),
795 mvm->mgmt_last_antenna_idx); 809 mvm->mgmt_last_antenna_idx);
796 810
797 beacon_cmd.tx.rate_n_flags = 811 beacon_cmd.tx.rate_n_flags =
@@ -848,10 +862,10 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
848 */ 862 */
849static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm, 863static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
850 struct ieee80211_vif *vif, 864 struct ieee80211_vif *vif,
851 struct iwl_mac_data_ap *ctxt_ap) 865 struct iwl_mac_data_ap *ctxt_ap,
866 bool add)
852{ 867{
853 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 868 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
854 u32 curr_dev_time;
855 869
856 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int); 870 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int);
857 ctxt_ap->bi_reciprocal = 871 ctxt_ap->bi_reciprocal =
@@ -863,10 +877,19 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
863 vif->bss_conf.dtim_period)); 877 vif->bss_conf.dtim_period));
864 878
865 ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue); 879 ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue);
866 curr_dev_time = iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);
867 ctxt_ap->beacon_time = cpu_to_le32(curr_dev_time);
868 880
869 ctxt_ap->beacon_tsf = cpu_to_le64(curr_dev_time); 881 /*
882 * Only read the system time when the MAC is being added, when we
883 * just modify the MAC then we should keep the time -- the firmware
884 * can otherwise have a "jumping" TBTT.
885 */
886 if (add)
887 mvmvif->ap_beacon_time =
888 iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);
889
890 ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time);
891
892 ctxt_ap->beacon_tsf = 0; /* unused */
870 893
871 /* TODO: Assume that the beacon id == mac context id */ 894 /* TODO: Assume that the beacon id == mac context id */
872 ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id); 895 ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id);
@@ -883,8 +906,12 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm,
883 /* Fill the common data for all mac context types */ 906 /* Fill the common data for all mac context types */
884 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 907 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
885 908
909 /* Also enable probe requests to pass */
910 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);
911
886 /* Fill the data specific for ap mode */ 912 /* Fill the data specific for ap mode */
887 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap); 913 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap,
914 action == FW_CTXT_ACTION_ADD);
888 915
889 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); 916 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
890} 917}
@@ -902,7 +929,8 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
902 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); 929 iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
903 930
904 /* Fill the data specific for GO mode */ 931 /* Fill the data specific for GO mode */
905 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap); 932 iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap,
933 action == FW_CTXT_ACTION_ADD);
906 934
907 cmd.go.ctwin = cpu_to_le32(noa->oppps_ctwindow & 935 cmd.go.ctwin = cpu_to_le32(noa->oppps_ctwindow &
908 IEEE80211_P2P_OPPPS_CTWINDOW_MASK); 936 IEEE80211_P2P_OPPPS_CTWINDOW_MASK);
@@ -996,3 +1024,22 @@ int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
996 mvmvif->uploaded = false; 1024 mvmvif->uploaded = false;
997 return 0; 1025 return 0;
998} 1026}
1027
1028int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
1029 struct iwl_rx_cmd_buffer *rxb,
1030 struct iwl_device_cmd *cmd)
1031{
1032 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1033 struct iwl_beacon_notif *beacon = (void *)pkt->data;
1034 u16 status __maybe_unused =
1035 le16_to_cpu(beacon->beacon_notify_hdr.status.status);
1036 u32 rate __maybe_unused =
1037 le32_to_cpu(beacon->beacon_notify_hdr.initial_rate);
1038
1039 IWL_DEBUG_RX(mvm, "beacon status %#x retries:%d tsf:0x%16llX rate:%d\n",
1040 status & TX_STATUS_MSK,
1041 beacon->beacon_notify_hdr.failure_frame,
1042 le64_to_cpu(beacon->tsf),
1043 rate);
1044 return 0;
1045}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 23460f4a4c75..fe031608fd91 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -65,7 +65,9 @@
65#include <linux/skbuff.h> 65#include <linux/skbuff.h>
66#include <linux/netdevice.h> 66#include <linux/netdevice.h>
67#include <linux/etherdevice.h> 67#include <linux/etherdevice.h>
68#include <linux/ip.h>
68#include <net/mac80211.h> 69#include <net/mac80211.h>
70#include <net/tcp.h>
69 71
70#include "iwl-op-mode.h" 72#include "iwl-op-mode.h"
71#include "iwl-io.h" 73#include "iwl-io.h"
@@ -102,10 +104,33 @@ static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
102 }, 104 },
103}; 105};
104 106
107#ifdef CONFIG_PM_SLEEP
108static const struct nl80211_wowlan_tcp_data_token_feature
109iwl_mvm_wowlan_tcp_token_feature = {
110 .min_len = 0,
111 .max_len = 255,
112 .bufsize = IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS,
113};
114
115static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = {
116 .tok = &iwl_mvm_wowlan_tcp_token_feature,
117 .data_payload_max = IWL_WOWLAN_TCP_MAX_PACKET_LEN -
118 sizeof(struct ethhdr) -
119 sizeof(struct iphdr) -
120 sizeof(struct tcphdr),
121 .data_interval_max = 65535, /* __le16 in API */
122 .wake_payload_max = IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN -
123 sizeof(struct ethhdr) -
124 sizeof(struct iphdr) -
125 sizeof(struct tcphdr),
126 .seq = true,
127};
128#endif
129
105int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) 130int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
106{ 131{
107 struct ieee80211_hw *hw = mvm->hw; 132 struct ieee80211_hw *hw = mvm->hw;
108 int num_mac, ret; 133 int num_mac, ret, i;
109 134
110 /* Tell mac80211 our characteristics */ 135 /* Tell mac80211 our characteristics */
111 hw->flags = IEEE80211_HW_SIGNAL_DBM | 136 hw->flags = IEEE80211_HW_SIGNAL_DBM |
@@ -118,8 +143,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
118 IEEE80211_HW_AMPDU_AGGREGATION | 143 IEEE80211_HW_AMPDU_AGGREGATION |
119 IEEE80211_HW_TIMING_BEACON_ONLY; 144 IEEE80211_HW_TIMING_BEACON_ONLY;
120 145
121 hw->queues = IWL_FIRST_AMPDU_QUEUE; 146 hw->queues = IWL_MVM_FIRST_AGG_QUEUE;
122 hw->offchannel_tx_hw_queue = IWL_OFFCHANNEL_QUEUE; 147 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
123 hw->rate_control_algorithm = "iwl-mvm-rs"; 148 hw->rate_control_algorithm = "iwl-mvm-rs";
124 149
125 /* 150 /*
@@ -149,18 +174,22 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
149 hw->wiphy->n_iface_combinations = 174 hw->wiphy->n_iface_combinations =
150 ARRAY_SIZE(iwl_mvm_iface_combinations); 175 ARRAY_SIZE(iwl_mvm_iface_combinations);
151 176
152 hw->wiphy->max_remain_on_channel_duration = 500; 177 hw->wiphy->max_remain_on_channel_duration = 10000;
153 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; 178 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
154 179
155 /* Extract MAC address */ 180 /* Extract MAC address */
156 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN); 181 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
157 hw->wiphy->addresses = mvm->addresses; 182 hw->wiphy->addresses = mvm->addresses;
158 hw->wiphy->n_addresses = 1; 183 hw->wiphy->n_addresses = 1;
159 num_mac = mvm->nvm_data->n_hw_addrs; 184
160 if (num_mac > 1) { 185 /* Extract additional MAC addresses if available */
161 memcpy(mvm->addresses[1].addr, mvm->addresses[0].addr, 186 num_mac = (mvm->nvm_data->n_hw_addrs > 1) ?
187 min(IWL_MVM_MAX_ADDRESSES, mvm->nvm_data->n_hw_addrs) : 1;
188
189 for (i = 1; i < num_mac; i++) {
190 memcpy(mvm->addresses[i].addr, mvm->addresses[i-1].addr,
162 ETH_ALEN); 191 ETH_ALEN);
163 mvm->addresses[1].addr[5]++; 192 mvm->addresses[i].addr[5]++;
164 hw->wiphy->n_addresses++; 193 hw->wiphy->n_addresses++;
165 } 194 }
166 195
@@ -206,6 +235,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
206 hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS; 235 hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
207 hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN; 236 hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
208 hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN; 237 hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
238 hw->wiphy->wowlan.tcp = &iwl_mvm_wowlan_tcp_support;
209 } 239 }
210#endif 240#endif
211 241
@@ -227,7 +257,7 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
227 goto drop; 257 goto drop;
228 } 258 }
229 259
230 if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_OFFCHANNEL_QUEUE && 260 if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
231 !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status)) 261 !test_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status))
232 goto drop; 262 goto drop;
233 263
@@ -273,12 +303,18 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
273 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); 303 ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false);
274 break; 304 break;
275 case IEEE80211_AMPDU_TX_START: 305 case IEEE80211_AMPDU_TX_START:
306 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) {
307 ret = -EINVAL;
308 break;
309 }
276 ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn); 310 ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn);
277 break; 311 break;
278 case IEEE80211_AMPDU_TX_STOP_CONT: 312 case IEEE80211_AMPDU_TX_STOP_CONT:
313 ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid);
314 break;
279 case IEEE80211_AMPDU_TX_STOP_FLUSH: 315 case IEEE80211_AMPDU_TX_STOP_FLUSH:
280 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: 316 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
281 ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid); 317 ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid);
282 break; 318 break;
283 case IEEE80211_AMPDU_TX_OPERATIONAL: 319 case IEEE80211_AMPDU_TX_OPERATIONAL:
284 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size); 320 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size);
@@ -466,11 +502,15 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
466 /* 502 /*
467 * TODO: remove this temporary code. 503 * TODO: remove this temporary code.
468 * Currently MVM FW supports power management only on single MAC. 504 * Currently MVM FW supports power management only on single MAC.
469 * Iterate and disable PM on all active interfaces. 505 * If new interface added, disable PM on existing interface.
506 * P2P device is a special case, since it is handled by FW similary to
507 * scan. If P2P deviced is added, PM remains enabled on existing
508 * interface.
470 * Note: the method below does not count the new interface being added 509 * Note: the method below does not count the new interface being added
471 * at this moment. 510 * at this moment.
472 */ 511 */
473 mvm->vif_count++; 512 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
513 mvm->vif_count++;
474 if (mvm->vif_count > 1) { 514 if (mvm->vif_count > 1) {
475 IWL_DEBUG_MAC80211(mvm, 515 IWL_DEBUG_MAC80211(mvm,
476 "Disable power on existing interfaces\n"); 516 "Disable power on existing interfaces\n");
@@ -526,6 +566,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
526 mvm->p2p_device_vif = vif; 566 mvm->p2p_device_vif = vif;
527 } 567 }
528 568
569 iwl_mvm_vif_dbgfs_register(mvm, vif);
529 goto out_unlock; 570 goto out_unlock;
530 571
531 out_unbind: 572 out_unbind:
@@ -539,10 +580,11 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
539 /* 580 /*
540 * TODO: remove this temporary code. 581 * TODO: remove this temporary code.
541 * Currently MVM FW supports power management only on single MAC. 582 * Currently MVM FW supports power management only on single MAC.
542 * Check if only one additional interface remains after rereasing 583 * Check if only one additional interface remains after releasing
543 * current one. Update power mode on the remaining interface. 584 * current one. Update power mode on the remaining interface.
544 */ 585 */
545 mvm->vif_count--; 586 if (vif->type != NL80211_IFTYPE_P2P_DEVICE)
587 mvm->vif_count--;
546 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", 588 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
547 mvm->vif_count); 589 mvm->vif_count);
548 if (mvm->vif_count == 1) { 590 if (mvm->vif_count == 1) {
@@ -557,11 +599,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
557 return ret; 599 return ret;
558} 600}
559 601
560static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, 602static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
561 struct ieee80211_vif *vif) 603 struct ieee80211_vif *vif)
562{ 604{
563 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
564 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
565 u32 tfd_msk = 0, ac; 605 u32 tfd_msk = 0, ac;
566 606
567 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 607 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
@@ -594,12 +634,23 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
594 */ 634 */
595 flush_work(&mvm->sta_drained_wk); 635 flush_work(&mvm->sta_drained_wk);
596 } 636 }
637}
638
639static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
640 struct ieee80211_vif *vif)
641{
642 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
643 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
644
645 iwl_mvm_prepare_mac_removal(mvm, vif);
597 646
598 mutex_lock(&mvm->mutex); 647 mutex_lock(&mvm->mutex);
599 648
649 iwl_mvm_vif_dbgfs_clean(mvm, vif);
650
600 /* 651 /*
601 * For AP/GO interface, the tear down of the resources allocated to the 652 * For AP/GO interface, the tear down of the resources allocated to the
602 * interface should be handled as part of the bss_info_changed flow. 653 * interface is be handled as part of the stop_ap flow.
603 */ 654 */
604 if (vif->type == NL80211_IFTYPE_AP) { 655 if (vif->type == NL80211_IFTYPE_AP) {
605 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); 656 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
@@ -620,7 +671,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
620 * Check if only one additional interface remains after removing 671 * Check if only one additional interface remains after removing
621 * current one. Update power mode on the remaining interface. 672 * current one. Update power mode on the remaining interface.
622 */ 673 */
623 if (mvm->vif_count) 674 if (mvm->vif_count && vif->type != NL80211_IFTYPE_P2P_DEVICE)
624 mvm->vif_count--; 675 mvm->vif_count--;
625 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n", 676 IWL_DEBUG_MAC80211(mvm, "Currently %d interfaces active\n",
626 mvm->vif_count); 677 mvm->vif_count);
@@ -670,6 +721,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
670 IWL_ERR(mvm, "failed to update quotas\n"); 721 IWL_ERR(mvm, "failed to update quotas\n");
671 return; 722 return;
672 } 723 }
724 iwl_mvm_bt_coex_vif_assoc(mvm, vif);
673 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { 725 } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
674 /* remove AP station now that the MAC is unassoc */ 726 /* remove AP station now that the MAC is unassoc */
675 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); 727 ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id);
@@ -763,6 +815,8 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
763 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 815 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
764 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 816 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
765 817
818 iwl_mvm_prepare_mac_removal(mvm, vif);
819
766 mutex_lock(&mvm->mutex); 820 mutex_lock(&mvm->mutex);
767 821
768 mvmvif->ap_active = false; 822 mvmvif->ap_active = false;
@@ -886,7 +940,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
886 */ 940 */
887 break; 941 break;
888 case STA_NOTIFY_AWAKE: 942 case STA_NOTIFY_AWAKE:
889 if (WARN_ON(mvmsta->sta_id == IWL_INVALID_STATION)) 943 if (WARN_ON(mvmsta->sta_id == IWL_MVM_STATION_COUNT))
890 break; 944 break;
891 iwl_mvm_sta_modify_ps_wake(mvm, sta); 945 iwl_mvm_sta_modify_ps_wake(mvm, sta);
892 break; 946 break;
@@ -1042,6 +1096,13 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1042 1096
1043 switch (cmd) { 1097 switch (cmd) {
1044 case SET_KEY: 1098 case SET_KEY:
1099 if (vif->type == NL80211_IFTYPE_AP && !sta) {
1100 /* GTK on AP interface is a TX-only key, return 0 */
1101 ret = 0;
1102 key->hw_key_idx = STA_KEY_IDX_INVALID;
1103 break;
1104 }
1105
1045 IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n"); 1106 IWL_DEBUG_MAC80211(mvm, "set hwcrypto key\n");
1046 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false); 1107 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, false);
1047 if (ret) { 1108 if (ret) {
@@ -1050,11 +1111,17 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
1050 * can't add key for RX, but we don't need it 1111 * can't add key for RX, but we don't need it
1051 * in the device for TX so still return 0 1112 * in the device for TX so still return 0
1052 */ 1113 */
1114 key->hw_key_idx = STA_KEY_IDX_INVALID;
1053 ret = 0; 1115 ret = 0;
1054 } 1116 }
1055 1117
1056 break; 1118 break;
1057 case DISABLE_KEY: 1119 case DISABLE_KEY:
1120 if (key->hw_key_idx == STA_KEY_IDX_INVALID) {
1121 ret = 0;
1122 break;
1123 }
1124
1058 IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n"); 1125 IWL_DEBUG_MAC80211(mvm, "disable hwcrypto key\n");
1059 ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key); 1126 ret = iwl_mvm_remove_sta_key(mvm, vif, sta, key);
1060 break; 1127 break;
@@ -1103,7 +1170,7 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
1103 &chandef, 1, 1); 1170 &chandef, 1, 1);
1104 1171
1105 /* Schedule the time events */ 1172 /* Schedule the time events */
1106 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration); 1173 ret = iwl_mvm_start_p2p_roc(mvm, vif, duration, type);
1107 1174
1108 mutex_unlock(&mvm->mutex); 1175 mutex_unlock(&mvm->mutex);
1109 IWL_DEBUG_MAC80211(mvm, "leave\n"); 1176 IWL_DEBUG_MAC80211(mvm, "leave\n");
@@ -1207,6 +1274,7 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
1207 * will handle quota settings. 1274 * will handle quota settings.
1208 */ 1275 */
1209 if (vif->type == NL80211_IFTYPE_MONITOR) { 1276 if (vif->type == NL80211_IFTYPE_MONITOR) {
1277 mvmvif->monitor_active = true;
1210 ret = iwl_mvm_update_quotas(mvm, vif); 1278 ret = iwl_mvm_update_quotas(mvm, vif);
1211 if (ret) 1279 if (ret)
1212 goto out_remove_binding; 1280 goto out_remove_binding;
@@ -1237,15 +1305,16 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
1237 if (vif->type == NL80211_IFTYPE_AP) 1305 if (vif->type == NL80211_IFTYPE_AP)
1238 goto out_unlock; 1306 goto out_unlock;
1239 1307
1240 iwl_mvm_binding_remove_vif(mvm, vif);
1241 switch (vif->type) { 1308 switch (vif->type) {
1242 case NL80211_IFTYPE_MONITOR: 1309 case NL80211_IFTYPE_MONITOR:
1243 iwl_mvm_update_quotas(mvm, vif); 1310 mvmvif->monitor_active = false;
1311 iwl_mvm_update_quotas(mvm, NULL);
1244 break; 1312 break;
1245 default: 1313 default:
1246 break; 1314 break;
1247 } 1315 }
1248 1316
1317 iwl_mvm_binding_remove_vif(mvm, vif);
1249out_unlock: 1318out_unlock:
1250 mvmvif->phy_ctxt = NULL; 1319 mvmvif->phy_ctxt = NULL;
1251 mutex_unlock(&mvm->mutex); 1320 mutex_unlock(&mvm->mutex);
@@ -1266,6 +1335,15 @@ static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
1266 return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif); 1335 return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif);
1267} 1336}
1268 1337
1338static void iwl_mvm_mac_rssi_callback(struct ieee80211_hw *hw,
1339 struct ieee80211_vif *vif,
1340 enum ieee80211_rssi_event rssi_event)
1341{
1342 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1343
1344 iwl_mvm_bt_rssi_event(mvm, vif, rssi_event);
1345}
1346
1269struct ieee80211_ops iwl_mvm_hw_ops = { 1347struct ieee80211_ops iwl_mvm_hw_ops = {
1270 .tx = iwl_mvm_mac_tx, 1348 .tx = iwl_mvm_mac_tx,
1271 .ampdu_action = iwl_mvm_mac_ampdu_action, 1349 .ampdu_action = iwl_mvm_mac_ampdu_action,
@@ -1289,6 +1367,7 @@ struct ieee80211_ops iwl_mvm_hw_ops = {
1289 .update_tkip_key = iwl_mvm_mac_update_tkip_key, 1367 .update_tkip_key = iwl_mvm_mac_update_tkip_key,
1290 .remain_on_channel = iwl_mvm_roc, 1368 .remain_on_channel = iwl_mvm_roc,
1291 .cancel_remain_on_channel = iwl_mvm_cancel_roc, 1369 .cancel_remain_on_channel = iwl_mvm_cancel_roc,
1370 .rssi_callback = iwl_mvm_mac_rssi_callback,
1292 1371
1293 .add_chanctx = iwl_mvm_add_chanctx, 1372 .add_chanctx = iwl_mvm_add_chanctx,
1294 .remove_chanctx = iwl_mvm_remove_chanctx, 1373 .remove_chanctx = iwl_mvm_remove_chanctx,
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 4e339ccfa800..8269bc562951 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -79,8 +79,9 @@
79#include "fw-api.h" 79#include "fw-api.h"
80 80
81#define IWL_INVALID_MAC80211_QUEUE 0xff 81#define IWL_INVALID_MAC80211_QUEUE 0xff
82#define IWL_MVM_MAX_ADDRESSES 2 82#define IWL_MVM_MAX_ADDRESSES 5
83#define IWL_RSSI_OFFSET 44 83/* RSSI offset for WkP */
84#define IWL_RSSI_OFFSET 50
84 85
85enum iwl_mvm_tx_fifo { 86enum iwl_mvm_tx_fifo {
86 IWL_MVM_TX_FIFO_BK = 0, 87 IWL_MVM_TX_FIFO_BK = 0,
@@ -89,10 +90,6 @@ enum iwl_mvm_tx_fifo {
89 IWL_MVM_TX_FIFO_VO, 90 IWL_MVM_TX_FIFO_VO,
90}; 91};
91 92
92/* Placeholder */
93#define IWL_OFFCHANNEL_QUEUE 8
94#define IWL_FIRST_AMPDU_QUEUE 11
95
96extern struct ieee80211_ops iwl_mvm_hw_ops; 93extern struct ieee80211_ops iwl_mvm_hw_ops;
97/** 94/**
98 * struct iwl_mvm_mod_params - module parameters for iwlmvm 95 * struct iwl_mvm_mod_params - module parameters for iwlmvm
@@ -160,6 +157,8 @@ enum iwl_power_scheme {
160 * @uploaded: indicates the MAC context has been added to the device 157 * @uploaded: indicates the MAC context has been added to the device
161 * @ap_active: indicates that ap context is configured, and that the interface 158 * @ap_active: indicates that ap context is configured, and that the interface
162 * should get quota etc. 159 * should get quota etc.
160 * @monitor_active: indicates that monitor context is configured, and that the
161 * interface should get quota etc.
163 * @queue_params: QoS params for this MAC 162 * @queue_params: QoS params for this MAC
164 * @bcast_sta: station used for broadcast packets. Used by the following 163 * @bcast_sta: station used for broadcast packets. Used by the following
165 * vifs: P2P_DEVICE, GO and AP. 164 * vifs: P2P_DEVICE, GO and AP.
@@ -172,6 +171,9 @@ struct iwl_mvm_vif {
172 171
173 bool uploaded; 172 bool uploaded;
174 bool ap_active; 173 bool ap_active;
174 bool monitor_active;
175
176 u32 ap_beacon_time;
175 177
176 enum iwl_tsf_id tsf_id; 178 enum iwl_tsf_id tsf_id;
177 179
@@ -210,6 +212,7 @@ struct iwl_mvm_vif {
210 212
211#ifdef CONFIG_IWLWIFI_DEBUGFS 213#ifdef CONFIG_IWLWIFI_DEBUGFS
212 struct dentry *dbgfs_dir; 214 struct dentry *dbgfs_dir;
215 struct dentry *dbgfs_slink;
213 void *dbgfs_data; 216 void *dbgfs_data;
214#endif 217#endif
215}; 218};
@@ -278,10 +281,7 @@ struct iwl_mvm {
278 atomic_t queue_stop_count[IWL_MAX_HW_QUEUES]; 281 atomic_t queue_stop_count[IWL_MAX_HW_QUEUES];
279 282
280 struct iwl_nvm_data *nvm_data; 283 struct iwl_nvm_data *nvm_data;
281 /* eeprom blob for debugfs/testmode */ 284 /* NVM sections */
282 u8 *eeprom_blob;
283 size_t eeprom_blob_size;
284 /* NVM sections for 7000 family */
285 struct iwl_nvm_section nvm_sections[NVM_NUM_OF_SECTIONS]; 285 struct iwl_nvm_section nvm_sections[NVM_NUM_OF_SECTIONS];
286 286
287 /* EEPROM MAC addresses */ 287 /* EEPROM MAC addresses */
@@ -322,11 +322,26 @@ struct iwl_mvm {
322 * can hold 16 keys at most. Reflect this fact. 322 * can hold 16 keys at most. Reflect this fact.
323 */ 323 */
324 unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)]; 324 unsigned long fw_key_table[BITS_TO_LONGS(STA_KEY_MAX_NUM)];
325
326 /*
327 * This counter of created interfaces is referenced only in conjunction
328 * with FW limitation related to power management. Currently PM is
329 * supported only on a single interface.
330 * IMPORTANT: this variable counts all interfaces except P2P device.
331 */
325 u8 vif_count; 332 u8 vif_count;
326 333
327 struct led_classdev led; 334 struct led_classdev led;
328 335
329 struct ieee80211_vif *p2p_device_vif; 336 struct ieee80211_vif *p2p_device_vif;
337
338#ifdef CONFIG_PM_SLEEP
339 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
340#endif
341
342 /* BT-Coex */
343 u8 bt_kill_msk;
344 struct iwl_bt_coex_profile_notif last_bt_notif;
330}; 345};
331 346
332/* Extract MVM priv from op_mode and _hw */ 347/* Extract MVM priv from op_mode and _hw */
@@ -440,6 +455,9 @@ u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
440 struct ieee80211_vif *vif); 455 struct ieee80211_vif *vif);
441int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, 456int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
442 struct ieee80211_vif *vif); 457 struct ieee80211_vif *vif);
458int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
459 struct iwl_rx_cmd_buffer *rxb,
460 struct iwl_device_cmd *cmd);
443 461
444/* Bindings */ 462/* Bindings */
445int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 463int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -461,16 +479,22 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm);
461/* MVM debugfs */ 479/* MVM debugfs */
462#ifdef CONFIG_IWLWIFI_DEBUGFS 480#ifdef CONFIG_IWLWIFI_DEBUGFS
463int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir); 481int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir);
464int iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 482void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
465 struct dentry *dbgfs_dir); 483void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
466void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
467 struct iwl_powertable_cmd *cmd);
468#else 484#else
469static inline int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, 485static inline int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm,
470 struct dentry *dbgfs_dir) 486 struct dentry *dbgfs_dir)
471{ 487{
472 return 0; 488 return 0;
473} 489}
490static inline void
491iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
492{
493}
494static inline void
495iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
496{
497}
474#endif /* CONFIG_IWLWIFI_DEBUGFS */ 498#endif /* CONFIG_IWLWIFI_DEBUGFS */
475 499
476/* rate scaling */ 500/* rate scaling */
@@ -480,6 +504,8 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
480/* power managment */ 504/* power managment */
481int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 505int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
482int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 506int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
507void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
508 struct iwl_powertable_cmd *cmd);
483 509
484int iwl_mvm_leds_init(struct iwl_mvm *mvm); 510int iwl_mvm_leds_init(struct iwl_mvm *mvm);
485void iwl_mvm_leds_exit(struct iwl_mvm *mvm); 511void iwl_mvm_leds_exit(struct iwl_mvm *mvm);
@@ -497,4 +523,14 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
497void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, 523void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
498 struct ieee80211_vif *vif, int idx); 524 struct ieee80211_vif *vif, int idx);
499 525
526/* BT Coex */
527int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm);
528int iwl_send_bt_init_conf(struct iwl_mvm *mvm);
529int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
530 struct iwl_rx_cmd_buffer *rxb,
531 struct iwl_device_cmd *cmd);
532void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
533 enum ieee80211_rssi_event rssi_event);
534void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
535
500#endif /* __IWL_MVM_H__ */ 536#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 20016bcbdeab..b8ec02f89acc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -74,26 +74,11 @@ static const int nvm_to_read[] = {
74 NVM_SECTION_TYPE_PRODUCTION, 74 NVM_SECTION_TYPE_PRODUCTION,
75}; 75};
76 76
77/* used to simplify the shared operations on NCM_ACCESS_CMD versions */ 77/* Default NVM size to read */
78union iwl_nvm_access_cmd { 78#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024);
79 struct iwl_nvm_access_cmd_ver1 ver1;
80 struct iwl_nvm_access_cmd_ver2 ver2;
81};
82union iwl_nvm_access_resp {
83 struct iwl_nvm_access_resp_ver1 ver1;
84 struct iwl_nvm_access_resp_ver2 ver2;
85};
86
87static inline void iwl_nvm_fill_read_ver1(struct iwl_nvm_access_cmd_ver1 *cmd,
88 u16 offset, u16 length)
89{
90 cmd->offset = cpu_to_le16(offset);
91 cmd->length = cpu_to_le16(length);
92 cmd->cache_refresh = 1;
93}
94 79
95static inline void iwl_nvm_fill_read_ver2(struct iwl_nvm_access_cmd_ver2 *cmd, 80static inline void iwl_nvm_fill_read(struct iwl_nvm_access_cmd *cmd,
96 u16 offset, u16 length, u16 section) 81 u16 offset, u16 length, u16 section)
97{ 82{
98 cmd->offset = cpu_to_le16(offset); 83 cmd->offset = cpu_to_le16(offset);
99 cmd->length = cpu_to_le16(length); 84 cmd->length = cpu_to_le16(length);
@@ -103,8 +88,8 @@ static inline void iwl_nvm_fill_read_ver2(struct iwl_nvm_access_cmd_ver2 *cmd,
103static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section, 88static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
104 u16 offset, u16 length, u8 *data) 89 u16 offset, u16 length, u8 *data)
105{ 90{
106 union iwl_nvm_access_cmd nvm_access_cmd; 91 struct iwl_nvm_access_cmd nvm_access_cmd = {};
107 union iwl_nvm_access_resp *nvm_resp; 92 struct iwl_nvm_access_resp *nvm_resp;
108 struct iwl_rx_packet *pkt; 93 struct iwl_rx_packet *pkt;
109 struct iwl_host_cmd cmd = { 94 struct iwl_host_cmd cmd = {
110 .id = NVM_ACCESS_CMD, 95 .id = NVM_ACCESS_CMD,
@@ -114,18 +99,8 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
114 int ret, bytes_read, offset_read; 99 int ret, bytes_read, offset_read;
115 u8 *resp_data; 100 u8 *resp_data;
116 101
117 memset(&nvm_access_cmd, 0, sizeof(nvm_access_cmd)); 102 iwl_nvm_fill_read(&nvm_access_cmd, offset, length, section);
118 103 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd);
119 /* TODO: not sure family should be the decider, maybe FW version? */
120 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
121 iwl_nvm_fill_read_ver2(&(nvm_access_cmd.ver2),
122 offset, length, section);
123 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver2);
124 } else {
125 iwl_nvm_fill_read_ver1(&(nvm_access_cmd.ver1),
126 offset, length);
127 cmd.len[0] = sizeof(struct iwl_nvm_access_cmd_ver1);
128 }
129 104
130 ret = iwl_mvm_send_cmd(mvm, &cmd); 105 ret = iwl_mvm_send_cmd(mvm, &cmd);
131 if (ret) 106 if (ret)
@@ -141,17 +116,10 @@ static int iwl_nvm_read_chunk(struct iwl_mvm *mvm, u16 section,
141 116
142 /* Extract NVM response */ 117 /* Extract NVM response */
143 nvm_resp = (void *)pkt->data; 118 nvm_resp = (void *)pkt->data;
144 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 119 ret = le16_to_cpu(nvm_resp->status);
145 ret = le16_to_cpu(nvm_resp->ver2.status); 120 bytes_read = le16_to_cpu(nvm_resp->length);
146 bytes_read = le16_to_cpu(nvm_resp->ver2.length); 121 offset_read = le16_to_cpu(nvm_resp->offset);
147 offset_read = le16_to_cpu(nvm_resp->ver2.offset); 122 resp_data = nvm_resp->data;
148 resp_data = nvm_resp->ver2.data;
149 } else {
150 ret = le16_to_cpu(nvm_resp->ver1.length) <= 0;
151 bytes_read = le16_to_cpu(nvm_resp->ver1.length);
152 offset_read = le16_to_cpu(nvm_resp->ver1.offset);
153 resp_data = nvm_resp->ver1.data;
154 }
155 if (ret) { 123 if (ret) {
156 IWL_ERR(mvm, 124 IWL_ERR(mvm,
157 "NVM access command failed with status %d (device: %s)\n", 125 "NVM access command failed with status %d (device: %s)\n",
@@ -191,17 +159,10 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
191{ 159{
192 u16 length, offset = 0; 160 u16 length, offset = 0;
193 int ret; 161 int ret;
194 bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000;
195 162
196 length = (iwlwifi_mod_params.amsdu_size_8K ? (8 * 1024) : (4 * 1024)) 163 /* Set nvm section read length */
197 - sizeof(union iwl_nvm_access_cmd) 164 length = IWL_NVM_DEFAULT_CHUNK_SIZE;
198 - sizeof(struct iwl_rx_packet); 165
199 /*
200 * if length is greater than EEPROM size, truncate it because uCode
201 * doesn't check it by itself, and exit the loop when reached.
202 */
203 if (old_eeprom && length > mvm->cfg->base_params->eeprom_size)
204 length = mvm->cfg->base_params->eeprom_size;
205 ret = length; 166 ret = length;
206 167
207 /* Read the NVM until exhausted (reading less than requested) */ 168 /* Read the NVM until exhausted (reading less than requested) */
@@ -214,8 +175,6 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
214 return ret; 175 return ret;
215 } 176 }
216 offset += ret; 177 offset += ret;
217 if (old_eeprom && offset == mvm->cfg->base_params->eeprom_size)
218 break;
219 } 178 }
220 179
221 IWL_INFO(mvm, "NVM section %d read completed\n", section); 180 IWL_INFO(mvm, "NVM section %d read completed\n", section);
@@ -249,63 +208,31 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
249 int ret, i, section; 208 int ret, i, section;
250 u8 *nvm_buffer, *temp; 209 u8 *nvm_buffer, *temp;
251 210
252 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 211 /* TODO: find correct NVM max size for a section */
253 /* TODO: find correct NVM max size for a section */ 212 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
254 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, 213 GFP_KERNEL);
255 GFP_KERNEL); 214 if (!nvm_buffer)
256 if (!nvm_buffer) 215 return -ENOMEM;
257 return -ENOMEM; 216 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) {
258 for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) { 217 section = nvm_to_read[i];
259 section = nvm_to_read[i]; 218 /* we override the constness for initial read */
260 /* we override the constness for initial read */ 219 ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
261 ret = iwl_nvm_read_section(mvm, section, nvm_buffer);
262 if (ret < 0)
263 break;
264 temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
265 if (!temp) {
266 ret = -ENOMEM;
267 break;
268 }
269 mvm->nvm_sections[section].data = temp;
270 mvm->nvm_sections[section].length = ret;
271 }
272 kfree(nvm_buffer);
273 if (ret < 0) 220 if (ret < 0)
274 return ret; 221 break;
275 } else { 222 temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
276 /* allocate eeprom */ 223 if (!temp) {
277 mvm->eeprom_blob_size = mvm->cfg->base_params->eeprom_size; 224 ret = -ENOMEM;
278 IWL_DEBUG_EEPROM(mvm->trans->dev, "NVM size = %zd\n", 225 break;
279 mvm->eeprom_blob_size);
280 mvm->eeprom_blob = kzalloc(mvm->eeprom_blob_size, GFP_KERNEL);
281 if (!mvm->eeprom_blob)
282 return -ENOMEM;
283
284 ret = iwl_nvm_read_section(mvm, 0, mvm->eeprom_blob);
285 if (ret != mvm->eeprom_blob_size) {
286 IWL_ERR(mvm, "Read partial NVM %d/%zd\n",
287 ret, mvm->eeprom_blob_size);
288 kfree(mvm->eeprom_blob);
289 mvm->eeprom_blob = NULL;
290 return -EINVAL;
291 } 226 }
227 mvm->nvm_sections[section].data = temp;
228 mvm->nvm_sections[section].length = ret;
292 } 229 }
230 kfree(nvm_buffer);
231 if (ret < 0)
232 return ret;
293 233
294 ret = 0; 234 ret = 0;
295 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) 235 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
296 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
297 else
298 mvm->nvm_data =
299 iwl_parse_eeprom_data(mvm->trans->dev,
300 mvm->cfg,
301 mvm->eeprom_blob,
302 mvm->eeprom_blob_size);
303
304 if (!mvm->nvm_data) {
305 kfree(mvm->eeprom_blob);
306 mvm->eeprom_blob = NULL;
307 ret = -ENOMEM;
308 }
309 236
310 return ret; 237 return ret;
311} 238}
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index aa59adf87db3..fe031d304d1e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -143,21 +143,12 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
143 u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash; 143 u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash;
144 u32 reg_val = 0; 144 u32 reg_val = 0;
145 145
146 /* 146 radio_cfg_type = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_TYPE) >>
147 * We can't upload the correct value to the INIT image 147 FW_PHY_CFG_RADIO_TYPE_POS;
148 * as we don't have nvm_data by that time. 148 radio_cfg_step = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_STEP) >>
149 * 149 FW_PHY_CFG_RADIO_STEP_POS;
150 * TODO: Figure out what we should do here 150 radio_cfg_dash = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_DASH) >>
151 */ 151 FW_PHY_CFG_RADIO_DASH_POS;
152 if (mvm->nvm_data) {
153 radio_cfg_type = mvm->nvm_data->radio_cfg_type;
154 radio_cfg_step = mvm->nvm_data->radio_cfg_step;
155 radio_cfg_dash = mvm->nvm_data->radio_cfg_dash;
156 } else {
157 radio_cfg_type = 0;
158 radio_cfg_step = 0;
159 radio_cfg_dash = 0;
160 }
161 152
162 /* SKU control */ 153 /* SKU control */
163 reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) << 154 reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) <<
@@ -175,7 +166,6 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
175 166
176 /* silicon bits */ 167 /* silicon bits */
177 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI; 168 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI;
178 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_MAC_SI;
179 169
180 iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG, 170 iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG,
181 CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH | 171 CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
@@ -230,6 +220,9 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
230 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), 220 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
231 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), 221 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
232 222
223 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
224 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false),
225
233 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), 226 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
234 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), 227 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
235 228
@@ -274,6 +267,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
274 CMD(WEP_KEY), 267 CMD(WEP_KEY),
275 CMD(REPLY_RX_PHY_CMD), 268 CMD(REPLY_RX_PHY_CMD),
276 CMD(REPLY_RX_MPDU_CMD), 269 CMD(REPLY_RX_MPDU_CMD),
270 CMD(BEACON_NOTIFICATION),
277 CMD(BEACON_TEMPLATE_CMD), 271 CMD(BEACON_TEMPLATE_CMD),
278 CMD(STATISTICS_NOTIFICATION), 272 CMD(STATISTICS_NOTIFICATION),
279 CMD(TX_ANT_CONFIGURATION_CMD), 273 CMD(TX_ANT_CONFIGURATION_CMD),
@@ -293,6 +287,11 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
293 CMD(NET_DETECT_PROFILES_CMD), 287 CMD(NET_DETECT_PROFILES_CMD),
294 CMD(NET_DETECT_HOTSPOTS_CMD), 288 CMD(NET_DETECT_HOTSPOTS_CMD),
295 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), 289 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD),
290 CMD(CARD_STATE_NOTIFICATION),
291 CMD(BT_COEX_PRIO_TABLE),
292 CMD(BT_COEX_PROT_ENV),
293 CMD(BT_PROFILE_NOTIFICATION),
294 CMD(BT_CONFIG),
296}; 295};
297#undef CMD 296#undef CMD
298 297
@@ -312,16 +311,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
312 }; 311 };
313 int err, scan_size; 312 int err, scan_size;
314 313
315 switch (cfg->device_family) {
316 case IWL_DEVICE_FAMILY_6030:
317 case IWL_DEVICE_FAMILY_6005:
318 case IWL_DEVICE_FAMILY_7000:
319 break;
320 default:
321 IWL_ERR(trans, "Trying to load mvm on an unsupported device\n");
322 return NULL;
323 }
324
325 /******************************** 314 /********************************
326 * 1. Allocating and configuring HW data 315 * 1. Allocating and configuring HW data
327 ********************************/ 316 ********************************/
@@ -363,8 +352,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
363 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); 352 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
364 trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K; 353 trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K;
365 354
366 /* TODO: this should really be a TLV */ 355 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE)
367 if (cfg->device_family == IWL_DEVICE_FAMILY_7000)
368 trans_cfg.bc_table_dword = true; 356 trans_cfg.bc_table_dword = true;
369 357
370 if (!iwlwifi_mod_params.wd_disable) 358 if (!iwlwifi_mod_params.wd_disable)
@@ -438,7 +426,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
438 out_free: 426 out_free:
439 iwl_phy_db_free(mvm->phy_db); 427 iwl_phy_db_free(mvm->phy_db);
440 kfree(mvm->scan_cmd); 428 kfree(mvm->scan_cmd);
441 kfree(mvm->eeprom_blob);
442 iwl_trans_stop_hw(trans, true); 429 iwl_trans_stop_hw(trans, true);
443 ieee80211_free_hw(mvm->hw); 430 ieee80211_free_hw(mvm->hw);
444 return NULL; 431 return NULL;
@@ -460,7 +447,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
460 iwl_phy_db_free(mvm->phy_db); 447 iwl_phy_db_free(mvm->phy_db);
461 mvm->phy_db = NULL; 448 mvm->phy_db = NULL;
462 449
463 kfree(mvm->eeprom_blob);
464 iwl_free_nvm_data(mvm->nvm_data); 450 iwl_free_nvm_data(mvm->nvm_data);
465 for (i = 0; i < NVM_NUM_OF_SECTIONS; i++) 451 for (i = 0; i < NVM_NUM_OF_SECTIONS; i++)
466 kfree(mvm->nvm_sections[i].data); 452 kfree(mvm->nvm_sections[i].data);
@@ -624,12 +610,8 @@ static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
624 ieee80211_free_txskb(mvm->hw, skb); 610 ieee80211_free_txskb(mvm->hw, skb);
625} 611}
626 612
627static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) 613static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
628{ 614{
629 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
630
631 iwl_mvm_dump_nic_error_log(mvm);
632
633 iwl_abort_notification_waits(&mvm->notif_wait); 615 iwl_abort_notification_waits(&mvm->notif_wait);
634 616
635 /* 617 /*
@@ -663,9 +645,21 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
663 } 645 }
664} 646}
665 647
648static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
649{
650 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
651
652 iwl_mvm_dump_nic_error_log(mvm);
653
654 iwl_mvm_nic_restart(mvm);
655}
656
666static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode) 657static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
667{ 658{
659 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
660
668 WARN_ON(1); 661 WARN_ON(1);
662 iwl_mvm_nic_restart(mvm);
669} 663}
670 664
671static const struct iwl_op_mode_ops iwl_mvm_ops = { 665static const struct iwl_op_mode_ops iwl_mvm_ops = {
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index b428448f8ddf..0f0b44eabd93 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -142,7 +142,7 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
142 struct cfg80211_chan_def *chandef, 142 struct cfg80211_chan_def *chandef,
143 u8 chains_static, u8 chains_dynamic) 143 u8 chains_static, u8 chains_dynamic)
144{ 144{
145 u8 valid_rx_chains, active_cnt, idle_cnt; 145 u8 active_cnt, idle_cnt;
146 146
147 /* Set the channel info data */ 147 /* Set the channel info data */
148 cmd->ci.band = (chandef->chan->band == IEEE80211_BAND_2GHZ ? 148 cmd->ci.band = (chandef->chan->band == IEEE80211_BAND_2GHZ ?
@@ -158,17 +158,16 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
158 * Need to add on chain noise calibration limitations, and 158 * Need to add on chain noise calibration limitations, and
159 * BT coex considerations. 159 * BT coex considerations.
160 */ 160 */
161 valid_rx_chains = mvm->nvm_data->valid_rx_ant;
162 idle_cnt = chains_static; 161 idle_cnt = chains_static;
163 active_cnt = chains_dynamic; 162 active_cnt = chains_dynamic;
164 163
165 cmd->rxchain_info = cpu_to_le32(valid_rx_chains << 164 cmd->rxchain_info = cpu_to_le32(iwl_fw_valid_rx_ant(mvm->fw) <<
166 PHY_RX_CHAIN_VALID_POS); 165 PHY_RX_CHAIN_VALID_POS);
167 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS); 166 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
168 cmd->rxchain_info |= cpu_to_le32(active_cnt << 167 cmd->rxchain_info |= cpu_to_le32(active_cnt <<
169 PHY_RX_CHAIN_MIMO_CNT_POS); 168 PHY_RX_CHAIN_MIMO_CNT_POS);
170 169
171 cmd->txchain_info = cpu_to_le32(mvm->nvm_data->valid_tx_ant); 170 cmd->txchain_info = cpu_to_le32(iwl_fw_valid_tx_ant(mvm->fw));
172} 171}
173 172
174/* 173/*
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 5a92a4978795..9395ab2a1af2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -75,23 +75,49 @@
75 75
76#define POWER_KEEP_ALIVE_PERIOD_SEC 25 76#define POWER_KEEP_ALIVE_PERIOD_SEC 25
77 77
78static void iwl_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 78static void iwl_mvm_power_log(struct iwl_mvm *mvm,
79 struct iwl_powertable_cmd *cmd) 79 struct iwl_powertable_cmd *cmd)
80{
81 IWL_DEBUG_POWER(mvm,
82 "Sending power table command for power level %d, flags = 0x%X\n",
83 iwlmvm_mod_params.power_scheme,
84 le16_to_cpu(cmd->flags));
85 IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n", cmd->keep_alive_seconds);
86
87 if (cmd->flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
88 IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n",
89 le32_to_cpu(cmd->rx_data_timeout));
90 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
91 le32_to_cpu(cmd->tx_data_timeout));
92 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
93 cmd->lprx_rssi_threshold);
94 }
95}
96
97void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
98 struct iwl_powertable_cmd *cmd)
80{ 99{
81 struct ieee80211_hw *hw = mvm->hw; 100 struct ieee80211_hw *hw = mvm->hw;
82 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
83 struct ieee80211_chanctx_conf *chanctx_conf; 101 struct ieee80211_chanctx_conf *chanctx_conf;
84 struct ieee80211_channel *chan; 102 struct ieee80211_channel *chan;
85 int dtimper, dtimper_msec; 103 int dtimper, dtimper_msec;
86 int keep_alive; 104 int keep_alive;
87 bool radar_detect = false; 105 bool radar_detect = false;
88 106
89 cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, 107 /*
90 mvmvif->color)); 108 * Regardless of power management state the driver must set
91 cmd->action = cpu_to_le32(FW_CTXT_ACTION_MODIFY); 109 * keep alive period. FW will use it for sending keep alive NDPs
110 * immediately after association.
111 */
112 cmd->keep_alive_seconds = POWER_KEEP_ALIVE_PERIOD_SEC;
113
114 if ((iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) ||
115 !iwlwifi_mod_params.power_save)
116 return;
117
118 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
92 119
93 if ((!vif->bss_conf.ps) || 120 if (!vif->bss_conf.ps)
94 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM))
95 return; 121 return;
96 122
97 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); 123 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
@@ -110,26 +136,23 @@ static void iwl_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
110 136
111 /* Check skip over DTIM conditions */ 137 /* Check skip over DTIM conditions */
112 if (!radar_detect && (dtimper <= 10) && 138 if (!radar_detect && (dtimper <= 10) &&
113 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP)) { 139 (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP))
114 cmd->flags |= cpu_to_le16(POWER_FLAGS_SLEEP_OVER_DTIM_MSK); 140 cmd->flags |= cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
115 cmd->num_skip_dtim = 2;
116 }
117 141
118 /* Check that keep alive period is at least 3 * DTIM */ 142 /* Check that keep alive period is at least 3 * DTIM */
119 dtimper_msec = dtimper * vif->bss_conf.beacon_int; 143 dtimper_msec = dtimper * vif->bss_conf.beacon_int;
120 keep_alive = max_t(int, 3 * dtimper_msec, 144 keep_alive = max_t(int, 3 * dtimper_msec,
121 MSEC_PER_SEC * POWER_KEEP_ALIVE_PERIOD_SEC); 145 MSEC_PER_SEC * cmd->keep_alive_seconds);
122 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC); 146 keep_alive = DIV_ROUND_UP(keep_alive, MSEC_PER_SEC);
123 147 cmd->keep_alive_seconds = keep_alive;
124 cmd->keep_alive_seconds = cpu_to_le16(keep_alive);
125 148
126 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP) { 149 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_LP) {
127 /* TODO: Also for D3 (device sleep / WoWLAN) */ 150 /* TODO: Also for D3 (device sleep / WoWLAN) */
128 cmd->rx_data_timeout = cpu_to_le32(10); 151 cmd->rx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
129 cmd->tx_data_timeout = cpu_to_le32(10); 152 cmd->tx_data_timeout = cpu_to_le32(10 * USEC_PER_MSEC);
130 } else { 153 } else {
131 cmd->rx_data_timeout = cpu_to_le32(50); 154 cmd->rx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
132 cmd->tx_data_timeout = cpu_to_le32(50); 155 cmd->tx_data_timeout = cpu_to_le32(100 * USEC_PER_MSEC);
133 } 156 }
134} 157}
135 158
@@ -137,36 +160,11 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
137{ 160{
138 struct iwl_powertable_cmd cmd = {}; 161 struct iwl_powertable_cmd cmd = {};
139 162
140 if (!iwlwifi_mod_params.power_save) {
141 IWL_DEBUG_POWER(mvm, "Power management is not allowed\n");
142 return 0;
143 }
144
145 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 163 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
146 return 0; 164 return 0;
147 165
148 iwl_power_build_cmd(mvm, vif, &cmd); 166 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
149 167 iwl_mvm_power_log(mvm, &cmd);
150 IWL_DEBUG_POWER(mvm,
151 "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n",
152 cmd.id_and_color, iwlmvm_mod_params.power_scheme,
153 le16_to_cpu(cmd.flags));
154
155 if (cmd.flags & cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK)) {
156 IWL_DEBUG_POWER(mvm, "Keep alive = %u sec\n",
157 le16_to_cpu(cmd.keep_alive_seconds));
158 IWL_DEBUG_POWER(mvm, "Rx timeout = %u usec\n",
159 le32_to_cpu(cmd.rx_data_timeout));
160 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
161 le32_to_cpu(cmd.tx_data_timeout));
162 IWL_DEBUG_POWER(mvm, "Rx timeout (uAPSD) = %u usec\n",
163 le32_to_cpu(cmd.rx_data_timeout_uapsd));
164 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
165 le32_to_cpu(cmd.tx_data_timeout_uapsd));
166 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
167 cmd.lprx_rssi_threshold);
168 IWL_DEBUG_POWER(mvm, "DTIMs to skip = %u\n", cmd.num_skip_dtim);
169 }
170 168
171 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, 169 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC,
172 sizeof(cmd), &cmd); 170 sizeof(cmd), &cmd);
@@ -175,33 +173,16 @@ int iwl_mvm_power_update_mode(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
175int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 173int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
176{ 174{
177 struct iwl_powertable_cmd cmd = {}; 175 struct iwl_powertable_cmd cmd = {};
178 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
179
180 if (!iwlwifi_mod_params.power_save) {
181 IWL_DEBUG_POWER(mvm, "Power management is not allowed\n");
182 return 0;
183 }
184 176
185 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) 177 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
186 return 0; 178 return 0;
187 179
188 cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, 180 if ((iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) &&
189 mvmvif->color)); 181 iwlwifi_mod_params.power_save)
190 cmd.action = cpu_to_le32(FW_CTXT_ACTION_MODIFY); 182 cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
191 183
192 IWL_DEBUG_POWER(mvm, 184 iwl_mvm_power_log(mvm, &cmd);
193 "Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n",
194 cmd.id_and_color, iwlmvm_mod_params.power_scheme,
195 le16_to_cpu(cmd.flags));
196 185
197 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC, 186 return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC,
198 sizeof(cmd), &cmd); 187 sizeof(cmd), &cmd);
199} 188}
200
201#ifdef CONFIG_IWLWIFI_DEBUGFS
202void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
203 struct iwl_powertable_cmd *cmd)
204{
205 iwl_power_build_cmd(mvm, vif, cmd);
206}
207#endif /* CONFIG_IWLWIFI_DEBUGFS */
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index 925628468146..a1e3e923ea3e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -114,7 +114,8 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
114 data->n_interfaces[id]++; 114 data->n_interfaces[id]++;
115 break; 115 break;
116 case NL80211_IFTYPE_MONITOR: 116 case NL80211_IFTYPE_MONITOR:
117 data->n_interfaces[id]++; 117 if (mvmvif->monitor_active)
118 data->n_interfaces[id]++;
118 break; 119 break;
119 case NL80211_IFTYPE_P2P_DEVICE: 120 case NL80211_IFTYPE_P2P_DEVICE:
120 break; 121 break;
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 56b636d9ab30..55334d542e26 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -680,12 +680,14 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
680 */ 680 */
681static bool rs_use_green(struct ieee80211_sta *sta) 681static bool rs_use_green(struct ieee80211_sta *sta)
682{ 682{
683 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv; 683 /*
684 684 * There's a bug somewhere in this code that causes the
685 bool use_green = !(sta_priv->vif->bss_conf.ht_operation_mode & 685 * scaling to get stuck because GF+SGI can't be combined
686 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); 686 * in SISO rates. Until we find that bug, disable GF, it
687 687 * has only limited benefit and we still interoperate with
688 return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && use_green; 688 * GF APs since we can always receive GF transmissions.
689 */
690 return false;
689} 691}
690 692
691/** 693/**
@@ -791,7 +793,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
791 793
792 if (num_of_ant(tbl->ant_type) > 1) 794 if (num_of_ant(tbl->ant_type) > 1)
793 tbl->ant_type = 795 tbl->ant_type =
794 first_antenna(mvm->nvm_data->valid_tx_ant); 796 first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
795 797
796 tbl->is_ht40 = 0; 798 tbl->is_ht40 = 0;
797 tbl->is_SGI = 0; 799 tbl->is_SGI = 0;
@@ -1233,7 +1235,7 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm,
1233 return -1; 1235 return -1;
1234 1236
1235 /* Need both Tx chains/antennas to support MIMO */ 1237 /* Need both Tx chains/antennas to support MIMO */
1236 if (num_of_ant(mvm->nvm_data->valid_tx_ant) < 2) 1238 if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 2)
1237 return -1; 1239 return -1;
1238 1240
1239 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n"); 1241 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n");
@@ -1285,7 +1287,7 @@ static int rs_switch_to_mimo3(struct iwl_mvm *mvm,
1285 return -1; 1287 return -1;
1286 1288
1287 /* Need both Tx chains/antennas to support MIMO */ 1289 /* Need both Tx chains/antennas to support MIMO */
1288 if (num_of_ant(mvm->nvm_data->valid_tx_ant) < 3) 1290 if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) < 3)
1289 return -1; 1291 return -1;
1290 1292
1291 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO3\n"); 1293 IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO3\n");
@@ -1379,7 +1381,7 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm,
1379 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1381 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1380 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1382 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1381 u8 start_action; 1383 u8 start_action;
1382 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; 1384 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1383 u8 tx_chains_num = num_of_ant(valid_tx_ant); 1385 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1384 int ret; 1386 int ret;
1385 u8 update_search_tbl_counter = 0; 1387 u8 update_search_tbl_counter = 0;
@@ -1512,7 +1514,7 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm,
1512 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1514 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1513 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1515 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1514 u8 start_action; 1516 u8 start_action;
1515 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; 1517 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1516 u8 tx_chains_num = num_of_ant(valid_tx_ant); 1518 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1517 u8 update_search_tbl_counter = 0; 1519 u8 update_search_tbl_counter = 0;
1518 int ret; 1520 int ret;
@@ -1647,7 +1649,7 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,
1647 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1649 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1648 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1650 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1649 u8 start_action; 1651 u8 start_action;
1650 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; 1652 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1651 u8 tx_chains_num = num_of_ant(valid_tx_ant); 1653 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1652 u8 update_search_tbl_counter = 0; 1654 u8 update_search_tbl_counter = 0;
1653 int ret; 1655 int ret;
@@ -1784,7 +1786,7 @@ static int rs_move_mimo3_to_other(struct iwl_mvm *mvm,
1784 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1786 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1785 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1787 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1786 u8 start_action; 1788 u8 start_action;
1787 u8 valid_tx_ant = mvm->nvm_data->valid_tx_ant; 1789 u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
1788 u8 tx_chains_num = num_of_ant(valid_tx_ant); 1790 u8 tx_chains_num = num_of_ant(valid_tx_ant);
1789 int ret; 1791 int ret;
1790 u8 update_search_tbl_counter = 0; 1792 u8 update_search_tbl_counter = 0;
@@ -2447,7 +2449,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
2447 2449
2448 i = lq_sta->last_txrate_idx; 2450 i = lq_sta->last_txrate_idx;
2449 2451
2450 valid_tx_ant = mvm->nvm_data->valid_tx_ant; 2452 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
2451 2453
2452 if (!lq_sta->search_better_tbl) 2454 if (!lq_sta->search_better_tbl)
2453 active_tbl = lq_sta->active_tbl; 2455 active_tbl = lq_sta->active_tbl;
@@ -2637,15 +2639,15 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2637 2639
2638 /* These values will be overridden later */ 2640 /* These values will be overridden later */
2639 lq_sta->lq.single_stream_ant_msk = 2641 lq_sta->lq.single_stream_ant_msk =
2640 first_antenna(mvm->nvm_data->valid_tx_ant); 2642 first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
2641 lq_sta->lq.dual_stream_ant_msk = 2643 lq_sta->lq.dual_stream_ant_msk =
2642 mvm->nvm_data->valid_tx_ant & 2644 iwl_fw_valid_tx_ant(mvm->fw) &
2643 ~first_antenna(mvm->nvm_data->valid_tx_ant); 2645 ~first_antenna(iwl_fw_valid_tx_ant(mvm->fw));
2644 if (!lq_sta->lq.dual_stream_ant_msk) { 2646 if (!lq_sta->lq.dual_stream_ant_msk) {
2645 lq_sta->lq.dual_stream_ant_msk = ANT_AB; 2647 lq_sta->lq.dual_stream_ant_msk = ANT_AB;
2646 } else if (num_of_ant(mvm->nvm_data->valid_tx_ant) == 2) { 2648 } else if (num_of_ant(iwl_fw_valid_tx_ant(mvm->fw)) == 2) {
2647 lq_sta->lq.dual_stream_ant_msk = 2649 lq_sta->lq.dual_stream_ant_msk =
2648 mvm->nvm_data->valid_tx_ant; 2650 iwl_fw_valid_tx_ant(mvm->fw);
2649 } 2651 }
2650 2652
2651 /* as default allow aggregation for all tids */ 2653 /* as default allow aggregation for all tids */
@@ -2706,7 +2708,7 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
2706 index++; 2708 index++;
2707 repeat_rate--; 2709 repeat_rate--;
2708 if (mvm) 2710 if (mvm)
2709 valid_tx_ant = mvm->nvm_data->valid_tx_ant; 2711 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
2710 2712
2711 /* Fill rest of rate table */ 2713 /* Fill rest of rate table */
2712 while (index < LINK_QUAL_MAX_RETRY_NUM) { 2714 while (index < LINK_QUAL_MAX_RETRY_NUM) {
@@ -2811,7 +2813,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
2811 u8 ant_sel_tx; 2813 u8 ant_sel_tx;
2812 2814
2813 mvm = lq_sta->drv; 2815 mvm = lq_sta->drv;
2814 valid_tx_ant = mvm->nvm_data->valid_tx_ant; 2816 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
2815 if (lq_sta->dbg_fixed_rate) { 2817 if (lq_sta->dbg_fixed_rate) {
2816 ant_sel_tx = 2818 ant_sel_tx =
2817 ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) 2819 ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK)
@@ -2882,9 +2884,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2882 desc += sprintf(buff+desc, "fixed rate 0x%X\n", 2884 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
2883 lq_sta->dbg_fixed_rate); 2885 lq_sta->dbg_fixed_rate);
2884 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", 2886 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
2885 (mvm->nvm_data->valid_tx_ant & ANT_A) ? "ANT_A," : "", 2887 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_A) ? "ANT_A," : "",
2886 (mvm->nvm_data->valid_tx_ant & ANT_B) ? "ANT_B," : "", 2888 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "",
2887 (mvm->nvm_data->valid_tx_ant & ANT_C) ? "ANT_C" : ""); 2889 (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : "");
2888 desc += sprintf(buff+desc, "lq type %s\n", 2890 desc += sprintf(buff+desc, "lq type %s\n",
2889 (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); 2891 (is_legacy(tbl->lq_type)) ? "legacy" : "HT");
2890 if (is_Ht(tbl->lq_type)) { 2892 if (is_Ht(tbl->lq_type)) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 3f40ab05bbd8..4dfc21a3e83e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -131,33 +131,42 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
131static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, 131static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
132 struct iwl_rx_phy_info *phy_info) 132 struct iwl_rx_phy_info *phy_info)
133{ 133{
134 u32 rssi_a, rssi_b, rssi_c, max_rssi, agc_db; 134 int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;
135 int rssi_all_band_a, rssi_all_band_b;
136 u32 agc_a, agc_b, max_agc;
135 u32 val; 137 u32 val;
136 138
137 /* Find max rssi among 3 possible receivers. 139 /* Find max rssi among 2 possible receivers.
138 * These values are measured by the Digital Signal Processor (DSP). 140 * These values are measured by the Digital Signal Processor (DSP).
139 * They should stay fairly constant even as the signal strength varies, 141 * They should stay fairly constant even as the signal strength varies,
140 * if the radio's Automatic Gain Control (AGC) is working right. 142 * if the radio's Automatic Gain Control (AGC) is working right.
141 * AGC value (see below) will provide the "interesting" info. 143 * AGC value (see below) will provide the "interesting" info.
142 */ 144 */
145 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);
146 agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS;
147 agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS;
148 max_agc = max_t(u32, agc_a, agc_b);
149
143 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]); 150 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]);
144 rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS; 151 rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS;
145 rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS; 152 rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS;
146 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_C_IDX]); 153 rssi_all_band_a = (val & IWL_OFDM_RSSI_ALLBAND_A_MSK) >>
147 rssi_c = (val & IWL_OFDM_RSSI_INBAND_C_MSK) >> IWL_OFDM_RSSI_C_POS; 154 IWL_OFDM_RSSI_ALLBAND_A_POS;
148 155 rssi_all_band_b = (val & IWL_OFDM_RSSI_ALLBAND_B_MSK) >>
149 val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]); 156 IWL_OFDM_RSSI_ALLBAND_B_POS;
150 agc_db = (val & IWL_OFDM_AGC_DB_MSK) >> IWL_OFDM_AGC_DB_POS;
151 157
152 max_rssi = max_t(u32, rssi_a, rssi_b); 158 /*
153 max_rssi = max_t(u32, max_rssi, rssi_c); 159 * dBm = rssi dB - agc dB - constant.
160 * Higher AGC (higher radio gain) means lower signal.
161 */
162 rssi_a_dbm = rssi_a - IWL_RSSI_OFFSET - agc_a;
163 rssi_b_dbm = rssi_b - IWL_RSSI_OFFSET - agc_b;
164 max_rssi_dbm = max_t(int, rssi_a_dbm, rssi_b_dbm);
154 165
155 IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", 166 IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",
156 rssi_a, rssi_b, rssi_c, max_rssi, agc_db); 167 rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b);
157 168
158 /* dBm = max_rssi dB - agc dB - constant. 169 return max_rssi_dbm;
159 * Higher AGC (higher radio gain) means lower signal. */
160 return max_rssi - agc_db - IWL_RSSI_OFFSET;
161} 170}
162 171
163/* 172/*
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 9b21b92aa8d1..2157b0f8ced5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -74,7 +74,7 @@
74static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) 74static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
75{ 75{
76 u16 rx_chain; 76 u16 rx_chain;
77 u8 rx_ant = mvm->nvm_data->valid_rx_ant; 77 u8 rx_ant = iwl_fw_valid_rx_ant(mvm->fw);
78 78
79 rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS; 79 rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS;
80 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS; 80 rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
@@ -115,7 +115,7 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
115 u32 tx_ant; 115 u32 tx_ant;
116 116
117 mvm->scan_last_antenna_idx = 117 mvm->scan_last_antenna_idx =
118 iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant, 118 iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw),
119 mvm->scan_last_antenna_idx); 119 mvm->scan_last_antenna_idx);
120 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS; 120 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
121 121
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 52aecf20d0df..0fd96e4da461 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -101,8 +101,55 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
101 } 101 }
102 add_sta_cmd.add_modify = update ? 1 : 0; 102 add_sta_cmd.add_modify = update ? 1 : 0;
103 103
104 /* STA_FLG_FAT_EN_MSK ? */ 104 add_sta_cmd.station_flags_msk |= cpu_to_le32(STA_FLG_FAT_EN_MSK |
105 /* STA_FLG_MIMO_EN_MSK ? */ 105 STA_FLG_MIMO_EN_MSK);
106
107 switch (sta->bandwidth) {
108 case IEEE80211_STA_RX_BW_160:
109 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_160MHZ);
110 /* fall through */
111 case IEEE80211_STA_RX_BW_80:
112 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_80MHZ);
113 /* fall through */
114 case IEEE80211_STA_RX_BW_40:
115 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_40MHZ);
116 /* fall through */
117 case IEEE80211_STA_RX_BW_20:
118 if (sta->ht_cap.ht_supported)
119 add_sta_cmd.station_flags |=
120 cpu_to_le32(STA_FLG_FAT_EN_20MHZ);
121 break;
122 }
123
124 switch (sta->rx_nss) {
125 case 1:
126 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO);
127 break;
128 case 2:
129 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO2);
130 break;
131 case 3 ... 8:
132 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO3);
133 break;
134 }
135
136 switch (sta->smps_mode) {
137 case IEEE80211_SMPS_AUTOMATIC:
138 case IEEE80211_SMPS_NUM_MODES:
139 WARN_ON(1);
140 break;
141 case IEEE80211_SMPS_STATIC:
142 /* override NSS */
143 add_sta_cmd.station_flags &= ~cpu_to_le32(STA_FLG_MIMO_EN_MSK);
144 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO);
145 break;
146 case IEEE80211_SMPS_DYNAMIC:
147 add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_RTS_MIMO_PROT);
148 break;
149 case IEEE80211_SMPS_OFF:
150 /* nothing */
151 break;
152 }
106 153
107 if (sta->ht_cap.ht_supported) { 154 if (sta->ht_cap.ht_supported) {
108 add_sta_cmd.station_flags_msk |= 155 add_sta_cmd.station_flags_msk |=
@@ -340,6 +387,9 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
340 387
341 if (vif->type == NL80211_IFTYPE_STATION && 388 if (vif->type == NL80211_IFTYPE_STATION &&
342 mvmvif->ap_sta_id == mvm_sta->sta_id) { 389 mvmvif->ap_sta_id == mvm_sta->sta_id) {
390 /* flush its queues here since we are freeing mvm_sta */
391 ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true);
392
343 /* 393 /*
344 * Put a non-NULL since the fw station isn't removed. 394 * Put a non-NULL since the fw station isn't removed.
345 * It will be removed after the MAC will be set as 395 * It will be removed after the MAC will be set as
@@ -348,9 +398,6 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
348 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], 398 rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
349 ERR_PTR(-EINVAL)); 399 ERR_PTR(-EINVAL));
350 400
351 /* flush its queues here since we are freeing mvm_sta */
352 ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true);
353
354 /* if we are associated - we can't remove the AP STA now */ 401 /* if we are associated - we can't remove the AP STA now */
355 if (vif->bss_conf.assoc) 402 if (vif->bss_conf.assoc)
356 return ret; 403 return ret;
@@ -770,6 +817,16 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
770 u16 txq_id; 817 u16 txq_id;
771 int err; 818 int err;
772 819
820
821 /*
822 * If mac80211 is cleaning its state, then say that we finished since
823 * our state has been cleared anyway.
824 */
825 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
826 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
827 return 0;
828 }
829
773 spin_lock_bh(&mvmsta->lock); 830 spin_lock_bh(&mvmsta->lock);
774 831
775 txq_id = tid_data->txq_id; 832 txq_id = tid_data->txq_id;
@@ -824,6 +881,34 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
824 return err; 881 return err;
825} 882}
826 883
884int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
885 struct ieee80211_sta *sta, u16 tid)
886{
887 struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
888 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
889 u16 txq_id;
890
891 /*
892 * First set the agg state to OFF to avoid calling
893 * ieee80211_stop_tx_ba_cb in iwl_mvm_check_ratid_empty.
894 */
895 spin_lock_bh(&mvmsta->lock);
896 txq_id = tid_data->txq_id;
897 IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n",
898 mvmsta->sta_id, tid, txq_id, tid_data->state);
899 tid_data->state = IWL_AGG_OFF;
900 spin_unlock_bh(&mvmsta->lock);
901
902 if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
903 IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
904
905 iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
906 mvm->queue_to_mac80211[tid_data->txq_id] =
907 IWL_INVALID_MAC80211_QUEUE;
908
909 return 0;
910}
911
827static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm) 912static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
828{ 913{
829 int i; 914 int i;
@@ -860,7 +945,7 @@ static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
860 mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) 945 mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT)
861 return mvmvif->ap_sta_id; 946 return mvmvif->ap_sta_id;
862 947
863 return IWL_INVALID_STATION; 948 return IWL_MVM_STATION_COUNT;
864} 949}
865 950
866static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, 951static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
@@ -1008,7 +1093,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
1008 1093
1009 /* Get the station id from the mvm local station table */ 1094 /* Get the station id from the mvm local station table */
1010 sta_id = iwl_mvm_get_key_sta_id(vif, sta); 1095 sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1011 if (sta_id == IWL_INVALID_STATION) { 1096 if (sta_id == IWL_MVM_STATION_COUNT) {
1012 IWL_ERR(mvm, "Failed to find station id\n"); 1097 IWL_ERR(mvm, "Failed to find station id\n");
1013 return -EINVAL; 1098 return -EINVAL;
1014 } 1099 }
@@ -1103,7 +1188,7 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
1103 return -ENOENT; 1188 return -ENOENT;
1104 } 1189 }
1105 1190
1106 if (sta_id == IWL_INVALID_STATION) { 1191 if (sta_id == IWL_MVM_STATION_COUNT) {
1107 IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n"); 1192 IWL_DEBUG_WEP(mvm, "station non-existent, early return.\n");
1108 return 0; 1193 return 0;
1109 } 1194 }
@@ -1169,7 +1254,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
1169 struct iwl_mvm_sta *mvm_sta; 1254 struct iwl_mvm_sta *mvm_sta;
1170 u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta); 1255 u8 sta_id = iwl_mvm_get_key_sta_id(vif, sta);
1171 1256
1172 if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) 1257 if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT))
1173 return; 1258 return;
1174 1259
1175 rcu_read_lock(); 1260 rcu_read_lock();
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index 896f88ac8145..12abd2d71835 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -271,6 +271,7 @@ struct iwl_mvm_tid_data {
271 * @tid_disable_agg: bitmap: if bit(tid) is set, the fw won't send ampdus for 271 * @tid_disable_agg: bitmap: if bit(tid) is set, the fw won't send ampdus for
272 * tid. 272 * tid.
273 * @max_agg_bufsize: the maximal size of the AGG buffer for this station 273 * @max_agg_bufsize: the maximal size of the AGG buffer for this station
274 * @bt_reduced_txpower: is reduced tx power enabled for this station
274 * @lock: lock to protect the whole struct. Since %tid_data is access from Tx 275 * @lock: lock to protect the whole struct. Since %tid_data is access from Tx
275 * and from Tx response flow, it needs a spinlock. 276 * and from Tx response flow, it needs a spinlock.
276 * @pending_frames: number of frames for this STA on the shared Tx queues. 277 * @pending_frames: number of frames for this STA on the shared Tx queues.
@@ -287,6 +288,7 @@ struct iwl_mvm_sta {
287 u32 mac_id_n_color; 288 u32 mac_id_n_color;
288 u16 tid_disable_agg; 289 u16 tid_disable_agg;
289 u8 max_agg_bufsize; 290 u8 max_agg_bufsize;
291 bool bt_reduced_txpower;
290 spinlock_t lock; 292 spinlock_t lock;
291 atomic_t pending_frames; 293 atomic_t pending_frames;
292 struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT]; 294 struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT];
@@ -348,6 +350,8 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
348 struct ieee80211_sta *sta, u16 tid, u8 buf_size); 350 struct ieee80211_sta *sta, u16 tid, u8 buf_size);
349int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 351int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
350 struct ieee80211_sta *sta, u16 tid); 352 struct ieee80211_sta *sta, u16 tid);
353int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
354 struct ieee80211_sta *sta, u16 tid);
351 355
352int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm); 356int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm);
353int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, 357int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index e437e02c7149..ad9bbca99213 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -76,14 +76,12 @@
76#define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024)) 76#define TU_TO_JIFFIES(_tu) (usecs_to_jiffies((_tu) * 1024))
77#define MSEC_TO_TU(_msec) (_msec*1000/1024) 77#define MSEC_TO_TU(_msec) (_msec*1000/1024)
78 78
79/* For ROC use a TE type which has priority high enough to be scheduled when 79/*
80 * there is a concurrent BSS or GO/AP. Currently, use a TE type that has 80 * For the high priority TE use a time event type that has similar priority to
81 * priority similar to the TE priority used for action scans by the FW. 81 * the FW's action scan priority.
82 * TODO: This needs to be changed, based on the reason for the ROC, i.e., use
83 * TE_P2P_DEVICE_DISCOVERABLE for remain on channel without mgmt skb, and use
84 * TE_P2P_DEVICE_ACTION_SCAN
85 */ 82 */
86#define IWL_MVM_ROC_TE_TYPE TE_P2P_DEVICE_ACTION_SCAN 83#define IWL_MVM_ROC_TE_TYPE_NORMAL TE_P2P_DEVICE_DISCOVERABLE
84#define IWL_MVM_ROC_TE_TYPE_MGMT_TX TE_P2P_CLIENT_ASSOC
87 85
88void iwl_mvm_te_clear_data(struct iwl_mvm *mvm, 86void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
89 struct iwl_mvm_time_event_data *te_data) 87 struct iwl_mvm_time_event_data *te_data)
@@ -116,7 +114,7 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
116 * issue as it will have to complete before the next command is 114 * issue as it will have to complete before the next command is
117 * executed, and a new time event means a new command. 115 * executed, and a new time event means a new command.
118 */ 116 */
119 iwl_mvm_flush_tx_path(mvm, BIT(IWL_OFFCHANNEL_QUEUE), false); 117 iwl_mvm_flush_tx_path(mvm, BIT(IWL_MVM_OFFCHANNEL_QUEUE), false);
120} 118}
121 119
122static void iwl_mvm_roc_finished(struct iwl_mvm *mvm) 120static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
@@ -168,7 +166,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
168 WARN_ONCE(!le32_to_cpu(notif->status), 166 WARN_ONCE(!le32_to_cpu(notif->status),
169 "Failed to schedule time event\n"); 167 "Failed to schedule time event\n");
170 168
171 if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_END) { 169 if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_END) {
172 IWL_DEBUG_TE(mvm, 170 IWL_DEBUG_TE(mvm,
173 "TE ended - current time %lu, estimated end %lu\n", 171 "TE ended - current time %lu, estimated end %lu\n",
174 jiffies, te_data->end_jiffies); 172 jiffies, te_data->end_jiffies);
@@ -191,7 +189,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
191 } 189 }
192 190
193 iwl_mvm_te_clear_data(mvm, te_data); 191 iwl_mvm_te_clear_data(mvm, te_data);
194 } else if (le32_to_cpu(notif->action) == TE_NOTIF_HOST_START) { 192 } else if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_START) {
195 te_data->running = true; 193 te_data->running = true;
196 te_data->end_jiffies = jiffies + 194 te_data->end_jiffies = jiffies +
197 TU_TO_JIFFIES(te_data->duration); 195 TU_TO_JIFFIES(te_data->duration);
@@ -370,7 +368,8 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
370 time_cmd.interval_reciprocal = cpu_to_le32(iwl_mvm_reciprocal(1)); 368 time_cmd.interval_reciprocal = cpu_to_le32(iwl_mvm_reciprocal(1));
371 time_cmd.duration = cpu_to_le32(duration); 369 time_cmd.duration = cpu_to_le32(duration);
372 time_cmd.repeat = cpu_to_le32(1); 370 time_cmd.repeat = cpu_to_le32(1);
373 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END); 371 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_EVENT_START |
372 TE_NOTIF_HOST_EVENT_END);
374 373
375 iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); 374 iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
376} 375}
@@ -438,7 +437,7 @@ void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
438} 437}
439 438
440int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 439int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
441 int duration) 440 int duration, enum ieee80211_roc_type type)
442{ 441{
443 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 442 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
444 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; 443 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
@@ -459,27 +458,36 @@ int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
459 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD); 458 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
460 time_cmd.id_and_color = 459 time_cmd.id_and_color =
461 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); 460 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
462 time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE); 461
462 switch (type) {
463 case IEEE80211_ROC_TYPE_NORMAL:
464 time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE_NORMAL);
465 break;
466 case IEEE80211_ROC_TYPE_MGMT_TX:
467 time_cmd.id = cpu_to_le32(IWL_MVM_ROC_TE_TYPE_MGMT_TX);
468 break;
469 default:
470 WARN_ONCE(1, "Got an invalid ROC type\n");
471 return -EINVAL;
472 }
463 473
464 time_cmd.apply_time = cpu_to_le32(0); 474 time_cmd.apply_time = cpu_to_le32(0);
465 time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT); 475 time_cmd.dep_policy = cpu_to_le32(TE_INDEPENDENT);
466 time_cmd.is_present = cpu_to_le32(1); 476 time_cmd.is_present = cpu_to_le32(1);
467
468 time_cmd.interval = cpu_to_le32(1); 477 time_cmd.interval = cpu_to_le32(1);
469 478
470 /* 479 /*
471 * IWL_MVM_ROC_TE_TYPE can have lower priority than other events 480 * The P2P Device TEs can have lower priority than other events
472 * that are being scheduled by the driver/fw, and thus it might not be 481 * that are being scheduled by the driver/fw, and thus it might not be
473 * scheduled. To improve the chances of it being scheduled, allow it to 482 * scheduled. To improve the chances of it being scheduled, allow them
474 * be fragmented. 483 * to be fragmented, and in addition allow them to be delayed.
475 * In addition, for the same reasons, allow to delay the scheduling of
476 * the time event.
477 */ 484 */
478 time_cmd.max_frags = cpu_to_le32(MSEC_TO_TU(duration)/20); 485 time_cmd.max_frags = cpu_to_le32(MSEC_TO_TU(duration)/20);
479 time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2)); 486 time_cmd.max_delay = cpu_to_le32(MSEC_TO_TU(duration/2));
480 time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration)); 487 time_cmd.duration = cpu_to_le32(MSEC_TO_TU(duration));
481 time_cmd.repeat = cpu_to_le32(1); 488 time_cmd.repeat = cpu_to_le32(1);
482 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_START | TE_NOTIF_HOST_END); 489 time_cmd.notify = cpu_to_le32(TE_NOTIF_HOST_EVENT_START |
490 TE_NOTIF_HOST_EVENT_END);
483 491
484 return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd); 492 return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
485} 493}
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h
index 64fb57a5ab43..f86c51065ed3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.h
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -162,6 +162,7 @@ int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
162 * that the vif type is NL80211_IFTYPE_P2P_DEVICE 162 * that the vif type is NL80211_IFTYPE_P2P_DEVICE
163 * @duration: the requested duration in millisecond for the fw to be on the 163 * @duration: the requested duration in millisecond for the fw to be on the
164 * channel that is bound to the vif. 164 * channel that is bound to the vif.
165 * @type: the remain on channel request type
165 * 166 *
166 * This function can be used to issue a remain on channel session, 167 * This function can be used to issue a remain on channel session,
167 * which means that the fw will stay in the channel for the request %duration 168 * which means that the fw will stay in the channel for the request %duration
@@ -172,7 +173,7 @@ int iwl_mvm_rx_time_event_notif(struct iwl_mvm *mvm,
172 * another notification to the driver. 173 * another notification to the driver.
173 */ 174 */
174int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 175int iwl_mvm_start_p2p_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
175 int duration); 176 int duration, enum ieee80211_roc_type type);
176 177
177/** 178/**
178 * iwl_mvm_stop_p2p_roc - stop remain on channel for p2p device functionlity 179 * iwl_mvm_stop_p2p_roc - stop remain on channel for p2p device functionlity
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 56df249b215e..479074303bd7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -205,7 +205,7 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
205 rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx); 205 rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
206 206
207 mvm->mgmt_last_antenna_idx = 207 mvm->mgmt_last_antenna_idx =
208 iwl_mvm_next_antenna(mvm, mvm->nvm_data->valid_tx_ant, 208 iwl_mvm_next_antenna(mvm, iwl_fw_valid_tx_ant(mvm->fw),
209 mvm->mgmt_last_antenna_idx); 209 mvm->mgmt_last_antenna_idx);
210 rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; 210 rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
211 211
@@ -365,7 +365,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
365 if (WARN_ON_ONCE(!mvmsta)) 365 if (WARN_ON_ONCE(!mvmsta))
366 return -1; 366 return -1;
367 367
368 if (WARN_ON_ONCE(mvmsta->sta_id == IWL_INVALID_STATION)) 368 if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_STATION_COUNT))
369 return -1; 369 return -1;
370 370
371 dev_cmd = iwl_mvm_set_tx_params(mvm, skb, sta, mvmsta->sta_id); 371 dev_cmd = iwl_mvm_set_tx_params(mvm, skb, sta, mvmsta->sta_id);
@@ -417,7 +417,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
417 spin_unlock(&mvmsta->lock); 417 spin_unlock(&mvmsta->lock);
418 418
419 if (mvmsta->vif->type == NL80211_IFTYPE_AP && 419 if (mvmsta->vif->type == NL80211_IFTYPE_AP &&
420 txq_id < IWL_FIRST_AMPDU_QUEUE) 420 txq_id < IWL_MVM_FIRST_AGG_QUEUE)
421 atomic_inc(&mvmsta->pending_frames); 421 atomic_inc(&mvmsta->pending_frames);
422 422
423 return 0; 423 return 0;
@@ -606,13 +606,9 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
606 info); 606 info);
607 607
608 /* Single frame failure in an AMPDU queue => send BAR */ 608 /* Single frame failure in an AMPDU queue => send BAR */
609 if (txq_id >= IWL_FIRST_AMPDU_QUEUE && 609 if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE &&
610 !(info->flags & IEEE80211_TX_STAT_ACK)) { 610 !(info->flags & IEEE80211_TX_STAT_ACK))
611 /* there must be only one skb in the skb_list */
612 WARN_ON_ONCE(skb_freed > 1 ||
613 !skb_queue_empty(&skbs));
614 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 611 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
615 }
616 612
617 /* W/A FW bug: seq_ctl is wrong when the queue is flushed */ 613 /* W/A FW bug: seq_ctl is wrong when the queue is flushed */
618 if (status == TX_STATUS_FAIL_FIFO_FLUSHED) { 614 if (status == TX_STATUS_FAIL_FIFO_FLUSHED) {
@@ -623,7 +619,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
623 ieee80211_tx_status_ni(mvm->hw, skb); 619 ieee80211_tx_status_ni(mvm->hw, skb);
624 } 620 }
625 621
626 if (txq_id >= IWL_FIRST_AMPDU_QUEUE) { 622 if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE) {
627 /* If this is an aggregation queue, we use the ssn since: 623 /* If this is an aggregation queue, we use the ssn since:
628 * ssn = wifi seq_num % 256. 624 * ssn = wifi seq_num % 256.
629 * The seq_ctl is the sequence control of the packet to which 625 * The seq_ctl is the sequence control of the packet to which
@@ -645,10 +641,12 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
645 } 641 }
646 642
647 IWL_DEBUG_TX_REPLY(mvm, 643 IWL_DEBUG_TX_REPLY(mvm,
648 "TXQ %d status %s (0x%08x)\n\t\t\t\tinitial_rate 0x%x " 644 "TXQ %d status %s (0x%08x)\n",
649 "retries %d, idx=%d ssn=%d next_reclaimed=0x%x seq_ctl=0x%x\n", 645 txq_id, iwl_mvm_get_tx_fail_reason(status), status);
650 txq_id, iwl_mvm_get_tx_fail_reason(status), 646
651 status, le32_to_cpu(tx_resp->initial_rate), 647 IWL_DEBUG_TX_REPLY(mvm,
648 "\t\t\t\tinitial_rate 0x%x retries %d, idx=%d ssn=%d next_reclaimed=0x%x seq_ctl=0x%x\n",
649 le32_to_cpu(tx_resp->initial_rate),
652 tx_resp->failure_frame, SEQ_TO_INDEX(sequence), 650 tx_resp->failure_frame, SEQ_TO_INDEX(sequence),
653 ssn, next_reclaimed, seq_ctl); 651 ssn, next_reclaimed, seq_ctl);
654 652
@@ -685,7 +683,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
685 * If there are no pending frames for this STA, notify mac80211 that 683 * If there are no pending frames for this STA, notify mac80211 that
686 * this station can go to sleep in its STA table. 684 * this station can go to sleep in its STA table.
687 */ 685 */
688 if (txq_id < IWL_FIRST_AMPDU_QUEUE && mvmsta && 686 if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && mvmsta &&
689 !WARN_ON(skb_freed > 1) && 687 !WARN_ON(skb_freed > 1) &&
690 mvmsta->vif->type == NL80211_IFTYPE_AP && 688 mvmsta->vif->type == NL80211_IFTYPE_AP &&
691 atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) { 689 atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) {
@@ -754,7 +752,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
754 u16 sequence = le16_to_cpu(pkt->hdr.sequence); 752 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
755 struct ieee80211_sta *sta; 753 struct ieee80211_sta *sta;
756 754
757 if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_FIRST_AMPDU_QUEUE)) 755 if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_MVM_FIRST_AGG_QUEUE))
758 return; 756 return;
759 757
760 if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS)) 758 if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS))
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 000e842c2edd..0cc8d8c0d393 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -462,7 +462,7 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq,
462 .data = { lq, }, 462 .data = { lq, },
463 }; 463 };
464 464
465 if (WARN_ON(lq->sta_id == IWL_INVALID_STATION)) 465 if (WARN_ON(lq->sta_id == IWL_MVM_STATION_COUNT))
466 return -EINVAL; 466 return -EINVAL;
467 467
468 if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) 468 if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
diff --git a/drivers/net/wireless/iwlwifi/pcie/cfg.h b/drivers/net/wireless/iwlwifi/pcie/cfg.h
deleted file mode 100644
index c6f8e83c3551..000000000000
--- a/drivers/net/wireless/iwlwifi/pcie/cfg.h
+++ /dev/null
@@ -1,115 +0,0 @@
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) 2007 - 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 LICENSE.GPL.
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) 2005 - 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#ifndef __iwl_pci_h__
64#define __iwl_pci_h__
65
66
67/*
68 * This file declares the config structures for all devices.
69 */
70
71extern const struct iwl_cfg iwl5300_agn_cfg;
72extern const struct iwl_cfg iwl5100_agn_cfg;
73extern const struct iwl_cfg iwl5350_agn_cfg;
74extern const struct iwl_cfg iwl5100_bgn_cfg;
75extern const struct iwl_cfg iwl5100_abg_cfg;
76extern const struct iwl_cfg iwl5150_agn_cfg;
77extern const struct iwl_cfg iwl5150_abg_cfg;
78extern const struct iwl_cfg iwl6005_2agn_cfg;
79extern const struct iwl_cfg iwl6005_2abg_cfg;
80extern const struct iwl_cfg iwl6005_2bg_cfg;
81extern const struct iwl_cfg iwl6005_2agn_sff_cfg;
82extern const struct iwl_cfg iwl6005_2agn_d_cfg;
83extern const struct iwl_cfg iwl6005_2agn_mow1_cfg;
84extern const struct iwl_cfg iwl6005_2agn_mow2_cfg;
85extern const struct iwl_cfg iwl1030_bgn_cfg;
86extern const struct iwl_cfg iwl1030_bg_cfg;
87extern const struct iwl_cfg iwl6030_2agn_cfg;
88extern const struct iwl_cfg iwl6030_2abg_cfg;
89extern const struct iwl_cfg iwl6030_2bgn_cfg;
90extern const struct iwl_cfg iwl6030_2bg_cfg;
91extern const struct iwl_cfg iwl6000i_2agn_cfg;
92extern const struct iwl_cfg iwl6000i_2abg_cfg;
93extern const struct iwl_cfg iwl6000i_2bg_cfg;
94extern const struct iwl_cfg iwl6000_3agn_cfg;
95extern const struct iwl_cfg iwl6050_2agn_cfg;
96extern const struct iwl_cfg iwl6050_2abg_cfg;
97extern const struct iwl_cfg iwl6150_bgn_cfg;
98extern const struct iwl_cfg iwl6150_bg_cfg;
99extern const struct iwl_cfg iwl1000_bgn_cfg;
100extern const struct iwl_cfg iwl1000_bg_cfg;
101extern const struct iwl_cfg iwl100_bgn_cfg;
102extern const struct iwl_cfg iwl100_bg_cfg;
103extern const struct iwl_cfg iwl130_bgn_cfg;
104extern const struct iwl_cfg iwl130_bg_cfg;
105extern const struct iwl_cfg iwl2000_2bgn_cfg;
106extern const struct iwl_cfg iwl2000_2bgn_d_cfg;
107extern const struct iwl_cfg iwl2030_2bgn_cfg;
108extern const struct iwl_cfg iwl6035_2agn_cfg;
109extern const struct iwl_cfg iwl105_bgn_cfg;
110extern const struct iwl_cfg iwl105_bgn_d_cfg;
111extern const struct iwl_cfg iwl135_bgn_cfg;
112extern const struct iwl_cfg iwl7260_2ac_cfg;
113extern const struct iwl_cfg iwl3160_ac_cfg;
114
115#endif /* __iwl_pci_h__ */
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 7bc0fb9128dd..0016bb24b3d7 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -69,8 +69,6 @@
69 69
70#include "iwl-trans.h" 70#include "iwl-trans.h"
71#include "iwl-drv.h" 71#include "iwl-drv.h"
72
73#include "cfg.h"
74#include "internal.h" 72#include "internal.h"
75 73
76#define IWL_PCI_DEVICE(dev, subdev, cfg) \ 74#define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -243,6 +241,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
243 {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)}, 241 {IWL_PCI_DEVICE(0x088F, 0x4260, iwl6035_2agn_cfg)},
244 {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)}, 242 {IWL_PCI_DEVICE(0x088E, 0x4460, iwl6035_2agn_cfg)},
245 {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)}, 243 {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)},
244 {IWL_PCI_DEVICE(0x088F, 0x5260, iwl6035_2agn_cfg)},
246 245
247/* 105 Series */ 246/* 105 Series */
248 {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, 247 {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index aa2a39a637dd..148843e7f34f 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -137,10 +137,6 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd)
137struct iwl_cmd_meta { 137struct iwl_cmd_meta {
138 /* only for SYNC commands, iff the reply skb is wanted */ 138 /* only for SYNC commands, iff the reply skb is wanted */
139 struct iwl_host_cmd *source; 139 struct iwl_host_cmd *source;
140
141 DEFINE_DMA_UNMAP_ADDR(mapping);
142 DEFINE_DMA_UNMAP_LEN(len);
143
144 u32 flags; 140 u32 flags;
145}; 141};
146 142
@@ -182,19 +178,39 @@ struct iwl_queue {
182#define TFD_TX_CMD_SLOTS 256 178#define TFD_TX_CMD_SLOTS 256
183#define TFD_CMD_SLOTS 32 179#define TFD_CMD_SLOTS 32
184 180
181/*
182 * The FH will write back to the first TB only, so we need
183 * to copy some data into the buffer regardless of whether
184 * it should be mapped or not. This indicates how big the
185 * first TB must be to include the scratch buffer. Since
186 * the scratch is 4 bytes at offset 12, it's 16 now. If we
187 * make it bigger then allocations will be bigger and copy
188 * slower, so that's probably not useful.
189 */
190#define IWL_HCMD_SCRATCHBUF_SIZE 16
191
185struct iwl_pcie_txq_entry { 192struct iwl_pcie_txq_entry {
186 struct iwl_device_cmd *cmd; 193 struct iwl_device_cmd *cmd;
187 struct iwl_device_cmd *copy_cmd;
188 struct sk_buff *skb; 194 struct sk_buff *skb;
189 /* buffer to free after command completes */ 195 /* buffer to free after command completes */
190 const void *free_buf; 196 const void *free_buf;
191 struct iwl_cmd_meta meta; 197 struct iwl_cmd_meta meta;
192}; 198};
193 199
200struct iwl_pcie_txq_scratch_buf {
201 struct iwl_cmd_header hdr;
202 u8 buf[8];
203 __le32 scratch;
204};
205
194/** 206/**
195 * struct iwl_txq - Tx Queue for DMA 207 * struct iwl_txq - Tx Queue for DMA
196 * @q: generic Rx/Tx queue descriptor 208 * @q: generic Rx/Tx queue descriptor
197 * @tfds: transmit frame descriptors (DMA memory) 209 * @tfds: transmit frame descriptors (DMA memory)
210 * @scratchbufs: start of command headers, including scratch buffers, for
211 * the writeback -- this is DMA memory and an array holding one buffer
212 * for each command on the queue
213 * @scratchbufs_dma: DMA address for the scratchbufs start
198 * @entries: transmit entries (driver state) 214 * @entries: transmit entries (driver state)
199 * @lock: queue lock 215 * @lock: queue lock
200 * @stuck_timer: timer that fires if queue gets stuck 216 * @stuck_timer: timer that fires if queue gets stuck
@@ -208,6 +224,8 @@ struct iwl_pcie_txq_entry {
208struct iwl_txq { 224struct iwl_txq {
209 struct iwl_queue q; 225 struct iwl_queue q;
210 struct iwl_tfd *tfds; 226 struct iwl_tfd *tfds;
227 struct iwl_pcie_txq_scratch_buf *scratchbufs;
228 dma_addr_t scratchbufs_dma;
211 struct iwl_pcie_txq_entry *entries; 229 struct iwl_pcie_txq_entry *entries;
212 spinlock_t lock; 230 spinlock_t lock;
213 struct timer_list stuck_timer; 231 struct timer_list stuck_timer;
@@ -216,6 +234,13 @@ struct iwl_txq {
216 u8 active; 234 u8 active;
217}; 235};
218 236
237static inline dma_addr_t
238iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
239{
240 return txq->scratchbufs_dma +
241 sizeof(struct iwl_pcie_txq_scratch_buf) * idx;
242}
243
219/** 244/**
220 * struct iwl_trans_pcie - PCIe transport specific data 245 * struct iwl_trans_pcie - PCIe transport specific data
221 * @rxq: all the RX queue data 246 * @rxq: all the RX queue data
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index b0ae06d2456f..567e67ad1f61 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -637,22 +637,14 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
637 index = SEQ_TO_INDEX(sequence); 637 index = SEQ_TO_INDEX(sequence);
638 cmd_index = get_cmd_index(&txq->q, index); 638 cmd_index = get_cmd_index(&txq->q, index);
639 639
640 if (reclaim) { 640 if (reclaim)
641 struct iwl_pcie_txq_entry *ent; 641 cmd = txq->entries[cmd_index].cmd;
642 ent = &txq->entries[cmd_index]; 642 else
643 cmd = ent->copy_cmd;
644 WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD);
645 } else {
646 cmd = NULL; 643 cmd = NULL;
647 }
648 644
649 err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); 645 err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
650 646
651 if (reclaim) { 647 if (reclaim) {
652 /* The original command isn't needed any more */
653 kfree(txq->entries[cmd_index].copy_cmd);
654 txq->entries[cmd_index].copy_cmd = NULL;
655 /* nor is the duplicated part of the command */
656 kfree(txq->entries[cmd_index].free_buf); 648 kfree(txq->entries[cmd_index].free_buf);
657 txq->entries[cmd_index].free_buf = NULL; 649 txq->entries[cmd_index].free_buf = NULL;
658 } 650 }
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 17bedc50e753..50ba0a468f94 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -22,7 +22,7 @@
22 * USA 22 * USA
23 * 23 *
24 * The full GNU General Public License is included in this distribution 24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL. 25 * in the file called COPYING.
26 * 26 *
27 * Contact Information: 27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com> 28 * Intel Linux Wireless <ilw@linux.intel.com>
@@ -475,6 +475,10 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
475 475
476 /* If platform's RF_KILL switch is NOT set to KILL */ 476 /* If platform's RF_KILL switch is NOT set to KILL */
477 hw_rfkill = iwl_is_rfkill_set(trans); 477 hw_rfkill = iwl_is_rfkill_set(trans);
478 if (hw_rfkill)
479 set_bit(STATUS_RFKILL, &trans_pcie->status);
480 else
481 clear_bit(STATUS_RFKILL, &trans_pcie->status);
478 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); 482 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
479 if (hw_rfkill && !run_in_rfkill) 483 if (hw_rfkill && !run_in_rfkill)
480 return -ERFKILL; 484 return -ERFKILL;
@@ -641,6 +645,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
641 645
642static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) 646static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
643{ 647{
648 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
644 bool hw_rfkill; 649 bool hw_rfkill;
645 int err; 650 int err;
646 651
@@ -656,6 +661,10 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
656 iwl_enable_rfkill_int(trans); 661 iwl_enable_rfkill_int(trans);
657 662
658 hw_rfkill = iwl_is_rfkill_set(trans); 663 hw_rfkill = iwl_is_rfkill_set(trans);
664 if (hw_rfkill)
665 set_bit(STATUS_RFKILL, &trans_pcie->status);
666 else
667 clear_bit(STATUS_RFKILL, &trans_pcie->status);
659 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); 668 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
660 669
661 return 0; 670 return 0;
@@ -694,6 +703,10 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans,
694 * op_mode. 703 * op_mode.
695 */ 704 */
696 hw_rfkill = iwl_is_rfkill_set(trans); 705 hw_rfkill = iwl_is_rfkill_set(trans);
706 if (hw_rfkill)
707 set_bit(STATUS_RFKILL, &trans_pcie->status);
708 else
709 clear_bit(STATUS_RFKILL, &trans_pcie->status);
697 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); 710 iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
698 } 711 }
699} 712}
@@ -715,7 +728,8 @@ static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs)
715 728
716static u32 iwl_trans_pcie_read_prph(struct iwl_trans *trans, u32 reg) 729static u32 iwl_trans_pcie_read_prph(struct iwl_trans *trans, u32 reg)
717{ 730{
718 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); 731 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR,
732 ((reg & 0x000FFFFF) | (3 << 24)));
719 return iwl_trans_pcie_read32(trans, HBUS_TARG_PRPH_RDAT); 733 return iwl_trans_pcie_read32(trans, HBUS_TARG_PRPH_RDAT);
720} 734}
721 735
@@ -723,7 +737,7 @@ static void iwl_trans_pcie_write_prph(struct iwl_trans *trans, u32 addr,
723 u32 val) 737 u32 val)
724{ 738{
725 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WADDR, 739 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WADDR,
726 ((addr & 0x0000FFFF) | (3 << 24))); 740 ((addr & 0x000FFFFF) | (3 << 24)));
727 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val); 741 iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val);
728} 742}
729 743
@@ -1370,28 +1384,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
1370 return ret; 1384 return ret;
1371} 1385}
1372 1386
1373static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
1374 const char __user *user_buf,
1375 size_t count, loff_t *ppos)
1376{
1377 struct iwl_trans *trans = file->private_data;
1378
1379 if (!trans->op_mode)
1380 return -EAGAIN;
1381
1382 local_bh_disable();
1383 iwl_op_mode_nic_error(trans->op_mode);
1384 local_bh_enable();
1385
1386 return count;
1387}
1388
1389DEBUGFS_READ_WRITE_FILE_OPS(interrupt); 1387DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
1390DEBUGFS_READ_FILE_OPS(fh_reg); 1388DEBUGFS_READ_FILE_OPS(fh_reg);
1391DEBUGFS_READ_FILE_OPS(rx_queue); 1389DEBUGFS_READ_FILE_OPS(rx_queue);
1392DEBUGFS_READ_FILE_OPS(tx_queue); 1390DEBUGFS_READ_FILE_OPS(tx_queue);
1393DEBUGFS_WRITE_FILE_OPS(csr); 1391DEBUGFS_WRITE_FILE_OPS(csr);
1394DEBUGFS_WRITE_FILE_OPS(fw_restart);
1395 1392
1396/* 1393/*
1397 * Create the debugfs files and directories 1394 * Create the debugfs files and directories
@@ -1405,7 +1402,6 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
1405 DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR); 1402 DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR);
1406 DEBUGFS_ADD_FILE(csr, dir, S_IWUSR); 1403 DEBUGFS_ADD_FILE(csr, dir, S_IWUSR);
1407 DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR); 1404 DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR);
1408 DEBUGFS_ADD_FILE(fw_restart, dir, S_IWUSR);
1409 return 0; 1405 return 0;
1410 1406
1411err: 1407err:
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index ad7441dfa6fb..d97c1fad7bc3 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -191,12 +191,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
191 } 191 }
192 192
193 for (i = q->read_ptr; i != q->write_ptr; 193 for (i = q->read_ptr; i != q->write_ptr;
194 i = iwl_queue_inc_wrap(i, q->n_bd)) { 194 i = iwl_queue_inc_wrap(i, q->n_bd))
195 struct iwl_tx_cmd *tx_cmd =
196 (struct iwl_tx_cmd *)txq->entries[i].cmd->payload;
197 IWL_ERR(trans, "scratch %d = 0x%08x\n", i, 195 IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
198 get_unaligned_le32(&tx_cmd->scratch)); 196 le32_to_cpu(txq->scratchbufs[i].scratch));
199 }
200 197
201 iwl_op_mode_nic_error(trans->op_mode); 198 iwl_op_mode_nic_error(trans->op_mode);
202} 199}
@@ -367,8 +364,8 @@ static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_tfd *tfd)
367} 364}
368 365
369static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, 366static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
370 struct iwl_cmd_meta *meta, struct iwl_tfd *tfd, 367 struct iwl_cmd_meta *meta,
371 enum dma_data_direction dma_dir) 368 struct iwl_tfd *tfd)
372{ 369{
373 int i; 370 int i;
374 int num_tbs; 371 int num_tbs;
@@ -382,17 +379,12 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
382 return; 379 return;
383 } 380 }
384 381
385 /* Unmap tx_cmd */ 382 /* first TB is never freed - it's the scratchbuf data */
386 if (num_tbs)
387 dma_unmap_single(trans->dev,
388 dma_unmap_addr(meta, mapping),
389 dma_unmap_len(meta, len),
390 DMA_BIDIRECTIONAL);
391 383
392 /* Unmap chunks, if any. */
393 for (i = 1; i < num_tbs; i++) 384 for (i = 1; i < num_tbs; i++)
394 dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i), 385 dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i),
395 iwl_pcie_tfd_tb_get_len(tfd, i), dma_dir); 386 iwl_pcie_tfd_tb_get_len(tfd, i),
387 DMA_TO_DEVICE);
396 388
397 tfd->num_tbs = 0; 389 tfd->num_tbs = 0;
398} 390}
@@ -406,8 +398,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
406 * Does NOT advance any TFD circular buffer read/write indexes 398 * Does NOT advance any TFD circular buffer read/write indexes
407 * Does NOT free the TFD itself (which is within circular buffer) 399 * Does NOT free the TFD itself (which is within circular buffer)
408 */ 400 */
409static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, 401static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)
410 enum dma_data_direction dma_dir)
411{ 402{
412 struct iwl_tfd *tfd_tmp = txq->tfds; 403 struct iwl_tfd *tfd_tmp = txq->tfds;
413 404
@@ -418,8 +409,7 @@ static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq,
418 lockdep_assert_held(&txq->lock); 409 lockdep_assert_held(&txq->lock);
419 410
420 /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ 411 /* We have only q->n_window txq->entries, but we use q->n_bd tfds */
421 iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], 412 iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr]);
422 dma_dir);
423 413
424 /* free SKB */ 414 /* free SKB */
425 if (txq->entries) { 415 if (txq->entries) {
@@ -479,6 +469,7 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans,
479{ 469{
480 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 470 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
481 size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; 471 size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX;
472 size_t scratchbuf_sz;
482 int i; 473 int i;
483 474
484 if (WARN_ON(txq->entries || txq->tfds)) 475 if (WARN_ON(txq->entries || txq->tfds))
@@ -514,9 +505,25 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans,
514 IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); 505 IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
515 goto error; 506 goto error;
516 } 507 }
508
509 BUILD_BUG_ON(IWL_HCMD_SCRATCHBUF_SIZE != sizeof(*txq->scratchbufs));
510 BUILD_BUG_ON(offsetof(struct iwl_pcie_txq_scratch_buf, scratch) !=
511 sizeof(struct iwl_cmd_header) +
512 offsetof(struct iwl_tx_cmd, scratch));
513
514 scratchbuf_sz = sizeof(*txq->scratchbufs) * slots_num;
515
516 txq->scratchbufs = dma_alloc_coherent(trans->dev, scratchbuf_sz,
517 &txq->scratchbufs_dma,
518 GFP_KERNEL);
519 if (!txq->scratchbufs)
520 goto err_free_tfds;
521
517 txq->q.id = txq_id; 522 txq->q.id = txq_id;
518 523
519 return 0; 524 return 0;
525err_free_tfds:
526 dma_free_coherent(trans->dev, tfd_sz, txq->tfds, txq->q.dma_addr);
520error: 527error:
521 if (txq->entries && txq_id == trans_pcie->cmd_queue) 528 if (txq->entries && txq_id == trans_pcie->cmd_queue)
522 for (i = 0; i < slots_num; i++) 529 for (i = 0; i < slots_num; i++)
@@ -565,22 +572,13 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
565 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 572 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
566 struct iwl_txq *txq = &trans_pcie->txq[txq_id]; 573 struct iwl_txq *txq = &trans_pcie->txq[txq_id];
567 struct iwl_queue *q = &txq->q; 574 struct iwl_queue *q = &txq->q;
568 enum dma_data_direction dma_dir;
569 575
570 if (!q->n_bd) 576 if (!q->n_bd)
571 return; 577 return;
572 578
573 /* In the command queue, all the TBs are mapped as BIDI
574 * so unmap them as such.
575 */
576 if (txq_id == trans_pcie->cmd_queue)
577 dma_dir = DMA_BIDIRECTIONAL;
578 else
579 dma_dir = DMA_TO_DEVICE;
580
581 spin_lock_bh(&txq->lock); 579 spin_lock_bh(&txq->lock);
582 while (q->write_ptr != q->read_ptr) { 580 while (q->write_ptr != q->read_ptr) {
583 iwl_pcie_txq_free_tfd(trans, txq, dma_dir); 581 iwl_pcie_txq_free_tfd(trans, txq);
584 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); 582 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
585 } 583 }
586 spin_unlock_bh(&txq->lock); 584 spin_unlock_bh(&txq->lock);
@@ -610,7 +608,6 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
610 if (txq_id == trans_pcie->cmd_queue) 608 if (txq_id == trans_pcie->cmd_queue)
611 for (i = 0; i < txq->q.n_window; i++) { 609 for (i = 0; i < txq->q.n_window; i++) {
612 kfree(txq->entries[i].cmd); 610 kfree(txq->entries[i].cmd);
613 kfree(txq->entries[i].copy_cmd);
614 kfree(txq->entries[i].free_buf); 611 kfree(txq->entries[i].free_buf);
615 } 612 }
616 613
@@ -619,6 +616,10 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
619 dma_free_coherent(dev, sizeof(struct iwl_tfd) * 616 dma_free_coherent(dev, sizeof(struct iwl_tfd) *
620 txq->q.n_bd, txq->tfds, txq->q.dma_addr); 617 txq->q.n_bd, txq->tfds, txq->q.dma_addr);
621 txq->q.dma_addr = 0; 618 txq->q.dma_addr = 0;
619
620 dma_free_coherent(dev,
621 sizeof(*txq->scratchbufs) * txq->q.n_window,
622 txq->scratchbufs, txq->scratchbufs_dma);
622 } 623 }
623 624
624 kfree(txq->entries); 625 kfree(txq->entries);
@@ -962,7 +963,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
962 963
963 iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq); 964 iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq);
964 965
965 iwl_pcie_txq_free_tfd(trans, txq, DMA_TO_DEVICE); 966 iwl_pcie_txq_free_tfd(trans, txq);
966 } 967 }
967 968
968 iwl_pcie_txq_progress(trans_pcie, txq); 969 iwl_pcie_txq_progress(trans_pcie, txq);
@@ -1062,7 +1063,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
1062 iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); 1063 iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id));
1063 1064
1064 /* If this queue is mapped to a certain station: it is an AGG queue */ 1065 /* If this queue is mapped to a certain station: it is an AGG queue */
1065 if (sta_id != IWL_INVALID_STATION) { 1066 if (sta_id >= 0) {
1066 u16 ra_tid = BUILD_RAxTID(sta_id, tid); 1067 u16 ra_tid = BUILD_RAxTID(sta_id, tid);
1067 1068
1068 /* Map receiver-address / traffic-ID to this queue */ 1069 /* Map receiver-address / traffic-ID to this queue */
@@ -1152,20 +1153,37 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1152 void *dup_buf = NULL; 1153 void *dup_buf = NULL;
1153 dma_addr_t phys_addr; 1154 dma_addr_t phys_addr;
1154 int idx; 1155 int idx;
1155 u16 copy_size, cmd_size; 1156 u16 copy_size, cmd_size, scratch_size;
1156 bool had_nocopy = false; 1157 bool had_nocopy = false;
1157 int i; 1158 int i;
1158 u32 cmd_pos; 1159 u32 cmd_pos;
1160 const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD];
1161 u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD];
1159 1162
1160 copy_size = sizeof(out_cmd->hdr); 1163 copy_size = sizeof(out_cmd->hdr);
1161 cmd_size = sizeof(out_cmd->hdr); 1164 cmd_size = sizeof(out_cmd->hdr);
1162 1165
1163 /* need one for the header if the first is NOCOPY */ 1166 /* need one for the header if the first is NOCOPY */
1164 BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1); 1167 BUILD_BUG_ON(IWL_MAX_CMD_TBS_PER_TFD > IWL_NUM_OF_TBS - 1);
1168
1169 for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
1170 cmddata[i] = cmd->data[i];
1171 cmdlen[i] = cmd->len[i];
1165 1172
1166 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
1167 if (!cmd->len[i]) 1173 if (!cmd->len[i])
1168 continue; 1174 continue;
1175
1176 /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */
1177 if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) {
1178 int copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size;
1179
1180 if (copy > cmdlen[i])
1181 copy = cmdlen[i];
1182 cmdlen[i] -= copy;
1183 cmddata[i] += copy;
1184 copy_size += copy;
1185 }
1186
1169 if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { 1187 if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
1170 had_nocopy = true; 1188 had_nocopy = true;
1171 if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) { 1189 if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) {
@@ -1185,7 +1203,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1185 goto free_dup_buf; 1203 goto free_dup_buf;
1186 } 1204 }
1187 1205
1188 dup_buf = kmemdup(cmd->data[i], cmd->len[i], 1206 dup_buf = kmemdup(cmddata[i], cmdlen[i],
1189 GFP_ATOMIC); 1207 GFP_ATOMIC);
1190 if (!dup_buf) 1208 if (!dup_buf)
1191 return -ENOMEM; 1209 return -ENOMEM;
@@ -1195,7 +1213,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1195 idx = -EINVAL; 1213 idx = -EINVAL;
1196 goto free_dup_buf; 1214 goto free_dup_buf;
1197 } 1215 }
1198 copy_size += cmd->len[i]; 1216 copy_size += cmdlen[i];
1199 } 1217 }
1200 cmd_size += cmd->len[i]; 1218 cmd_size += cmd->len[i];
1201 } 1219 }
@@ -1242,30 +1260,30 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1242 1260
1243 /* and copy the data that needs to be copied */ 1261 /* and copy the data that needs to be copied */
1244 cmd_pos = offsetof(struct iwl_device_cmd, payload); 1262 cmd_pos = offsetof(struct iwl_device_cmd, payload);
1245 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { 1263 copy_size = sizeof(out_cmd->hdr);
1264 for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
1265 int copy = 0;
1266
1246 if (!cmd->len[i]) 1267 if (!cmd->len[i])
1247 continue; 1268 continue;
1248 if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
1249 IWL_HCMD_DFL_DUP))
1250 break;
1251 memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]);
1252 cmd_pos += cmd->len[i];
1253 }
1254 1269
1255 WARN_ON_ONCE(txq->entries[idx].copy_cmd); 1270 /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */
1271 if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) {
1272 copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size;
1256 1273
1257 /* 1274 if (copy > cmd->len[i])
1258 * since out_cmd will be the source address of the FH, it will write 1275 copy = cmd->len[i];
1259 * the retry count there. So when the user needs to receivce the HCMD 1276 }
1260 * that corresponds to the response in the response handler, it needs 1277
1261 * to set CMD_WANT_HCMD. 1278 /* copy everything if not nocopy/dup */
1262 */ 1279 if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
1263 if (cmd->flags & CMD_WANT_HCMD) { 1280 IWL_HCMD_DFL_DUP)))
1264 txq->entries[idx].copy_cmd = 1281 copy = cmd->len[i];
1265 kmemdup(out_cmd, cmd_pos, GFP_ATOMIC); 1282
1266 if (unlikely(!txq->entries[idx].copy_cmd)) { 1283 if (copy) {
1267 idx = -ENOMEM; 1284 memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy);
1268 goto out; 1285 cmd_pos += copy;
1286 copy_size += copy;
1269 } 1287 }
1270 } 1288 }
1271 1289
@@ -1275,22 +1293,35 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1275 out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), 1293 out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
1276 cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); 1294 cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue);
1277 1295
1278 phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, 1296 /* start the TFD with the scratchbuf */
1279 DMA_BIDIRECTIONAL); 1297 scratch_size = min_t(int, copy_size, IWL_HCMD_SCRATCHBUF_SIZE);
1280 if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { 1298 memcpy(&txq->scratchbufs[q->write_ptr], &out_cmd->hdr, scratch_size);
1281 idx = -ENOMEM; 1299 iwl_pcie_txq_build_tfd(trans, txq,
1282 goto out; 1300 iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr),
1283 } 1301 scratch_size, 1);
1284 1302
1285 dma_unmap_addr_set(out_meta, mapping, phys_addr); 1303 /* map first command fragment, if any remains */
1286 dma_unmap_len_set(out_meta, len, copy_size); 1304 if (copy_size > scratch_size) {
1305 phys_addr = dma_map_single(trans->dev,
1306 ((u8 *)&out_cmd->hdr) + scratch_size,
1307 copy_size - scratch_size,
1308 DMA_TO_DEVICE);
1309 if (dma_mapping_error(trans->dev, phys_addr)) {
1310 iwl_pcie_tfd_unmap(trans, out_meta,
1311 &txq->tfds[q->write_ptr]);
1312 idx = -ENOMEM;
1313 goto out;
1314 }
1287 1315
1288 iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1); 1316 iwl_pcie_txq_build_tfd(trans, txq, phys_addr,
1317 copy_size - scratch_size, 0);
1318 }
1289 1319
1290 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { 1320 /* map the remaining (adjusted) nocopy/dup fragments */
1291 const void *data = cmd->data[i]; 1321 for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
1322 const void *data = cmddata[i];
1292 1323
1293 if (!cmd->len[i]) 1324 if (!cmdlen[i])
1294 continue; 1325 continue;
1295 if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | 1326 if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
1296 IWL_HCMD_DFL_DUP))) 1327 IWL_HCMD_DFL_DUP)))
@@ -1298,16 +1329,15 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1298 if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) 1329 if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP)
1299 data = dup_buf; 1330 data = dup_buf;
1300 phys_addr = dma_map_single(trans->dev, (void *)data, 1331 phys_addr = dma_map_single(trans->dev, (void *)data,
1301 cmd->len[i], DMA_BIDIRECTIONAL); 1332 cmdlen[i], DMA_TO_DEVICE);
1302 if (dma_mapping_error(trans->dev, phys_addr)) { 1333 if (dma_mapping_error(trans->dev, phys_addr)) {
1303 iwl_pcie_tfd_unmap(trans, out_meta, 1334 iwl_pcie_tfd_unmap(trans, out_meta,
1304 &txq->tfds[q->write_ptr], 1335 &txq->tfds[q->write_ptr]);
1305 DMA_BIDIRECTIONAL);
1306 idx = -ENOMEM; 1336 idx = -ENOMEM;
1307 goto out; 1337 goto out;
1308 } 1338 }
1309 1339
1310 iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0); 1340 iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0);
1311 } 1341 }
1312 1342
1313 out_meta->flags = cmd->flags; 1343 out_meta->flags = cmd->flags;
@@ -1317,8 +1347,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1317 1347
1318 txq->need_update = 1; 1348 txq->need_update = 1;
1319 1349
1320 trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, 1350 trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr);
1321 &out_cmd->hdr, copy_size);
1322 1351
1323 /* start timer if queue currently empty */ 1352 /* start timer if queue currently empty */
1324 if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) 1353 if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout)
@@ -1377,7 +1406,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
1377 cmd = txq->entries[cmd_index].cmd; 1406 cmd = txq->entries[cmd_index].cmd;
1378 meta = &txq->entries[cmd_index].meta; 1407 meta = &txq->entries[cmd_index].meta;
1379 1408
1380 iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); 1409 iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index]);
1381 1410
1382 /* Input error checking is done when commands are added to queue. */ 1411 /* Input error checking is done when commands are added to queue. */
1383 if (meta->flags & CMD_WANT_SKB) { 1412 if (meta->flags & CMD_WANT_SKB) {
@@ -1537,8 +1566,11 @@ int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
1537 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) 1566 if (test_bit(STATUS_FW_ERROR, &trans_pcie->status))
1538 return -EIO; 1567 return -EIO;
1539 1568
1540 if (test_bit(STATUS_RFKILL, &trans_pcie->status)) 1569 if (test_bit(STATUS_RFKILL, &trans_pcie->status)) {
1570 IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n",
1571 cmd->id);
1541 return -ERFKILL; 1572 return -ERFKILL;
1573 }
1542 1574
1543 if (cmd->flags & CMD_ASYNC) 1575 if (cmd->flags & CMD_ASYNC)
1544 return iwl_pcie_send_hcmd_async(trans, cmd); 1576 return iwl_pcie_send_hcmd_async(trans, cmd);
@@ -1556,10 +1588,9 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1556 struct iwl_cmd_meta *out_meta; 1588 struct iwl_cmd_meta *out_meta;
1557 struct iwl_txq *txq; 1589 struct iwl_txq *txq;
1558 struct iwl_queue *q; 1590 struct iwl_queue *q;
1559 dma_addr_t phys_addr = 0; 1591 dma_addr_t tb0_phys, tb1_phys, scratch_phys;
1560 dma_addr_t txcmd_phys; 1592 void *tb1_addr;
1561 dma_addr_t scratch_phys; 1593 u16 len, tb1_len, tb2_len;
1562 u16 len, firstlen, secondlen;
1563 u8 wait_write_ptr = 0; 1594 u8 wait_write_ptr = 0;
1564 __le16 fc = hdr->frame_control; 1595 __le16 fc = hdr->frame_control;
1565 u8 hdr_len = ieee80211_hdrlen(fc); 1596 u8 hdr_len = ieee80211_hdrlen(fc);
@@ -1597,85 +1628,80 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1597 cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | 1628 cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
1598 INDEX_TO_SEQ(q->write_ptr))); 1629 INDEX_TO_SEQ(q->write_ptr)));
1599 1630
1631 tb0_phys = iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr);
1632 scratch_phys = tb0_phys + sizeof(struct iwl_cmd_header) +
1633 offsetof(struct iwl_tx_cmd, scratch);
1634
1635 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
1636 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
1637
1600 /* Set up first empty entry in queue's array of Tx/cmd buffers */ 1638 /* Set up first empty entry in queue's array of Tx/cmd buffers */
1601 out_meta = &txq->entries[q->write_ptr].meta; 1639 out_meta = &txq->entries[q->write_ptr].meta;
1602 1640
1603 /* 1641 /*
1604 * Use the first empty entry in this queue's command buffer array 1642 * The second TB (tb1) points to the remainder of the TX command
1605 * to contain the Tx command and MAC header concatenated together 1643 * and the 802.11 header - dword aligned size
1606 * (payload data will be in another buffer). 1644 * (This calculation modifies the TX command, so do it before the
1607 * Size of this varies, due to varying MAC header length. 1645 * setup of the first TB)
1608 * If end is not dword aligned, we'll have 2 extra bytes at the end
1609 * of the MAC header (device reads on dword boundaries).
1610 * We'll tell device about this padding later.
1611 */ 1646 */
1612 len = sizeof(struct iwl_tx_cmd) + 1647 len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) +
1613 sizeof(struct iwl_cmd_header) + hdr_len; 1648 hdr_len - IWL_HCMD_SCRATCHBUF_SIZE;
1614 firstlen = (len + 3) & ~3; 1649 tb1_len = (len + 3) & ~3;
1615 1650
1616 /* Tell NIC about any 2-byte padding after MAC header */ 1651 /* Tell NIC about any 2-byte padding after MAC header */
1617 if (firstlen != len) 1652 if (tb1_len != len)
1618 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; 1653 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
1619 1654
1620 /* Physical address of this Tx command's header (not MAC header!), 1655 /* The first TB points to the scratchbuf data - min_copy bytes */
1621 * within command buffer array. */ 1656 memcpy(&txq->scratchbufs[q->write_ptr], &dev_cmd->hdr,
1622 txcmd_phys = dma_map_single(trans->dev, 1657 IWL_HCMD_SCRATCHBUF_SIZE);
1623 &dev_cmd->hdr, firstlen, 1658 iwl_pcie_txq_build_tfd(trans, txq, tb0_phys,
1624 DMA_BIDIRECTIONAL); 1659 IWL_HCMD_SCRATCHBUF_SIZE, 1);
1625 if (unlikely(dma_mapping_error(trans->dev, txcmd_phys)))
1626 goto out_err;
1627 dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
1628 dma_unmap_len_set(out_meta, len, firstlen);
1629 1660
1630 if (!ieee80211_has_morefrags(fc)) { 1661 /* there must be data left over for TB1 or this code must be changed */
1631 txq->need_update = 1; 1662 BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_HCMD_SCRATCHBUF_SIZE);
1632 } else { 1663
1633 wait_write_ptr = 1; 1664 /* map the data for TB1 */
1634 txq->need_update = 0; 1665 tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_HCMD_SCRATCHBUF_SIZE;
1635 } 1666 tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE);
1667 if (unlikely(dma_mapping_error(trans->dev, tb1_phys)))
1668 goto out_err;
1669 iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, 0);
1636 1670
1637 /* Set up TFD's 2nd entry to point directly to remainder of skb, 1671 /*
1638 * if any (802.11 null frames have no payload). */ 1672 * Set up TFD's third entry to point directly to remainder
1639 secondlen = skb->len - hdr_len; 1673 * of skb, if any (802.11 null frames have no payload).
1640 if (secondlen > 0) { 1674 */
1641 phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, 1675 tb2_len = skb->len - hdr_len;
1642 secondlen, DMA_TO_DEVICE); 1676 if (tb2_len > 0) {
1643 if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { 1677 dma_addr_t tb2_phys = dma_map_single(trans->dev,
1644 dma_unmap_single(trans->dev, 1678 skb->data + hdr_len,
1645 dma_unmap_addr(out_meta, mapping), 1679 tb2_len, DMA_TO_DEVICE);
1646 dma_unmap_len(out_meta, len), 1680 if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) {
1647 DMA_BIDIRECTIONAL); 1681 iwl_pcie_tfd_unmap(trans, out_meta,
1682 &txq->tfds[q->write_ptr]);
1648 goto out_err; 1683 goto out_err;
1649 } 1684 }
1685 iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, 0);
1650 } 1686 }
1651 1687
1652 /* Attach buffers to TFD */
1653 iwl_pcie_txq_build_tfd(trans, txq, txcmd_phys, firstlen, 1);
1654 if (secondlen > 0)
1655 iwl_pcie_txq_build_tfd(trans, txq, phys_addr, secondlen, 0);
1656
1657 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
1658 offsetof(struct iwl_tx_cmd, scratch);
1659
1660 /* take back ownership of DMA buffer to enable update */
1661 dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen,
1662 DMA_BIDIRECTIONAL);
1663 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
1664 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
1665
1666 /* Set up entry for this TFD in Tx byte-count array */ 1688 /* Set up entry for this TFD in Tx byte-count array */
1667 iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); 1689 iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));
1668 1690
1669 dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,
1670 DMA_BIDIRECTIONAL);
1671
1672 trace_iwlwifi_dev_tx(trans->dev, skb, 1691 trace_iwlwifi_dev_tx(trans->dev, skb,
1673 &txq->tfds[txq->q.write_ptr], 1692 &txq->tfds[txq->q.write_ptr],
1674 sizeof(struct iwl_tfd), 1693 sizeof(struct iwl_tfd),
1675 &dev_cmd->hdr, firstlen, 1694 &dev_cmd->hdr, IWL_HCMD_SCRATCHBUF_SIZE + tb1_len,
1676 skb->data + hdr_len, secondlen); 1695 skb->data + hdr_len, tb2_len);
1677 trace_iwlwifi_dev_tx_data(trans->dev, skb, 1696 trace_iwlwifi_dev_tx_data(trans->dev, skb,
1678 skb->data + hdr_len, secondlen); 1697 skb->data + hdr_len, tb2_len);
1698
1699 if (!ieee80211_has_morefrags(fc)) {
1700 txq->need_update = 1;
1701 } else {
1702 wait_write_ptr = 1;
1703 txq->need_update = 0;
1704 }
1679 1705
1680 /* start timer if queue currently empty */ 1706 /* start timer if queue currently empty */
1681 if (txq->need_update && q->read_ptr == q->write_ptr && 1707 if (txq->need_update && q->read_ptr == q->write_ptr &&