iw: update to 3.17
[openwrt/staging/yousong.git] / package / kernel / mac80211 / patches / 318-mac80211-add-ieee80211_tx_status_noskb.patch
1 From: Felix Fietkau <nbd@openwrt.org>
2 Date: Sat, 15 Nov 2014 23:50:27 +0100
3 Subject: [PATCH] mac80211: add ieee80211_tx_status_noskb
4
5 This can be used by drivers that cannot reliably map tx status
6 information onto specific skbs.
7
8 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
9 ---
10
11 --- a/include/net/mac80211.h
12 +++ b/include/net/mac80211.h
13 @@ -3517,6 +3517,28 @@ void ieee80211_tx_status(struct ieee8021
14 struct sk_buff *skb);
15
16 /**
17 + * ieee80211_tx_status_noskb - transmit status callback without skb
18 + *
19 + * This function can be used as a replacement for ieee80211_tx_status
20 + * in drivers that cannot reliably map tx status information back to
21 + * specific skbs.
22 + *
23 + * This function may not be called in IRQ context. Calls to this function
24 + * for a single hardware must be synchronized against each other. Calls
25 + * to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe()
26 + * may not be mixed for a single hardware. Must not run concurrently with
27 + * ieee80211_rx() or ieee80211_rx_ni().
28 + *
29 + * @hw: the hardware the frame was transmitted by
30 + * @sta: the receiver station to which this packet is sent
31 + * (NULL for multicast packets)
32 + * @info: tx status information
33 + */
34 +void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
35 + struct ieee80211_sta *sta,
36 + struct ieee80211_tx_info *info);
37 +
38 +/**
39 * ieee80211_tx_status_ni - transmit status callback (in process context)
40 *
41 * Like ieee80211_tx_status() but can be called in process context.
42 --- a/net/mac80211/rate.h
43 +++ b/net/mac80211/rate.h
44 @@ -49,6 +49,23 @@ static inline void rate_control_tx_statu
45 }
46
47
48 +static inline void
49 +rate_control_tx_status_noskb(struct ieee80211_local *local,
50 + struct ieee80211_supported_band *sband,
51 + struct sta_info *sta,
52 + struct ieee80211_tx_info *info)
53 +{
54 + struct rate_control_ref *ref = local->rate_ctrl;
55 + struct ieee80211_sta *ista = &sta->sta;
56 + void *priv_sta = sta->rate_ctrl_priv;
57 +
58 + if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
59 + return;
60 +
61 + ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
62 +}
63 +
64 +
65 static inline void rate_control_rate_init(struct sta_info *sta)
66 {
67 struct ieee80211_local *local = sta->sdata->local;
68 --- a/net/mac80211/status.c
69 +++ b/net/mac80211/status.c
70 @@ -541,10 +541,9 @@ static void ieee80211_tx_latency_end_msr
71 #define STA_LOST_TDLS_PKT_THRESHOLD 10
72 #define STA_LOST_TDLS_PKT_TIME (10*HZ) /* 10secs since last ACK */
73
74 -static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb)
75 +static void ieee80211_lost_packet(struct sta_info *sta,
76 + struct ieee80211_tx_info *info)
77 {
78 - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
79 -
80 /* This packet was aggregated but doesn't carry status info */
81 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
82 !(info->flags & IEEE80211_TX_STAT_AMPDU))
83 @@ -571,24 +570,13 @@ static void ieee80211_lost_packet(struct
84 sta->lost_packets = 0;
85 }
86
87 -void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
88 +static int ieee80211_tx_get_rates(struct ieee80211_hw *hw,
89 + struct ieee80211_tx_info *info,
90 + int *retry_count)
91 {
92 - struct sk_buff *skb2;
93 - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
94 - struct ieee80211_local *local = hw_to_local(hw);
95 - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
96 - __le16 fc;
97 - struct ieee80211_supported_band *sband;
98 - struct ieee80211_sub_if_data *sdata;
99 - struct net_device *prev_dev = NULL;
100 - struct sta_info *sta, *tmp;
101 - int retry_count = -1, i;
102 int rates_idx = -1;
103 - bool send_to_cooked;
104 - bool acked;
105 - struct ieee80211_bar *bar;
106 - int rtap_len;
107 - int shift = 0;
108 + int count = -1;
109 + int i;
110
111 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
112 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
113 @@ -606,12 +594,94 @@ void ieee80211_tx_status(struct ieee8021
114 break;
115 }
116
117 - retry_count += info->status.rates[i].count;
118 + count += info->status.rates[i].count;
119 }
120 rates_idx = i - 1;
121
122 - if (retry_count < 0)
123 - retry_count = 0;
124 + if (count < 0)
125 + count = 0;
126 +
127 + *retry_count = count;
128 + return rates_idx;
129 +}
130 +
131 +void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
132 + struct ieee80211_sta *pubsta,
133 + struct ieee80211_tx_info *info)
134 +{
135 + struct ieee80211_local *local = hw_to_local(hw);
136 + struct ieee80211_supported_band *sband;
137 + int retry_count;
138 + int rates_idx;
139 + bool acked;
140 +
141 + rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
142 +
143 + sband = hw->wiphy->bands[info->band];
144 +
145 + acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
146 + if (pubsta) {
147 + struct sta_info *sta;
148 +
149 + sta = container_of(pubsta, struct sta_info, sta);
150 +
151 + if (info->flags & IEEE80211_TX_STATUS_EOSP)
152 + clear_sta_flag(sta, WLAN_STA_SP);
153 +
154 + if (!acked)
155 + sta->tx_retry_failed++;
156 + sta->tx_retry_count += retry_count;
157 +
158 + if (acked) {
159 + sta->last_rx = jiffies;
160 +
161 + if (sta->lost_packets)
162 + sta->lost_packets = 0;
163 +
164 + /* Track when last TDLS packet was ACKed */
165 + if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
166 + sta->last_tdls_pkt_time = jiffies;
167 + } else {
168 + ieee80211_lost_packet(sta, info);
169 + }
170 +
171 + rate_control_tx_status_noskb(local, sband, sta, info);
172 + }
173 +
174 + if (acked) {
175 + local->dot11TransmittedFrameCount++;
176 + if (!pubsta)
177 + local->dot11MulticastTransmittedFrameCount++;
178 + if (retry_count > 0)
179 + local->dot11RetryCount++;
180 + if (retry_count > 1)
181 + local->dot11MultipleRetryCount++;
182 + } else {
183 + local->dot11FailedCount++;
184 + }
185 +}
186 +EXPORT_SYMBOL(ieee80211_tx_status_noskb);
187 +
188 +void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
189 +{
190 + struct sk_buff *skb2;
191 + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
192 + struct ieee80211_local *local = hw_to_local(hw);
193 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
194 + __le16 fc;
195 + struct ieee80211_supported_band *sband;
196 + struct ieee80211_sub_if_data *sdata;
197 + struct net_device *prev_dev = NULL;
198 + struct sta_info *sta, *tmp;
199 + int retry_count;
200 + int rates_idx;
201 + bool send_to_cooked;
202 + bool acked;
203 + struct ieee80211_bar *bar;
204 + int rtap_len;
205 + int shift = 0;
206 +
207 + rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
208
209 rcu_read_lock();
210
211 @@ -716,7 +786,7 @@ void ieee80211_tx_status(struct ieee8021
212 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
213 sta->last_tdls_pkt_time = jiffies;
214 } else {
215 - ieee80211_lost_packet(sta, skb);
216 + ieee80211_lost_packet(sta, info);
217 }
218 }
219