aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/dynack.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-09-14 09:08:18 -0400
committerDavid S. Miller <davem@davemloft.net>2019-09-14 09:08:18 -0400
commita3d3c74da49c65fc63a937fa559186b0e16adca3 (patch)
tree946a98b1350387ee8c6ee8d6572864c838b20191 /drivers/net/wireless/ath/ath9k/dynack.c
parent1ba569fc2250b7717fcf3b943efe043c98c6a919 (diff)
parentf9e568754562e0f506e12aa899c378b4155080e9 (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.c101
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 */
31static 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 */
106static 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 */
87static void ath_dynack_compute_ackto(struct ath_hw *ah) 124static 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 */
117static void ath_dynack_compute_to(struct ath_hw *ah) 146static 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 */
293void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an) 322void 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}
305EXPORT_SYMBOL(ath_dynack_node_init); 332EXPORT_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}
321EXPORT_SYMBOL(ath_dynack_node_deinit); 348EXPORT_SYMBOL(ath_dynack_node_deinit);
322 349
@@ -327,22 +354,26 @@ EXPORT_SYMBOL(ath_dynack_node_deinit);
327 */ 354 */
328void ath_dynack_reset(struct ath_hw *ah) 355void 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}
347EXPORT_SYMBOL(ath_dynack_reset); 378EXPORT_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}