diff options
author | David S. Miller <davem@davemloft.net> | 2019-09-14 09:08:18 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-09-14 09:08:18 -0400 |
commit | a3d3c74da49c65fc63a937fa559186b0e16adca3 (patch) | |
tree | 946a98b1350387ee8c6ee8d6572864c838b20191 /drivers/net/wireless/ath/ath9k/dynack.c | |
parent | 1ba569fc2250b7717fcf3b943efe043c98c6a919 (diff) | |
parent | f9e568754562e0f506e12aa899c378b4155080e9 (diff) |
Merge tag 'wireless-drivers-next-for-davem-2019-09-14' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says:
====================
wireless-drivers-next patches for 5.4
Last set of patches for 5.4. wil6210 and rtw88 being most active this
time, but ath9k also having a new module to load devices without
EEPROM.
Major changes:
wil6210
* add support for Enhanced Directional Multi-Gigabit (EDMG) channels 9-11
* add debugfs file to show PCM ring content
* report boottime_ns in scan results
ath9k
* add a separate loader for AR92XX (and older) pci(e) without eeprom
brcmfmac
* use the same wiphy after PCIe reset to not confuse the user space
rtw88
* enable interrupt migration
* enable AMSDU in AMPDU aggregation
* report RX power for each antenna
* enable to DPK and IQK calibration methods to improve performance
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/dynack.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/dynack.c | 101 |
1 files changed, 67 insertions, 34 deletions
diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c index f112fa5b2eac..fbeb4a739d32 100644 --- a/drivers/net/wireless/ath/ath9k/dynack.c +++ b/drivers/net/wireless/ath/ath9k/dynack.c | |||
@@ -20,12 +20,31 @@ | |||
20 | 20 | ||
21 | #define COMPUTE_TO (5 * HZ) | 21 | #define COMPUTE_TO (5 * HZ) |
22 | #define LATEACK_DELAY (10 * HZ) | 22 | #define LATEACK_DELAY (10 * HZ) |
23 | #define LATEACK_TO 256 | ||
24 | #define MAX_DELAY 300 | ||
25 | #define EWMA_LEVEL 96 | 23 | #define EWMA_LEVEL 96 |
26 | #define EWMA_DIV 128 | 24 | #define EWMA_DIV 128 |
27 | 25 | ||
28 | /** | 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 | } | ||
46 | |||
47 | /** | ||
29 | * ath_dynack_ewma - EWMA (Exponentially Weighted Moving Average) calculation | 48 | * ath_dynack_ewma - EWMA (Exponentially Weighted Moving Average) calculation |
30 | * | 49 | * |
31 | */ | 50 | */ |
@@ -79,6 +98,24 @@ static inline bool ath_dynack_bssidmask(struct ath_hw *ah, const u8 *mac) | |||
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 | * ath_dynack_compute_ackto - compute ACK timeout as the maximum STA timeout | 119 | * ath_dynack_compute_ackto - compute ACK timeout as the maximum STA timeout |
83 | * @ah: ath hw | 120 | * @ah: ath hw |
84 | * | 121 | * |
@@ -86,7 +123,6 @@ static inline bool ath_dynack_bssidmask(struct ath_hw *ah, const u8 *mac) | |||
86 | */ | 123 | */ |
87 | static void ath_dynack_compute_ackto(struct ath_hw *ah) | 124 | static void ath_dynack_compute_ackto(struct ath_hw *ah) |
88 | { | 125 | { |
89 | struct ath_common *common = ath9k_hw_common(ah); | ||
90 | struct ath_dynack *da = &ah->dynack; | 126 | struct ath_dynack *da = &ah->dynack; |
91 | struct ath_node *an; | 127 | struct ath_node *an; |
92 | int to = 0; | 128 | int to = 0; |
@@ -96,15 +132,8 @@ static void ath_dynack_compute_ackto(struct ath_hw *ah) | |||
96 | to = an->ackto; | 132 | to = an->ackto; |
97 | 133 | ||
98 | if (to && da->ackto != to) { | 134 | if (to && da->ackto != to) { |
99 | u32 slottime; | 135 | ath_dynack_set_timeout(ah, to); |
100 | |||
101 | slottime = (to - 3) / 2; | ||
102 | da->ackto = to; | 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,15 +145,16 @@ static void ath_dynack_compute_ackto(struct ath_hw *ah) | |||
116 | */ | 145 | */ |
117 | static void ath_dynack_compute_to(struct ath_hw *ah) | 146 | static void ath_dynack_compute_to(struct ath_hw *ah) |
118 | { | 147 | { |
119 | u32 ackto, ack_ts; | 148 | struct ath_dynack *da = &ah->dynack; |
120 | u8 *dst, *src; | 149 | u32 ackto, ack_ts, max_to; |
121 | struct ieee80211_sta *sta; | 150 | struct ieee80211_sta *sta; |
122 | struct ath_node *an; | ||
123 | struct ts_info *st_ts; | 151 | struct ts_info *st_ts; |
124 | struct ath_dynack *da = &ah->dynack; | 152 | struct ath_node *an; |
153 | u8 *dst, *src; | ||
125 | 154 | ||
126 | rcu_read_lock(); | 155 | rcu_read_lock(); |
127 | 156 | ||
157 | max_to = ath_dynack_get_max_to(ah); | ||
128 | while (da->st_rbf.h_rb != da->st_rbf.t_rb && | 158 | while (da->st_rbf.h_rb != da->st_rbf.t_rb && |
129 | da->ack_rbf.h_rb != da->ack_rbf.t_rb) { | 159 | da->ack_rbf.h_rb != da->ack_rbf.t_rb) { |
130 | ack_ts = da->ack_rbf.tstamp[da->ack_rbf.h_rb]; | 160 | ack_ts = da->ack_rbf.tstamp[da->ack_rbf.h_rb]; |
@@ -140,7 +170,7 @@ static void ath_dynack_compute_to(struct ath_hw *ah) | |||
140 | if (ack_ts > st_ts->tstamp + st_ts->dur) { | 170 | if (ack_ts > st_ts->tstamp + st_ts->dur) { |
141 | ackto = ack_ts - st_ts->tstamp - st_ts->dur; | 171 | ackto = ack_ts - st_ts->tstamp - st_ts->dur; |
142 | 172 | ||
143 | if (ackto < MAX_DELAY) { | 173 | if (ackto < max_to) { |
144 | sta = ieee80211_find_sta_by_ifaddr(ah->hw, dst, | 174 | sta = ieee80211_find_sta_by_ifaddr(ah->hw, dst, |
145 | src); | 175 | src); |
146 | if (sta) { | 176 | if (sta) { |
@@ -197,11 +227,10 @@ void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb, | |||
197 | if (ieee80211_is_assoc_req(hdr->frame_control) || | 227 | if (ieee80211_is_assoc_req(hdr->frame_control) || |
198 | ieee80211_is_assoc_resp(hdr->frame_control) || | 228 | ieee80211_is_assoc_resp(hdr->frame_control) || |
199 | ieee80211_is_auth(hdr->frame_control)) { | 229 | ieee80211_is_auth(hdr->frame_control)) { |
200 | ath_dbg(common, DYNACK, "late ack\n"); | 230 | u32 max_to = ath_dynack_get_max_to(ah); |
201 | 231 | ||
202 | ath9k_hw_setslottime(ah, (LATEACK_TO - 3) / 2); | 232 | ath_dbg(common, DYNACK, "late ack\n"); |
203 | ath9k_hw_set_ack_timeout(ah, LATEACK_TO); | 233 | ath_dynack_set_timeout(ah, max_to); |
204 | ath9k_hw_set_cts_timeout(ah, LATEACK_TO); | ||
205 | if (sta) { | 234 | if (sta) { |
206 | struct ath_node *an; | 235 | struct ath_node *an; |
207 | 236 | ||
@@ -292,15 +321,13 @@ EXPORT_SYMBOL(ath_dynack_sample_ack_ts); | |||
292 | */ | 321 | */ |
293 | void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an) | 322 | void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an) |
294 | { | 323 | { |
295 | /* ackto = slottime + sifs + air delay */ | ||
296 | u32 ackto = 9 + 16 + 64; | ||
297 | struct ath_dynack *da = &ah->dynack; | 324 | struct ath_dynack *da = &ah->dynack; |
298 | 325 | ||
299 | an->ackto = ackto; | 326 | an->ackto = da->ackto; |
300 | 327 | ||
301 | spin_lock(&da->qlock); | 328 | spin_lock_bh(&da->qlock); |
302 | list_add_tail(&an->list, &da->nodes); | 329 | list_add_tail(&an->list, &da->nodes); |
303 | spin_unlock(&da->qlock); | 330 | spin_unlock_bh(&da->qlock); |
304 | } | 331 | } |
305 | EXPORT_SYMBOL(ath_dynack_node_init); | 332 | EXPORT_SYMBOL(ath_dynack_node_init); |
306 | 333 | ||
@@ -314,9 +341,9 @@ void ath_dynack_node_deinit(struct ath_hw *ah, struct ath_node *an) | |||
314 | { | 341 | { |
315 | struct ath_dynack *da = &ah->dynack; | 342 | struct ath_dynack *da = &ah->dynack; |
316 | 343 | ||
317 | spin_lock(&da->qlock); | 344 | spin_lock_bh(&da->qlock); |
318 | list_del(&an->list); | 345 | list_del(&an->list); |
319 | spin_unlock(&da->qlock); | 346 | spin_unlock_bh(&da->qlock); |
320 | } | 347 | } |
321 | EXPORT_SYMBOL(ath_dynack_node_deinit); | 348 | EXPORT_SYMBOL(ath_dynack_node_deinit); |
322 | 349 | ||
@@ -327,22 +354,26 @@ EXPORT_SYMBOL(ath_dynack_node_deinit); | |||
327 | */ | 354 | */ |
328 | void ath_dynack_reset(struct ath_hw *ah) | 355 | void ath_dynack_reset(struct ath_hw *ah) |
329 | { | 356 | { |
330 | /* ackto = slottime + sifs + air delay */ | ||
331 | u32 ackto = 9 + 16 + 64; | ||
332 | struct ath_dynack *da = &ah->dynack; | 357 | struct ath_dynack *da = &ah->dynack; |
358 | struct ath_node *an; | ||
359 | |||
360 | spin_lock_bh(&da->qlock); | ||
333 | 361 | ||
334 | da->lto = jiffies; | 362 | da->lto = jiffies + COMPUTE_TO; |
335 | da->ackto = ackto; | ||
336 | 363 | ||
337 | da->st_rbf.t_rb = 0; | 364 | da->st_rbf.t_rb = 0; |
338 | da->st_rbf.h_rb = 0; | 365 | da->st_rbf.h_rb = 0; |
339 | da->ack_rbf.t_rb = 0; | 366 | da->ack_rbf.t_rb = 0; |
340 | da->ack_rbf.h_rb = 0; | 367 | da->ack_rbf.h_rb = 0; |
341 | 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 | |||
342 | /* init acktimeout */ | 373 | /* init acktimeout */ |
343 | ath9k_hw_setslottime(ah, (ackto - 3) / 2); | 374 | ath_dynack_set_timeout(ah, da->ackto); |
344 | ath9k_hw_set_ack_timeout(ah, ackto); | 375 | |
345 | ath9k_hw_set_cts_timeout(ah, ackto); | 376 | spin_unlock_bh(&da->qlock); |
346 | } | 377 | } |
347 | EXPORT_SYMBOL(ath_dynack_reset); | 378 | EXPORT_SYMBOL(ath_dynack_reset); |
348 | 379 | ||
@@ -359,6 +390,8 @@ void ath_dynack_init(struct ath_hw *ah) | |||
359 | 390 | ||
360 | spin_lock_init(&da->qlock); | 391 | spin_lock_init(&da->qlock); |
361 | INIT_LIST_HEAD(&da->nodes); | 392 | INIT_LIST_HEAD(&da->nodes); |
393 | /* ackto = slottime + sifs + air delay */ | ||
394 | da->ackto = 9 + 16 + 64; | ||
362 | 395 | ||
363 | ah->hw->wiphy->features |= NL80211_FEATURE_ACKTO_ESTIMATION; | 396 | ah->hw->wiphy->features |= NL80211_FEATURE_ACKTO_ESTIMATION; |
364 | } | 397 | } |