提交 0ccb7a34 编写于 作者: J Janusz Dziedzic 提交者: Kalle Valo

ath10k: handle attention flags correctly when using A-MSDU

In case of A-MSDU RX we should check attention flags
correctly to be sure we report correct FCS status for
A-MSDU subframes. Without a patch we could report A-MSDU
subframes with wrong FCS as a correct to the stack, next
get a lot of DUP ACK TCP packets. Finally TP drop is seen
and this drop depends on FCS errors ratio for A-MSDU frame.

Example test case when TP drop is seen:
- ath10k configured as an AP
- used ath10k station
- forced A-MSDU (7 frames) on STA
- other traffic on channel (often FCS errors)
- monitor iface added on AP
- TCP STA -> AP traffic (iperf)

a) Iperf logs for case without the patch:

echo "1 64" > htt_max_amsdu_ampdu // disable A-MSDU
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0- 5.0 sec  56.6 MBytes  95.0 Mbits/sec
[  3]  5.0-10.0 sec  60.4 MBytes   101 Mbits/sec
[  3] 10.0-15.0 sec  60.2 MBytes   101 Mbits/sec
[  3] 15.0-20.0 sec  60.2 MBytes   101 Mbits/sec
[  3] 20.0-25.0 sec  63.8 MBytes   107 Mbits/sec
[  3] 25.0-30.0 sec  64.9 MBytes   109 Mbits/sec

echo "7 64" > htt_max_amsdu_ampdu  // set 7 A-MSDU subframes
[  3] 30.0-35.0 sec  40.0 MBytes  67.1 Mbits/sec
[  3] 35.0-40.0 sec  35.9 MBytes  60.2 Mbits/sec
[  3] 40.0-45.0 sec  36.9 MBytes  61.9 Mbits/sec
[  3] 45.0-50.0 sec  37.9 MBytes  63.5 Mbits/sec
[  3] 50.0-55.0 sec  34.5 MBytes  57.9 Mbits/sec
[  3] 55.0-60.0 sec  25.4 MBytes  42.6 Mbits/sec
[  3] 60.0-65.0 sec  48.2 MBytes  81.0 Mbits/sec
[  3] 65.0-70.0 sec  28.8 MBytes  48.2 Mbits/sec
[  3] 70.0-75.0 sec  29.2 MBytes  49.1 Mbits/sec
[  3] 75.0-80.0 sec  22.9 MBytes  38.4 Mbits/sec
[  3] 80.0-85.0 sec  26.4 MBytes  44.2 Mbits/sec
[  3] 85.0-90.0 sec  31.5 MBytes  52.8 Mbits/sec

b) Iperf logs for case with patch:

echo "1 64" > htt_max_amsdu_ampdu // disable A-MSDU
[  3] local 192.168.12.2 port 57512 connected with 192.168.12.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0- 5.0 sec  60.8 MBytes   102 Mbits/sec
[  3]  5.0-10.0 sec  62.2 MBytes   104 Mbits/sec
[  3] 10.0-15.0 sec  60.9 MBytes   102 Mbits/sec

echo "7 64" > htt_max_amsdu_ampdu  // set 7 A-MSDU subframes
[  3] 15.0-20.0 sec  68.1 MBytes   114 Mbits/sec
[  3] 20.0-25.0 sec  80.5 MBytes   135 Mbits/sec
[  3] 25.0-30.0 sec  83.0 MBytes   139 Mbits/sec
[  3] 30.0-35.0 sec  79.1 MBytes   133 Mbits/sec
[  3] 35.0-40.0 sec  77.1 MBytes   129 Mbits/sec
[  3] 40.0-45.0 sec  77.4 MBytes   130 Mbits/sec
Reported-by: NDenton Gentry <denton.gentry@gmail.com>
Signed-off-by: NJanusz Dziedzic <janusz.dziedzic@tieto.com>
Signed-off-by: NKalle Valo <kvalo@qca.qualcomm.com>
上级 cf850d1d
...@@ -308,7 +308,8 @@ static void ath10k_htt_rx_free_msdu_chain(struct sk_buff *skb) ...@@ -308,7 +308,8 @@ static void ath10k_htt_rx_free_msdu_chain(struct sk_buff *skb)
static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
u8 **fw_desc, int *fw_desc_len, u8 **fw_desc, int *fw_desc_len,
struct sk_buff **head_msdu, struct sk_buff **head_msdu,
struct sk_buff **tail_msdu) struct sk_buff **tail_msdu,
u32 *attention)
{ {
int msdu_len, msdu_chaining = 0; int msdu_len, msdu_chaining = 0;
struct sk_buff *msdu; struct sk_buff *msdu;
...@@ -358,6 +359,11 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, ...@@ -358,6 +359,11 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
break; break;
} }
*attention |= __le32_to_cpu(rx_desc->attention.flags) &
(RX_ATTENTION_FLAGS_TKIP_MIC_ERR |
RX_ATTENTION_FLAGS_DECRYPT_ERR |
RX_ATTENTION_FLAGS_FCS_ERR |
RX_ATTENTION_FLAGS_MGMT_TYPE);
/* /*
* Copy the FW rx descriptor for this MSDU from the rx * Copy the FW rx descriptor for this MSDU from the rx
* indication message into the MSDU's netbuf. HL uses the * indication message into the MSDU's netbuf. HL uses the
...@@ -1216,13 +1222,15 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, ...@@ -1216,13 +1222,15 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) { for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) {
struct sk_buff *msdu_head, *msdu_tail; struct sk_buff *msdu_head, *msdu_tail;
attention = 0;
msdu_head = NULL; msdu_head = NULL;
msdu_tail = NULL; msdu_tail = NULL;
ret = ath10k_htt_rx_amsdu_pop(htt, ret = ath10k_htt_rx_amsdu_pop(htt,
&fw_desc, &fw_desc,
&fw_desc_len, &fw_desc_len,
&msdu_head, &msdu_head,
&msdu_tail); &msdu_tail,
&attention);
if (ret < 0) { if (ret < 0) {
ath10k_warn("failed to pop amsdu from htt rx ring %d\n", ath10k_warn("failed to pop amsdu from htt rx ring %d\n",
...@@ -1234,7 +1242,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, ...@@ -1234,7 +1242,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
rxd = container_of((void *)msdu_head->data, rxd = container_of((void *)msdu_head->data,
struct htt_rx_desc, struct htt_rx_desc,
msdu_payload); msdu_payload);
attention = __le32_to_cpu(rxd->attention.flags);
if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head, if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head,
status, status,
...@@ -1287,6 +1294,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, ...@@ -1287,6 +1294,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
u8 *fw_desc; u8 *fw_desc;
int fw_desc_len, hdrlen, paramlen; int fw_desc_len, hdrlen, paramlen;
int trim; int trim;
u32 attention = 0;
fw_desc_len = __le16_to_cpu(frag->fw_rx_desc_bytes); fw_desc_len = __le16_to_cpu(frag->fw_rx_desc_bytes);
fw_desc = (u8 *)frag->fw_msdu_rx_desc; fw_desc = (u8 *)frag->fw_msdu_rx_desc;
...@@ -1296,7 +1304,8 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, ...@@ -1296,7 +1304,8 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
spin_lock_bh(&htt->rx_ring.lock); spin_lock_bh(&htt->rx_ring.lock);
ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len, ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len,
&msdu_head, &msdu_tail); &msdu_head, &msdu_tail,
&attention);
spin_unlock_bh(&htt->rx_ring.lock); spin_unlock_bh(&htt->rx_ring.lock);
ath10k_dbg(ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n"); ath10k_dbg(ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n");
...@@ -1313,10 +1322,8 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, ...@@ -1313,10 +1322,8 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
hdr = (struct ieee80211_hdr *)msdu_head->data; hdr = (struct ieee80211_hdr *)msdu_head->data;
rxd = (void *)msdu_head->data - sizeof(*rxd); rxd = (void *)msdu_head->data - sizeof(*rxd);
tkip_mic_err = !!(__le32_to_cpu(rxd->attention.flags) & tkip_mic_err = !!(attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR);
RX_ATTENTION_FLAGS_TKIP_MIC_ERR); decrypt_err = !!(attention & RX_ATTENTION_FLAGS_DECRYPT_ERR);
decrypt_err = !!(__le32_to_cpu(rxd->attention.flags) &
RX_ATTENTION_FLAGS_DECRYPT_ERR);
fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), fmt = MS(__le32_to_cpu(rxd->msdu_start.info1),
RX_MSDU_START_INFO1_DECAP_FORMAT); RX_MSDU_START_INFO1_DECAP_FORMAT);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册