mac80211: backport fix for an no-ack tx status issue
authorFelix Fietkau <nbd@nbd.name>
Sat, 18 Jan 2020 17:41:08 +0000 (18:41 +0100)
committerPetr Štetiar <ynezz@true.cz>
Fri, 1 May 2020 09:12:31 +0000 (11:12 +0200)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Tested-by: Jérôme Benoit <jerome.benoit@piment-noir.org> [WRT1900AC v1]
[added missing package version bump]
Signed-off-by: Petr Štetiar <ynezz@true.cz>
(cherry picked from commit e0ab33ea496f371a0683b18d5555d651f8df1f5e)

package/kernel/mac80211/Makefile
package/kernel/mac80211/patches/subsys/305-mac80211-fix-tx-status-for-no-ack-cases.patch [new file with mode: 0644]

index cd50bd5..6220b73 100644 (file)
@@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk
 PKG_NAME:=mac80211
 
 PKG_VERSION:=4.19.112-1
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v4.19.112/
 PKG_HASH:=e60a7aec902638c538b150d0d6165d866eb804845b97d7770acd653fd6a6b718
 
diff --git a/package/kernel/mac80211/patches/subsys/305-mac80211-fix-tx-status-for-no-ack-cases.patch b/package/kernel/mac80211/patches/subsys/305-mac80211-fix-tx-status-for-no-ack-cases.patch
new file mode 100644 (file)
index 0000000..3ea78fb
--- /dev/null
@@ -0,0 +1,82 @@
+From: Markus Theil <markus.theil@tu-ilmenau.de>
+Date: Wed, 18 Dec 2019 15:27:36 +0100
+Subject: [PATCH] mac80211: fix tx status for no ack cases
+
+Before this patch, frames which where successfully transmitted without
+requiring acks where accounted as lost frames.
+
+Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
+Link: https://lore.kernel.org/r/20191218142736.15843-1-markus.theil@tu-ilmenau.de
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -881,6 +881,7 @@ static void __ieee80211_tx_status(struct
+       int rates_idx;
+       bool send_to_cooked;
+       bool acked;
++      bool noack_success;
+       struct ieee80211_bar *bar;
+       int shift = 0;
+       int tid = IEEE80211_NUM_TIDS;
+@@ -898,6 +899,8 @@ static void __ieee80211_tx_status(struct
+                       clear_sta_flag(sta, WLAN_STA_SP);
+               acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
++              noack_success = !!(info->flags &
++                                 IEEE80211_TX_STAT_NOACK_TRANSMITTED);
+               /* mesh Peer Service Period support */
+               if (ieee80211_vif_is_mesh(&sta->sdata->vif) &&
+@@ -962,12 +965,12 @@ static void __ieee80211_tx_status(struct
+                       ieee80211_handle_filtered_frame(local, sta, skb);
+                       return;
+               } else {
+-                      if (!acked)
++                      if (!acked && !noack_success)
+                               sta->status_stats.retry_failed++;
+                       sta->status_stats.retry_count += retry_count;
+                       if (ieee80211_is_data_present(fc)) {
+-                              if (!acked)
++                              if (!acked && !noack_success)
+                                       sta->status_stats.msdu_failed[tid]++;
+                               sta->status_stats.msdu_retries[tid] +=
+@@ -994,7 +997,7 @@ static void __ieee80211_tx_status(struct
+                                                      info->status.tx_time, 0);
+               if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
+-                      if (info->flags & IEEE80211_TX_STAT_ACK) {
++                      if (acked) {
+                               if (sta->status_stats.lost_packets)
+                                       sta->status_stats.lost_packets = 0;
+@@ -1002,6 +1005,8 @@ static void __ieee80211_tx_status(struct
+                               if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
+                                       sta->status_stats.last_tdls_pkt_time =
+                                               jiffies;
++                      } else if (noack_success) {
++                              /* nothing to do here, do not account as lost */
+                       } else {
+                               ieee80211_lost_packet(sta, info);
+                       }
+@@ -1127,7 +1132,7 @@ void ieee80211_tx_status_ext(struct ieee
+               sta = container_of(pubsta, struct sta_info, sta);
+-              if (!acked)
++              if (!acked && !noack_success)
+                       sta->status_stats.retry_failed++;
+               sta->status_stats.retry_count += retry_count;
+@@ -1142,6 +1147,8 @@ void ieee80211_tx_status_ext(struct ieee
+                               sta->status_stats.last_tdls_pkt_time = jiffies;
+               } else if (test_sta_flag(sta, WLAN_STA_PS_STA)) {
+                       return;
++              } else if (noack_success) {
++                      /* nothing to do here, do not account as lost */
+               } else {
+                       ieee80211_lost_packet(sta, info);
+               }