diff options
Diffstat (limited to 'package/mac80211/patches/561-mac80211_tx_status.patch')
-rw-r--r-- | package/mac80211/patches/561-mac80211_tx_status.patch | 96 |
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 0000000000..513dd0a6ec --- /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) + { |