summaryrefslogtreecommitdiffstats
path: root/package/mac80211/patches/561-mac80211_tx_status.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/mac80211/patches/561-mac80211_tx_status.patch')
-rw-r--r--package/mac80211/patches/561-mac80211_tx_status.patch96
1 files changed, 96 insertions, 0 deletions
diff --git a/package/mac80211/patches/561-mac80211_tx_status.patch b/package/mac80211/patches/561-mac80211_tx_status.patch
new file mode 100644
index 000000000..513dd0a6e
--- /dev/null
+++ b/package/mac80211/patches/561-mac80211_tx_status.patch
@@ -0,0 +1,96 @@
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -2370,6 +2370,25 @@ static inline int ieee80211_sta_ps_trans
+ void ieee80211_sta_set_tim(struct ieee80211_sta *sta);
+
+ /**
++ * ieee80211_tx_status_sta - transmit status callback
++ *
++ * Call this function for all transmitted frames after they have been
++ * transmitted. It is permissible to not call this function for
++ * multicast frames but this can affect statistics.
++ *
++ * This function may not be called in IRQ context. Calls to this function
++ * for a single hardware must be synchronized against each other. Calls
++ * to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe()
++ * may not be mixed for a single hardware.
++ *
++ * @hw: the hardware the frame was transmitted by
++ * @skb: the frame that was transmitted, owned by mac80211 after this call
++ * @sta: station for which the tx status is provided
++ */
++void ieee80211_tx_status_sta(struct ieee80211_hw *hw, struct sk_buff *skb,
++ struct ieee80211_sta *sta);
++
++/**
+ * ieee80211_tx_status - transmit status callback
+ *
+ * Call this function for all transmitted frames after they have been
+@@ -2384,8 +2403,11 @@ void ieee80211_sta_set_tim(struct ieee80
+ * @hw: the hardware the frame was transmitted by
+ * @skb: the frame that was transmitted, owned by mac80211 after this call
+ */
+-void ieee80211_tx_status(struct ieee80211_hw *hw,
+- struct sk_buff *skb);
++static inline void ieee80211_tx_status(struct ieee80211_hw *hw,
++ struct sk_buff *skb)
++{
++ ieee80211_tx_status_sta(hw, skb, NULL);
++}
+
+ /**
+ * ieee80211_tx_status_ni - transmit status callback (in process context)
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -202,7 +202,8 @@ static void ieee80211_set_bar_pending(st
+ */
+ #define STA_LOST_PKT_THRESHOLD 50
+
+-void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
++void ieee80211_tx_status_sta(struct ieee80211_hw *hw, struct sk_buff *skb,
++ struct ieee80211_sta *pubsta)
+ {
+ struct sk_buff *skb2;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+@@ -214,7 +215,7 @@ void ieee80211_tx_status(struct ieee8021
+ struct ieee80211_tx_status_rtap_hdr *rthdr;
+ struct ieee80211_sub_if_data *sdata;
+ struct net_device *prev_dev = NULL;
+- struct sta_info *sta, *tmp;
++ struct sta_info *sta = NULL, *tmp, *tmp2;
+ int retry_count = -1, i;
+ int rates_idx = -1;
+ bool send_to_cooked;
+@@ -244,11 +245,19 @@ void ieee80211_tx_status(struct ieee8021
+ sband = local->hw.wiphy->bands[info->band];
+ fc = hdr->frame_control;
+
+- for_each_sta_info(local, hdr->addr1, sta, tmp) {
+- /* skip wrong virtual interface */
+- if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN))
+- continue;
++ if (!pubsta) {
++ for_each_sta_info(local, hdr->addr1, tmp, tmp2) {
++ /* skip wrong virtual interface */
++ if (memcmp(hdr->addr2, tmp->sdata->vif.addr, ETH_ALEN))
++ continue;
++
++ sta = tmp;
++ }
++ } else {
++ sta = container_of(pubsta, struct sta_info, sta);
++ }
+
++ if (sta) {
+ acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
+ if (!acked && test_sta_flags(sta, WLAN_STA_PS_STA)) {
+ /*
+@@ -497,7 +506,7 @@ void ieee80211_tx_status(struct ieee8021
+ rcu_read_unlock();
+ dev_kfree_skb(skb);
+ }
+-EXPORT_SYMBOL(ieee80211_tx_status);
++EXPORT_SYMBOL(ieee80211_tx_status_sta);
+
+ void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets)
+ {