.. | .. |
---|
20 | 20 | |
---|
21 | 21 | #define COMPUTE_TO (5 * HZ) |
---|
22 | 22 | #define LATEACK_DELAY (10 * HZ) |
---|
23 | | -#define LATEACK_TO 256 |
---|
24 | | -#define MAX_DELAY 300 |
---|
25 | 23 | #define EWMA_LEVEL 96 |
---|
26 | 24 | #define EWMA_DIV 128 |
---|
| 25 | + |
---|
| 26 | +/** |
---|
| 27 | + * ath_dynack_get_max_to - set max timeout according to channel width |
---|
| 28 | + * @ah: ath hw |
---|
| 29 | + * |
---|
| 30 | + */ |
---|
| 31 | +static u32 ath_dynack_get_max_to(struct ath_hw *ah) |
---|
| 32 | +{ |
---|
| 33 | + const struct ath9k_channel *chan = ah->curchan; |
---|
| 34 | + |
---|
| 35 | + if (!chan) |
---|
| 36 | + return 300; |
---|
| 37 | + |
---|
| 38 | + if (IS_CHAN_HT40(chan)) |
---|
| 39 | + return 300; |
---|
| 40 | + if (IS_CHAN_HALF_RATE(chan)) |
---|
| 41 | + return 750; |
---|
| 42 | + if (IS_CHAN_QUARTER_RATE(chan)) |
---|
| 43 | + return 1500; |
---|
| 44 | + return 600; |
---|
| 45 | +} |
---|
27 | 46 | |
---|
28 | 47 | /** |
---|
29 | 48 | * ath_dynack_ewma - EWMA (Exponentially Weighted Moving Average) calculation |
---|
.. | .. |
---|
79 | 98 | } |
---|
80 | 99 | |
---|
81 | 100 | /** |
---|
| 101 | + * ath_dynack_set_timeout - configure timeouts/slottime registers |
---|
| 102 | + * @ah: ath hw |
---|
| 103 | + * @to: timeout value |
---|
| 104 | + * |
---|
| 105 | + */ |
---|
| 106 | +static void ath_dynack_set_timeout(struct ath_hw *ah, int to) |
---|
| 107 | +{ |
---|
| 108 | + struct ath_common *common = ath9k_hw_common(ah); |
---|
| 109 | + int slottime = (to - 3) / 2; |
---|
| 110 | + |
---|
| 111 | + ath_dbg(common, DYNACK, "ACK timeout %u slottime %u\n", |
---|
| 112 | + to, slottime); |
---|
| 113 | + ath9k_hw_setslottime(ah, slottime); |
---|
| 114 | + ath9k_hw_set_ack_timeout(ah, to); |
---|
| 115 | + ath9k_hw_set_cts_timeout(ah, to); |
---|
| 116 | +} |
---|
| 117 | + |
---|
| 118 | +/** |
---|
82 | 119 | * ath_dynack_compute_ackto - compute ACK timeout as the maximum STA timeout |
---|
83 | 120 | * @ah: ath hw |
---|
84 | 121 | * |
---|
.. | .. |
---|
86 | 123 | */ |
---|
87 | 124 | static void ath_dynack_compute_ackto(struct ath_hw *ah) |
---|
88 | 125 | { |
---|
89 | | - struct ath_common *common = ath9k_hw_common(ah); |
---|
90 | 126 | struct ath_dynack *da = &ah->dynack; |
---|
91 | 127 | struct ath_node *an; |
---|
92 | 128 | int to = 0; |
---|
.. | .. |
---|
96 | 132 | to = an->ackto; |
---|
97 | 133 | |
---|
98 | 134 | if (to && da->ackto != to) { |
---|
99 | | - u32 slottime; |
---|
100 | | - |
---|
101 | | - slottime = (to - 3) / 2; |
---|
| 135 | + ath_dynack_set_timeout(ah, to); |
---|
102 | 136 | da->ackto = to; |
---|
103 | | - ath_dbg(common, DYNACK, "ACK timeout %u slottime %u\n", |
---|
104 | | - da->ackto, slottime); |
---|
105 | | - ath9k_hw_setslottime(ah, slottime); |
---|
106 | | - ath9k_hw_set_ack_timeout(ah, da->ackto); |
---|
107 | | - ath9k_hw_set_cts_timeout(ah, da->ackto); |
---|
108 | 137 | } |
---|
109 | 138 | } |
---|
110 | 139 | |
---|
.. | .. |
---|
116 | 145 | */ |
---|
117 | 146 | static void ath_dynack_compute_to(struct ath_hw *ah) |
---|
118 | 147 | { |
---|
119 | | - u32 ackto, ack_ts; |
---|
120 | | - u8 *dst, *src; |
---|
121 | | - struct ieee80211_sta *sta; |
---|
122 | | - struct ath_node *an; |
---|
123 | | - struct ts_info *st_ts; |
---|
124 | 148 | struct ath_dynack *da = &ah->dynack; |
---|
| 149 | + u32 ackto, ack_ts, max_to; |
---|
| 150 | + struct ieee80211_sta *sta; |
---|
| 151 | + struct ts_info *st_ts; |
---|
| 152 | + struct ath_node *an; |
---|
| 153 | + u8 *dst, *src; |
---|
125 | 154 | |
---|
126 | 155 | rcu_read_lock(); |
---|
127 | 156 | |
---|
| 157 | + max_to = ath_dynack_get_max_to(ah); |
---|
128 | 158 | while (da->st_rbf.h_rb != da->st_rbf.t_rb && |
---|
129 | 159 | da->ack_rbf.h_rb != da->ack_rbf.t_rb) { |
---|
130 | 160 | ack_ts = da->ack_rbf.tstamp[da->ack_rbf.h_rb]; |
---|
.. | .. |
---|
140 | 170 | if (ack_ts > st_ts->tstamp + st_ts->dur) { |
---|
141 | 171 | ackto = ack_ts - st_ts->tstamp - st_ts->dur; |
---|
142 | 172 | |
---|
143 | | - if (ackto < MAX_DELAY) { |
---|
| 173 | + if (ackto < max_to) { |
---|
144 | 174 | sta = ieee80211_find_sta_by_ifaddr(ah->hw, dst, |
---|
145 | 175 | src); |
---|
146 | 176 | if (sta) { |
---|
.. | .. |
---|
178 | 208 | struct ath_tx_status *ts, |
---|
179 | 209 | struct ieee80211_sta *sta) |
---|
180 | 210 | { |
---|
181 | | - u8 ridx; |
---|
182 | 211 | struct ieee80211_hdr *hdr; |
---|
183 | 212 | struct ath_dynack *da = &ah->dynack; |
---|
184 | 213 | struct ath_common *common = ath9k_hw_common(ah); |
---|
185 | 214 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
---|
| 215 | + u32 dur = ts->duration; |
---|
| 216 | + u8 ridx; |
---|
186 | 217 | |
---|
187 | 218 | if (!da->enabled || (info->flags & IEEE80211_TX_CTL_NO_ACK)) |
---|
188 | 219 | return; |
---|
.. | .. |
---|
196 | 227 | if (ieee80211_is_assoc_req(hdr->frame_control) || |
---|
197 | 228 | ieee80211_is_assoc_resp(hdr->frame_control) || |
---|
198 | 229 | ieee80211_is_auth(hdr->frame_control)) { |
---|
199 | | - ath_dbg(common, DYNACK, "late ack\n"); |
---|
| 230 | + u32 max_to = ath_dynack_get_max_to(ah); |
---|
200 | 231 | |
---|
201 | | - ath9k_hw_setslottime(ah, (LATEACK_TO - 3) / 2); |
---|
202 | | - ath9k_hw_set_ack_timeout(ah, LATEACK_TO); |
---|
203 | | - ath9k_hw_set_cts_timeout(ah, LATEACK_TO); |
---|
| 232 | + ath_dbg(common, DYNACK, "late ack\n"); |
---|
| 233 | + ath_dynack_set_timeout(ah, max_to); |
---|
204 | 234 | if (sta) { |
---|
205 | 235 | struct ath_node *an; |
---|
206 | 236 | |
---|
.. | .. |
---|
217 | 247 | ridx = ts->ts_rateindex; |
---|
218 | 248 | |
---|
219 | 249 | da->st_rbf.ts[da->st_rbf.t_rb].tstamp = ts->ts_tstamp; |
---|
220 | | - da->st_rbf.ts[da->st_rbf.t_rb].dur = ts->duration; |
---|
221 | 250 | ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_dest, hdr->addr1); |
---|
222 | 251 | ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_src, hdr->addr2); |
---|
223 | 252 | |
---|
224 | 253 | if (!(info->status.rates[ridx].flags & IEEE80211_TX_RC_MCS)) { |
---|
225 | | - u32 phy, sifs; |
---|
226 | 254 | const struct ieee80211_rate *rate; |
---|
227 | 255 | struct ieee80211_tx_rate *rates = info->status.rates; |
---|
| 256 | + u32 phy; |
---|
228 | 257 | |
---|
229 | 258 | rate = &common->sbands[info->band].bitrates[rates[ridx].idx]; |
---|
230 | 259 | if (info->band == NL80211_BAND_2GHZ && |
---|
.. | .. |
---|
233 | 262 | else |
---|
234 | 263 | phy = WLAN_RC_PHY_OFDM; |
---|
235 | 264 | |
---|
236 | | - sifs = ath_dynack_get_sifs(ah, phy); |
---|
237 | | - da->st_rbf.ts[da->st_rbf.t_rb].dur -= sifs; |
---|
| 265 | + dur -= ath_dynack_get_sifs(ah, phy); |
---|
238 | 266 | } |
---|
239 | | - |
---|
240 | | - ath_dbg(common, DYNACK, "{%pM} tx sample %u [dur %u][h %u-t %u]\n", |
---|
241 | | - hdr->addr1, da->st_rbf.ts[da->st_rbf.t_rb].tstamp, |
---|
242 | | - da->st_rbf.ts[da->st_rbf.t_rb].dur, da->st_rbf.h_rb, |
---|
243 | | - (da->st_rbf.t_rb + 1) % ATH_DYN_BUF); |
---|
| 267 | + da->st_rbf.ts[da->st_rbf.t_rb].dur = dur; |
---|
244 | 268 | |
---|
245 | 269 | INCR(da->st_rbf.t_rb, ATH_DYN_BUF); |
---|
246 | 270 | if (da->st_rbf.t_rb == da->st_rbf.h_rb) |
---|
247 | 271 | INCR(da->st_rbf.h_rb, ATH_DYN_BUF); |
---|
| 272 | + |
---|
| 273 | + ath_dbg(common, DYNACK, "{%pM} tx sample %u [dur %u][h %u-t %u]\n", |
---|
| 274 | + hdr->addr1, ts->ts_tstamp, dur, da->st_rbf.h_rb, |
---|
| 275 | + da->st_rbf.t_rb); |
---|
248 | 276 | |
---|
249 | 277 | ath_dynack_compute_to(ah); |
---|
250 | 278 | |
---|
.. | .. |
---|
272 | 300 | spin_lock_bh(&da->qlock); |
---|
273 | 301 | da->ack_rbf.tstamp[da->ack_rbf.t_rb] = ts; |
---|
274 | 302 | |
---|
275 | | - ath_dbg(common, DYNACK, "rx sample %u [h %u-t %u]\n", |
---|
276 | | - da->ack_rbf.tstamp[da->ack_rbf.t_rb], |
---|
277 | | - da->ack_rbf.h_rb, (da->ack_rbf.t_rb + 1) % ATH_DYN_BUF); |
---|
278 | | - |
---|
279 | 303 | INCR(da->ack_rbf.t_rb, ATH_DYN_BUF); |
---|
280 | 304 | if (da->ack_rbf.t_rb == da->ack_rbf.h_rb) |
---|
281 | 305 | INCR(da->ack_rbf.h_rb, ATH_DYN_BUF); |
---|
| 306 | + |
---|
| 307 | + ath_dbg(common, DYNACK, "rx sample %u [h %u-t %u]\n", |
---|
| 308 | + ts, da->ack_rbf.h_rb, da->ack_rbf.t_rb); |
---|
282 | 309 | |
---|
283 | 310 | ath_dynack_compute_to(ah); |
---|
284 | 311 | |
---|
.. | .. |
---|
294 | 321 | */ |
---|
295 | 322 | void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an) |
---|
296 | 323 | { |
---|
297 | | - /* ackto = slottime + sifs + air delay */ |
---|
298 | | - u32 ackto = 9 + 16 + 64; |
---|
299 | 324 | struct ath_dynack *da = &ah->dynack; |
---|
300 | 325 | |
---|
301 | | - an->ackto = ackto; |
---|
| 326 | + an->ackto = da->ackto; |
---|
302 | 327 | |
---|
303 | 328 | spin_lock_bh(&da->qlock); |
---|
304 | 329 | list_add_tail(&an->list, &da->nodes); |
---|
.. | .. |
---|
329 | 354 | */ |
---|
330 | 355 | void ath_dynack_reset(struct ath_hw *ah) |
---|
331 | 356 | { |
---|
332 | | - /* ackto = slottime + sifs + air delay */ |
---|
333 | | - u32 ackto = 9 + 16 + 64; |
---|
334 | 357 | struct ath_dynack *da = &ah->dynack; |
---|
| 358 | + struct ath_node *an; |
---|
335 | 359 | |
---|
336 | | - da->lto = jiffies; |
---|
337 | | - da->ackto = ackto; |
---|
| 360 | + spin_lock_bh(&da->qlock); |
---|
| 361 | + |
---|
| 362 | + da->lto = jiffies + COMPUTE_TO; |
---|
338 | 363 | |
---|
339 | 364 | da->st_rbf.t_rb = 0; |
---|
340 | 365 | da->st_rbf.h_rb = 0; |
---|
341 | 366 | da->ack_rbf.t_rb = 0; |
---|
342 | 367 | da->ack_rbf.h_rb = 0; |
---|
343 | 368 | |
---|
| 369 | + da->ackto = ath_dynack_get_max_to(ah); |
---|
| 370 | + list_for_each_entry(an, &da->nodes, list) |
---|
| 371 | + an->ackto = da->ackto; |
---|
| 372 | + |
---|
344 | 373 | /* init acktimeout */ |
---|
345 | | - ath9k_hw_setslottime(ah, (ackto - 3) / 2); |
---|
346 | | - ath9k_hw_set_ack_timeout(ah, ackto); |
---|
347 | | - ath9k_hw_set_cts_timeout(ah, ackto); |
---|
| 374 | + ath_dynack_set_timeout(ah, da->ackto); |
---|
| 375 | + |
---|
| 376 | + spin_unlock_bh(&da->qlock); |
---|
348 | 377 | } |
---|
349 | 378 | EXPORT_SYMBOL(ath_dynack_reset); |
---|
350 | 379 | |
---|
.. | .. |
---|
361 | 390 | |
---|
362 | 391 | spin_lock_init(&da->qlock); |
---|
363 | 392 | INIT_LIST_HEAD(&da->nodes); |
---|
| 393 | + /* ackto = slottime + sifs + air delay */ |
---|
| 394 | + da->ackto = 9 + 16 + 64; |
---|
364 | 395 | |
---|
365 | 396 | ah->hw->wiphy->features |= NL80211_FEATURE_ACKTO_ESTIMATION; |
---|
366 | 397 | } |
---|