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/dvm/sta.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h20
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c104
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h18
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c133
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c19
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c18
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c37
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c6
-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/tx.c299
18 files changed, 370 insertions, 385 deletions
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/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 9a0f45ec9e01..81aa91fab5aa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -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..fbfd2d137117 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -1102,7 +1102,6 @@ void iwl_drv_stop(struct iwl_drv *drv)
1102 1102
1103/* shared module parameters */ 1103/* shared module parameters */
1104struct iwl_mod_params iwlwifi_mod_params = { 1104struct iwl_mod_params iwlwifi_mod_params = {
1105 .amsdu_size_8K = 1,
1106 .restart_fw = 1, 1105 .restart_fw = 1,
1107 .plcp_check = true, 1106 .plcp_check = true,
1108 .bt_coex_active = true, 1107 .bt_coex_active = true,
@@ -1207,7 +1206,7 @@ MODULE_PARM_DESC(11n_disable,
1207 "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); 1206 "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX");
1208module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, 1207module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K,
1209 int, S_IRUGO); 1208 int, S_IRUGO);
1210MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); 1209MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)");
1211module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO); 1210module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO);
1212MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); 1211MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
1213 1212
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index e5e3a79eae2f..2c2a729092f5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -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
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
index 14fc8d39fc28..3392011a8768 100644
--- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
@@ -136,12 +136,6 @@ struct iwl_calib_res_notif_phy_db {
136 u8 data[]; 136 u8 data[];
137} __packed; 137} __packed;
138 138
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) 139struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans)
146{ 140{
147 struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db), 141 struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db),
@@ -260,11 +254,6 @@ 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; 254 (size - CHANNEL_NUM_SIZE) / phy_db->channel_num;
261 } 255 }
262 256
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, 257 IWL_DEBUG_INFO(phy_db->trans,
269 "%s(%d): [PHYDB]SET: Type %d , Size: %d\n", 258 "%s(%d): [PHYDB]SET: Type %d , Size: %d\n",
270 __func__, __LINE__, type, size); 259 __func__, __LINE__, type, size);
@@ -372,11 +361,6 @@ int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db,
372 *size = entry->size; 361 *size = entry->size;
373 } 362 }
374 363
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, 364 IWL_DEBUG_INFO(phy_db->trans,
381 "%s(%d): [PHYDB] GET: Type %d , Size: %d\n", 365 "%s(%d): [PHYDB] GET: Type %d , Size: %d\n",
382 __func__, __LINE__, type, *size); 366 __func__, __LINE__, type, *size);
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 8c7bec6b9a0b..0cac2b7af78b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -186,19 +186,13 @@ struct iwl_rx_packet {
186 * @CMD_ASYNC: Return right away and don't want for the response 186 * @CMD_ASYNC: Return right away and don't want for the response
187 * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the 187 * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the
188 * response. The caller needs to call iwl_free_resp when done. 188 * response. The caller needs to call iwl_free_resp when done.
189 * @CMD_WANT_HCMD: The caller needs to get the HCMD that was sent in the
190 * response handler. Chunks flagged by %IWL_HCMD_DFL_NOCOPY won't be
191 * copied. The pointer passed to the response handler is in the transport
192 * ownership and don't need to be freed by the op_mode. This also means
193 * that the pointer is invalidated after the op_mode's handler returns.
194 * @CMD_ON_DEMAND: This command is sent by the test mode pipe. 189 * @CMD_ON_DEMAND: This command is sent by the test mode pipe.
195 */ 190 */
196enum CMD_MODE { 191enum CMD_MODE {
197 CMD_SYNC = 0, 192 CMD_SYNC = 0,
198 CMD_ASYNC = BIT(0), 193 CMD_ASYNC = BIT(0),
199 CMD_WANT_SKB = BIT(1), 194 CMD_WANT_SKB = BIT(1),
200 CMD_WANT_HCMD = BIT(2), 195 CMD_ON_DEMAND = BIT(2),
201 CMD_ON_DEMAND = BIT(3),
202}; 196};
203 197
204#define DEF_CMD_PAYLOAD_SIZE 320 198#define DEF_CMD_PAYLOAD_SIZE 320
@@ -217,7 +211,11 @@ struct iwl_device_cmd {
217 211
218#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) 212#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
219 213
220#define IWL_MAX_CMD_TFDS 2 214/*
215 * number of transfer buffers (fragments) per transmit frame descriptor;
216 * this is just the driver's idea, the hardware supports 20
217 */
218#define IWL_MAX_CMD_TBS_PER_TFD 2
221 219
222/** 220/**
223 * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command 221 * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command
@@ -254,15 +252,15 @@ enum iwl_hcmd_dataflag {
254 * @id: id of the host command 252 * @id: id of the host command
255 */ 253 */
256struct iwl_host_cmd { 254struct iwl_host_cmd {
257 const void *data[IWL_MAX_CMD_TFDS]; 255 const void *data[IWL_MAX_CMD_TBS_PER_TFD];
258 struct iwl_rx_packet *resp_pkt; 256 struct iwl_rx_packet *resp_pkt;
259 unsigned long _rx_page_addr; 257 unsigned long _rx_page_addr;
260 u32 _rx_page_order; 258 u32 _rx_page_order;
261 int handler_status; 259 int handler_status;
262 260
263 u32 flags; 261 u32 flags;
264 u16 len[IWL_MAX_CMD_TFDS]; 262 u16 len[IWL_MAX_CMD_TBS_PER_TFD];
265 u8 dataflags[IWL_MAX_CMD_TFDS]; 263 u8 dataflags[IWL_MAX_CMD_TBS_PER_TFD];
266 u8 id; 264 u8 id;
267}; 265};
268 266
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index c64d864799cd..994c8c263dc0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -61,6 +61,7 @@
61 * 61 *
62 *****************************************************************************/ 62 *****************************************************************************/
63 63
64#include <linux/etherdevice.h>
64#include <net/cfg80211.h> 65#include <net/cfg80211.h>
65#include <net/ipv6.h> 66#include <net/ipv6.h>
66#include "iwl-modparams.h" 67#include "iwl-modparams.h"
@@ -192,6 +193,11 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
192 sizeof(wkc), &wkc); 193 sizeof(wkc), &wkc);
193 data->error = ret != 0; 194 data->error = ret != 0;
194 195
196 mvm->ptk_ivlen = key->iv_len;
197 mvm->ptk_icvlen = key->icv_len;
198 mvm->gtk_ivlen = key->iv_len;
199 mvm->gtk_icvlen = key->icv_len;
200
195 /* don't upload key again */ 201 /* don't upload key again */
196 goto out_unlock; 202 goto out_unlock;
197 } 203 }
@@ -304,9 +310,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
304 */ 310 */
305 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { 311 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
306 key->hw_key_idx = 0; 312 key->hw_key_idx = 0;
313 mvm->ptk_ivlen = key->iv_len;
314 mvm->ptk_icvlen = key->icv_len;
307 } else { 315 } else {
308 data->gtk_key_idx++; 316 data->gtk_key_idx++;
309 key->hw_key_idx = data->gtk_key_idx; 317 key->hw_key_idx = data->gtk_key_idx;
318 mvm->gtk_ivlen = key->iv_len;
319 mvm->gtk_icvlen = key->icv_len;
310 } 320 }
311 321
312 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true); 322 ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true);
@@ -649,6 +659,11 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
649 /* We reprogram keys and shouldn't allocate new key indices */ 659 /* We reprogram keys and shouldn't allocate new key indices */
650 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); 660 memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
651 661
662 mvm->ptk_ivlen = 0;
663 mvm->ptk_icvlen = 0;
664 mvm->ptk_ivlen = 0;
665 mvm->ptk_icvlen = 0;
666
652 /* 667 /*
653 * The D3 firmware still hardcodes the AP station ID for the 668 * 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 669 * BSS we're associated with as 0. As a result, we have to move
@@ -783,7 +798,6 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
783 struct iwl_wowlan_status *status; 798 struct iwl_wowlan_status *status;
784 u32 reasons; 799 u32 reasons;
785 int ret, len; 800 int ret, len;
786 bool pkt8023 = false;
787 struct sk_buff *pkt = NULL; 801 struct sk_buff *pkt = NULL;
788 802
789 iwl_trans_read_mem_bytes(mvm->trans, base, 803 iwl_trans_read_mem_bytes(mvm->trans, base,
@@ -824,7 +838,8 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
824 status = (void *)cmd.resp_pkt->data; 838 status = (void *)cmd.resp_pkt->data;
825 839
826 if (len - sizeof(struct iwl_cmd_header) != 840 if (len - sizeof(struct iwl_cmd_header) !=
827 sizeof(*status) + le32_to_cpu(status->wake_packet_bufsize)) { 841 sizeof(*status) +
842 ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) {
828 IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); 843 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
829 goto out; 844 goto out;
830 } 845 }
@@ -836,61 +851,96 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
836 goto report; 851 goto report;
837 } 852 }
838 853
839 if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) { 854 if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET)
840 wakeup.magic_pkt = true; 855 wakeup.magic_pkt = true;
841 pkt8023 = true;
842 }
843 856
844 if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) { 857 if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN)
845 wakeup.pattern_idx = 858 wakeup.pattern_idx =
846 le16_to_cpu(status->pattern_number); 859 le16_to_cpu(status->pattern_number);
847 pkt8023 = true;
848 }
849 860
850 if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | 861 if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
851 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)) 862 IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH))
852 wakeup.disconnect = true; 863 wakeup.disconnect = true;
853 864
854 if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) { 865 if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)
855 wakeup.gtk_rekey_failure = true; 866 wakeup.gtk_rekey_failure = true;
856 pkt8023 = true;
857 }
858 867
859 if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) { 868 if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
860 wakeup.rfkill_release = true; 869 wakeup.rfkill_release = true;
861 pkt8023 = true;
862 }
863 870
864 if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) { 871 if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST)
865 wakeup.eap_identity_req = true; 872 wakeup.eap_identity_req = true;
866 pkt8023 = true;
867 }
868 873
869 if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) { 874 if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE)
870 wakeup.four_way_handshake = true; 875 wakeup.four_way_handshake = true;
871 pkt8023 = true;
872 }
873 876
874 if (status->wake_packet_bufsize) { 877 if (status->wake_packet_bufsize) {
875 u32 pktsize = le32_to_cpu(status->wake_packet_bufsize); 878 int pktsize = le32_to_cpu(status->wake_packet_bufsize);
876 u32 pktlen = le32_to_cpu(status->wake_packet_length); 879 int pktlen = le32_to_cpu(status->wake_packet_length);
880 const u8 *pktdata = status->wake_packet;
881 struct ieee80211_hdr *hdr = (void *)pktdata;
882 int truncated = pktlen - pktsize;
883
884 /* this would be a firmware bug */
885 if (WARN_ON_ONCE(truncated < 0))
886 truncated = 0;
887
888 if (ieee80211_is_data(hdr->frame_control)) {
889 int hdrlen = ieee80211_hdrlen(hdr->frame_control);
890 int ivlen = 0, icvlen = 4; /* also FCS */
877 891
878 if (pkt8023) {
879 pkt = alloc_skb(pktsize, GFP_KERNEL); 892 pkt = alloc_skb(pktsize, GFP_KERNEL);
880 if (!pkt) 893 if (!pkt)
881 goto report; 894 goto report;
882 memcpy(skb_put(pkt, pktsize), status->wake_packet, 895
883 pktsize); 896 memcpy(skb_put(pkt, hdrlen), pktdata, hdrlen);
897 pktdata += hdrlen;
898 pktsize -= hdrlen;
899
900 if (ieee80211_has_protected(hdr->frame_control)) {
901 if (is_multicast_ether_addr(hdr->addr1)) {
902 ivlen = mvm->gtk_ivlen;
903 icvlen += mvm->gtk_icvlen;
904 } else {
905 ivlen = mvm->ptk_ivlen;
906 icvlen += mvm->ptk_icvlen;
907 }
908 }
909
910 /* if truncated, FCS/ICV is (partially) gone */
911 if (truncated >= icvlen) {
912 icvlen = 0;
913 truncated -= icvlen;
914 } else {
915 icvlen -= truncated;
916 truncated = 0;
917 }
918
919 pktsize -= ivlen + icvlen;
920 pktdata += ivlen;
921
922 memcpy(skb_put(pkt, pktsize), pktdata, pktsize);
923
884 if (ieee80211_data_to_8023(pkt, vif->addr, vif->type)) 924 if (ieee80211_data_to_8023(pkt, vif->addr, vif->type))
885 goto report; 925 goto report;
886 wakeup.packet = pkt->data; 926 wakeup.packet = pkt->data;
887 wakeup.packet_present_len = pkt->len; 927 wakeup.packet_present_len = pkt->len;
888 wakeup.packet_len = pkt->len - (pktlen - pktsize); 928 wakeup.packet_len = pkt->len - truncated;
889 wakeup.packet_80211 = false; 929 wakeup.packet_80211 = false;
890 } else { 930 } else {
931 int fcslen = 4;
932
933 if (truncated >= 4) {
934 truncated -= 4;
935 fcslen = 0;
936 } else {
937 fcslen -= truncated;
938 truncated = 0;
939 }
940 pktsize -= fcslen;
891 wakeup.packet = status->wake_packet; 941 wakeup.packet = status->wake_packet;
892 wakeup.packet_present_len = pktsize; 942 wakeup.packet_present_len = pktsize;
893 wakeup.packet_len = pktlen; 943 wakeup.packet_len = pktlen - truncated;
894 wakeup.packet_80211 = true; 944 wakeup.packet_80211 = true;
895 } 945 }
896 } 946 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 23eebda848b0..2adb61f103f4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -762,18 +762,20 @@ struct iwl_phy_context_cmd {
762#define IWL_RX_INFO_PHY_CNT 8 762#define IWL_RX_INFO_PHY_CNT 8
763#define IWL_RX_INFO_AGC_IDX 1 763#define IWL_RX_INFO_AGC_IDX 1
764#define IWL_RX_INFO_RSSI_AB_IDX 2 764#define IWL_RX_INFO_RSSI_AB_IDX 2
765#define IWL_RX_INFO_RSSI_C_IDX 3 765#define IWL_OFDM_AGC_A_MSK 0x0000007f
766#define IWL_OFDM_AGC_DB_MSK 0xfe00 766#define IWL_OFDM_AGC_A_POS 0
767#define IWL_OFDM_AGC_DB_POS 9 767#define IWL_OFDM_AGC_B_MSK 0x00003f80
768#define IWL_OFDM_AGC_B_POS 7
769#define IWL_OFDM_AGC_CODE_MSK 0x3fe00000
770#define IWL_OFDM_AGC_CODE_POS 20
768#define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff 771#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 772#define IWL_OFDM_RSSI_A_POS 0
773#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00
774#define IWL_OFDM_RSSI_ALLBAND_A_POS 8
771#define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000 775#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 776#define IWL_OFDM_RSSI_B_POS 16
774#define IWL_OFDM_RSSI_INBAND_C_MSK 0x00ff 777#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000
775#define IWL_OFDM_RSSI_ALLBAND_C_MSK 0xff00 778#define IWL_OFDM_RSSI_ALLBAND_B_POS 24
776#define IWL_OFDM_RSSI_C_POS 0
777 779
778/** 780/**
779 * struct iwl_rx_phy_info - phy info 781 * struct iwl_rx_phy_info - phy info
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index d3d959db03a9..500f818dba04 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -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
@@ -241,20 +227,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
241 227
242 return 0; 228 return 0;
243} 229}
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 230
259static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) 231static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
260{ 232{
@@ -262,7 +234,7 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
262 enum iwl_ucode_type ucode_type = mvm->cur_ucode; 234 enum iwl_ucode_type ucode_type = mvm->cur_ucode;
263 235
264 /* Set parameters */ 236 /* Set parameters */
265 phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_build_phy_cfg(mvm)); 237 phy_cfg_cmd.phy_cfg = cpu_to_le32(mvm->fw->phy_config);
266 phy_cfg_cmd.calib_control.event_trigger = 238 phy_cfg_cmd.calib_control.event_trigger =
267 mvm->fw->default_calib[ucode_type].event_trigger; 239 mvm->fw->default_calib[ucode_type].event_trigger;
268 phy_cfg_cmd.calib_control.flow_trigger = 240 phy_cfg_cmd.calib_control.flow_trigger =
@@ -275,103 +247,6 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
275 sizeof(phy_cfg_cmd), &phy_cfg_cmd); 247 sizeof(phy_cfg_cmd), &phy_cfg_cmd);
276} 248}
277 249
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) 250static int iwl_set_default_calibrations(struct iwl_mvm *mvm)
376{ 251{
377 u8 cmd_raw[16]; /* holds the variable size commands */ 252 u8 cmd_raw[16]; /* holds the variable size commands */
@@ -446,8 +321,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
446 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); 321 ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
447 WARN_ON(ret); 322 WARN_ON(ret);
448 323
449 /* Override the calibrations from TLV and the const of fw */ 324 /* Send TX valid antennas before triggering calibrations */
450 iwl_set_default_calib_trigger(mvm); 325 ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant);
326 if (ret)
327 goto error;
451 328
452 /* WkP doesn't have all calibrations, need to set default values */ 329 /* WkP doesn't have all calibrations, need to set default values */
453 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 330 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index e8264e11b12d..7e169b085afe 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -557,11 +557,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
557 return ret; 557 return ret;
558} 558}
559 559
560static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, 560static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
561 struct ieee80211_vif *vif) 561 struct ieee80211_vif *vif)
562{ 562{
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; 563 u32 tfd_msk = 0, ac;
566 564
567 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 565 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
@@ -594,12 +592,21 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
594 */ 592 */
595 flush_work(&mvm->sta_drained_wk); 593 flush_work(&mvm->sta_drained_wk);
596 } 594 }
595}
596
597static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
598 struct ieee80211_vif *vif)
599{
600 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
601 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
602
603 iwl_mvm_prepare_mac_removal(mvm, vif);
597 604
598 mutex_lock(&mvm->mutex); 605 mutex_lock(&mvm->mutex);
599 606
600 /* 607 /*
601 * For AP/GO interface, the tear down of the resources allocated to the 608 * 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. 609 * interface is be handled as part of the stop_ap flow.
603 */ 610 */
604 if (vif->type == NL80211_IFTYPE_AP) { 611 if (vif->type == NL80211_IFTYPE_AP) {
605 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); 612 iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
@@ -763,6 +770,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); 770 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
764 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 771 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
765 772
773 iwl_mvm_prepare_mac_removal(mvm, vif);
774
766 mutex_lock(&mvm->mutex); 775 mutex_lock(&mvm->mutex);
767 776
768 mvmvif->ap_active = false; 777 mvmvif->ap_active = false;
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 4e339ccfa800..bdae700c769e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -80,7 +80,8 @@
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 2
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,
@@ -327,6 +328,10 @@ struct iwl_mvm {
327 struct led_classdev led; 328 struct led_classdev led;
328 329
329 struct ieee80211_vif *p2p_device_vif; 330 struct ieee80211_vif *p2p_device_vif;
331
332#ifdef CONFIG_PM_SLEEP
333 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
334#endif
330}; 335};
331 336
332/* Extract MVM priv from op_mode and _hw */ 337/* Extract MVM priv from op_mode and _hw */
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index aa59adf87db3..d0f9c1e0475e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -624,12 +624,8 @@ static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
624 ieee80211_free_txskb(mvm->hw, skb); 624 ieee80211_free_txskb(mvm->hw, skb);
625} 625}
626 626
627static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) 627static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
628{ 628{
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); 629 iwl_abort_notification_waits(&mvm->notif_wait);
634 630
635 /* 631 /*
@@ -663,9 +659,21 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
663 } 659 }
664} 660}
665 661
662static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
663{
664 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
665
666 iwl_mvm_dump_nic_error_log(mvm);
667
668 iwl_mvm_nic_restart(mvm);
669}
670
666static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode) 671static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
667{ 672{
673 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
674
668 WARN_ON(1); 675 WARN_ON(1);
676 iwl_mvm_nic_restart(mvm);
669} 677}
670 678
671static const struct iwl_op_mode_ops iwl_mvm_ops = { 679static const struct iwl_op_mode_ops iwl_mvm_ops = {
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 3f40ab05bbd8..b0b190d0ec23 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -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/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 861a7f9f8e7f..274f44e2ef60 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -770,6 +770,16 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
770 u16 txq_id; 770 u16 txq_id;
771 int err; 771 int err;
772 772
773
774 /*
775 * If mac80211 is cleaning its state, then say that we finished since
776 * our state has been cleared anyway.
777 */
778 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
779 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
780 return 0;
781 }
782
773 spin_lock_bh(&mvmsta->lock); 783 spin_lock_bh(&mvmsta->lock);
774 784
775 txq_id = tid_data->txq_id; 785 txq_id = tid_data->txq_id;
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 6b67ce3f679c..6645efe5c03e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -607,12 +607,8 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
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_FIRST_AMPDU_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) {
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/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 8e9e3212fe78..8595c16f74de 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);
@@ -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);
1246 if (!cmd->len[i]) 1264 for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
1265 int copy = 0;
1266
1267 if (!cmd->len)
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) {
@@ -1556,10 +1585,9 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1556 struct iwl_cmd_meta *out_meta; 1585 struct iwl_cmd_meta *out_meta;
1557 struct iwl_txq *txq; 1586 struct iwl_txq *txq;
1558 struct iwl_queue *q; 1587 struct iwl_queue *q;
1559 dma_addr_t phys_addr = 0; 1588 dma_addr_t tb0_phys, tb1_phys, scratch_phys;
1560 dma_addr_t txcmd_phys; 1589 void *tb1_addr;
1561 dma_addr_t scratch_phys; 1590 u16 len, tb1_len, tb2_len;
1562 u16 len, firstlen, secondlen;
1563 u8 wait_write_ptr = 0; 1591 u8 wait_write_ptr = 0;
1564 __le16 fc = hdr->frame_control; 1592 __le16 fc = hdr->frame_control;
1565 u8 hdr_len = ieee80211_hdrlen(fc); 1593 u8 hdr_len = ieee80211_hdrlen(fc);
@@ -1597,85 +1625,80 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1597 cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | 1625 cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
1598 INDEX_TO_SEQ(q->write_ptr))); 1626 INDEX_TO_SEQ(q->write_ptr)));
1599 1627
1628 tb0_phys = iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr);
1629 scratch_phys = tb0_phys + sizeof(struct iwl_cmd_header) +
1630 offsetof(struct iwl_tx_cmd, scratch);
1631
1632 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
1633 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
1634
1600 /* Set up first empty entry in queue's array of Tx/cmd buffers */ 1635 /* Set up first empty entry in queue's array of Tx/cmd buffers */
1601 out_meta = &txq->entries[q->write_ptr].meta; 1636 out_meta = &txq->entries[q->write_ptr].meta;
1602 1637
1603 /* 1638 /*
1604 * Use the first empty entry in this queue's command buffer array 1639 * The second TB (tb1) points to the remainder of the TX command
1605 * to contain the Tx command and MAC header concatenated together 1640 * and the 802.11 header - dword aligned size
1606 * (payload data will be in another buffer). 1641 * (This calculation modifies the TX command, so do it before the
1607 * Size of this varies, due to varying MAC header length. 1642 * 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 */ 1643 */
1612 len = sizeof(struct iwl_tx_cmd) + 1644 len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) +
1613 sizeof(struct iwl_cmd_header) + hdr_len; 1645 hdr_len - IWL_HCMD_SCRATCHBUF_SIZE;
1614 firstlen = (len + 3) & ~3; 1646 tb1_len = (len + 3) & ~3;
1615 1647
1616 /* Tell NIC about any 2-byte padding after MAC header */ 1648 /* Tell NIC about any 2-byte padding after MAC header */
1617 if (firstlen != len) 1649 if (tb1_len != len)
1618 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; 1650 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
1619 1651
1620 /* Physical address of this Tx command's header (not MAC header!), 1652 /* The first TB points to the scratchbuf data - min_copy bytes */
1621 * within command buffer array. */ 1653 memcpy(&txq->scratchbufs[q->write_ptr], &dev_cmd->hdr,
1622 txcmd_phys = dma_map_single(trans->dev, 1654 IWL_HCMD_SCRATCHBUF_SIZE);
1623 &dev_cmd->hdr, firstlen, 1655 iwl_pcie_txq_build_tfd(trans, txq, tb0_phys,
1624 DMA_BIDIRECTIONAL); 1656 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 1657
1630 if (!ieee80211_has_morefrags(fc)) { 1658 /* there must be data left over for TB1 or this code must be changed */
1631 txq->need_update = 1; 1659 BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_HCMD_SCRATCHBUF_SIZE);
1632 } else { 1660
1633 wait_write_ptr = 1; 1661 /* map the data for TB1 */
1634 txq->need_update = 0; 1662 tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_HCMD_SCRATCHBUF_SIZE;
1635 } 1663 tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE);
1664 if (unlikely(dma_mapping_error(trans->dev, tb1_phys)))
1665 goto out_err;
1666 iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, 0);
1636 1667
1637 /* Set up TFD's 2nd entry to point directly to remainder of skb, 1668 /*
1638 * if any (802.11 null frames have no payload). */ 1669 * Set up TFD's third entry to point directly to remainder
1639 secondlen = skb->len - hdr_len; 1670 * of skb, if any (802.11 null frames have no payload).
1640 if (secondlen > 0) { 1671 */
1641 phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, 1672 tb2_len = skb->len - hdr_len;
1642 secondlen, DMA_TO_DEVICE); 1673 if (tb2_len > 0) {
1643 if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { 1674 dma_addr_t tb2_phys = dma_map_single(trans->dev,
1644 dma_unmap_single(trans->dev, 1675 skb->data + hdr_len,
1645 dma_unmap_addr(out_meta, mapping), 1676 tb2_len, DMA_TO_DEVICE);
1646 dma_unmap_len(out_meta, len), 1677 if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) {
1647 DMA_BIDIRECTIONAL); 1678 iwl_pcie_tfd_unmap(trans, out_meta,
1679 &txq->tfds[q->write_ptr]);
1648 goto out_err; 1680 goto out_err;
1649 } 1681 }
1682 iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, 0);
1650 } 1683 }
1651 1684
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 */ 1685 /* 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)); 1686 iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));
1668 1687
1669 dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,
1670 DMA_BIDIRECTIONAL);
1671
1672 trace_iwlwifi_dev_tx(trans->dev, skb, 1688 trace_iwlwifi_dev_tx(trans->dev, skb,
1673 &txq->tfds[txq->q.write_ptr], 1689 &txq->tfds[txq->q.write_ptr],
1674 sizeof(struct iwl_tfd), 1690 sizeof(struct iwl_tfd),
1675 &dev_cmd->hdr, firstlen, 1691 &dev_cmd->hdr, IWL_HCMD_SCRATCHBUF_SIZE + tb1_len,
1676 skb->data + hdr_len, secondlen); 1692 skb->data + hdr_len, tb2_len);
1677 trace_iwlwifi_dev_tx_data(trans->dev, skb, 1693 trace_iwlwifi_dev_tx_data(trans->dev, skb,
1678 skb->data + hdr_len, secondlen); 1694 skb->data + hdr_len, tb2_len);
1695
1696 if (!ieee80211_has_morefrags(fc)) {
1697 txq->need_update = 1;
1698 } else {
1699 wait_write_ptr = 1;
1700 txq->need_update = 0;
1701 }
1679 1702
1680 /* start timer if queue currently empty */ 1703 /* start timer if queue currently empty */
1681 if (txq->need_update && q->read_ptr == q->write_ptr && 1704 if (txq->need_update && q->read_ptr == q->write_ptr &&