[backfire] mac80211: revert r29210 for now, it breaks on several architectures
[openwrt-10.03/.git] / package / mac80211 / patches / 561-mac80211_tx_status.patch
1 --- a/include/net/mac80211.h
2 +++ b/include/net/mac80211.h
3 @@ -2370,6 +2370,25 @@ static inline int ieee80211_sta_ps_trans
4  void ieee80211_sta_set_tim(struct ieee80211_sta *sta);
5  
6  /**
7 + * ieee80211_tx_status_sta - transmit status callback
8 + *
9 + * Call this function for all transmitted frames after they have been
10 + * transmitted. It is permissible to not call this function for
11 + * multicast frames but this can affect statistics.
12 + *
13 + * This function may not be called in IRQ context. Calls to this function
14 + * for a single hardware must be synchronized against each other. Calls
15 + * to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe()
16 + * may not be mixed for a single hardware.
17 + *
18 + * @hw: the hardware the frame was transmitted by
19 + * @skb: the frame that was transmitted, owned by mac80211 after this call
20 + * @sta: station for which the tx status is provided
21 + */
22 +void ieee80211_tx_status_sta(struct ieee80211_hw *hw, struct sk_buff *skb,
23 +                            struct ieee80211_sta *sta);
24 +
25 +/**
26   * ieee80211_tx_status - transmit status callback
27   *
28   * Call this function for all transmitted frames after they have been
29 @@ -2384,8 +2403,11 @@ void ieee80211_sta_set_tim(struct ieee80
30   * @hw: the hardware the frame was transmitted by
31   * @skb: the frame that was transmitted, owned by mac80211 after this call
32   */
33 -void ieee80211_tx_status(struct ieee80211_hw *hw,
34 -                        struct sk_buff *skb);
35 +static inline void ieee80211_tx_status(struct ieee80211_hw *hw,
36 +                                      struct sk_buff *skb)
37 +{
38 +       ieee80211_tx_status_sta(hw, skb, NULL);
39 +}
40  
41  /**
42   * ieee80211_tx_status_ni - transmit status callback (in process context)
43 --- a/net/mac80211/status.c
44 +++ b/net/mac80211/status.c
45 @@ -202,7 +202,8 @@ static void ieee80211_set_bar_pending(st
46   */
47  #define STA_LOST_PKT_THRESHOLD 50
48  
49 -void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
50 +void ieee80211_tx_status_sta(struct ieee80211_hw *hw, struct sk_buff *skb,
51 +                            struct ieee80211_sta *pubsta)
52  {
53         struct sk_buff *skb2;
54         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
55 @@ -214,7 +215,7 @@ void ieee80211_tx_status(struct ieee8021
56         struct ieee80211_tx_status_rtap_hdr *rthdr;
57         struct ieee80211_sub_if_data *sdata;
58         struct net_device *prev_dev = NULL;
59 -       struct sta_info *sta, *tmp;
60 +       struct sta_info *sta = NULL, *tmp, *tmp2;
61         int retry_count = -1, i;
62         int rates_idx = -1;
63         bool send_to_cooked;
64 @@ -244,11 +245,19 @@ void ieee80211_tx_status(struct ieee8021
65         sband = local->hw.wiphy->bands[info->band];
66         fc = hdr->frame_control;
67  
68 -       for_each_sta_info(local, hdr->addr1, sta, tmp) {
69 -               /* skip wrong virtual interface */
70 -               if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN))
71 -                       continue;
72 +       if (!pubsta) {
73 +               for_each_sta_info(local, hdr->addr1, tmp, tmp2) {
74 +                       /* skip wrong virtual interface */
75 +                       if (memcmp(hdr->addr2, tmp->sdata->vif.addr, ETH_ALEN))
76 +                               continue;
77 +
78 +                       sta = tmp;
79 +               }
80 +       } else {
81 +               sta = container_of(pubsta, struct sta_info, sta);
82 +       }
83  
84 +       if (sta) {
85                 acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
86                 if (!acked && test_sta_flags(sta, WLAN_STA_PS_STA)) {
87                         /*
88 @@ -497,7 +506,7 @@ void ieee80211_tx_status(struct ieee8021
89         rcu_read_unlock();
90         dev_kfree_skb(skb);
91  }
92 -EXPORT_SYMBOL(ieee80211_tx_status);
93 +EXPORT_SYMBOL(ieee80211_tx_status_sta);
94  
95  void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets)
96  {