1 |
From 99235bc25f2207fb21a7f5808b3e70cf5b6372e5 Mon Sep 17 00:00:00 2001 |
2 |
From: Sara Sharon <sara.sharon@intel.com> |
3 |
Date: Tue, 1 May 2018 14:54:22 +0300 |
4 |
Subject: [PATCH 075/145] iwlwifi: mvm: fix BAR seq ctrl reporting |
5 |
|
6 |
[ Upstream commit 941ab4eb66c10bc5c7234e83a7a858b2806ed151 ] |
7 |
|
8 |
There is a bug in FW where the sequence control may be |
9 |
incorrect, and the driver overrides it with the value |
10 |
of the ieee80211 header. |
11 |
|
12 |
However, in BAR there is no sequence control in the header, |
13 |
which result with arbitrary sequence. |
14 |
|
15 |
This access to an unknown location is bad and it makes the |
16 |
logs very confusing - so fix it. |
17 |
|
18 |
Signed-off-by: Sara Sharon <sara.sharon@intel.com> |
19 |
Signed-off-by: Luca Coelho <luciano.coelho@intel.com> |
20 |
Signed-off-by: Sasha Levin <sashal@kernel.org> |
21 |
--- |
22 |
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 9 +++++---- |
23 |
1 file changed, 5 insertions(+), 4 deletions(-) |
24 |
|
25 |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c |
26 |
index ff193dca2020..2d21f0a1fa00 100644 |
27 |
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c |
28 |
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c |
29 |
@@ -1405,6 +1405,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, |
30 |
while (!skb_queue_empty(&skbs)) { |
31 |
struct sk_buff *skb = __skb_dequeue(&skbs); |
32 |
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
33 |
+ struct ieee80211_hdr *hdr = (void *)skb->data; |
34 |
bool flushed = false; |
35 |
|
36 |
skb_freed++; |
37 |
@@ -1449,11 +1450,11 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, |
38 |
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; |
39 |
info->flags &= ~IEEE80211_TX_CTL_AMPDU; |
40 |
|
41 |
- /* W/A FW bug: seq_ctl is wrong when the status isn't success */ |
42 |
- if (status != TX_STATUS_SUCCESS) { |
43 |
- struct ieee80211_hdr *hdr = (void *)skb->data; |
44 |
+ /* W/A FW bug: seq_ctl is wrong upon failure / BAR frame */ |
45 |
+ if (ieee80211_is_back_req(hdr->frame_control)) |
46 |
+ seq_ctl = 0; |
47 |
+ else if (status != TX_STATUS_SUCCESS) |
48 |
seq_ctl = le16_to_cpu(hdr->seq_ctrl); |
49 |
- } |
50 |
|
51 |
if (unlikely(!seq_ctl)) { |
52 |
struct ieee80211_hdr *hdr = (void *)skb->data; |
53 |
-- |
54 |
2.19.1 |
55 |
|