1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /****************************************************************************** |
3 | * |
4 | * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. |
5 | * |
6 | * Contact Information: |
7 | * Intel Linux Wireless <ilw@linux.intel.com> |
8 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
9 | * |
10 | *****************************************************************************/ |
11 | |
12 | #include <linux/kernel.h> |
13 | #include <linux/skbuff.h> |
14 | #include <linux/slab.h> |
15 | #include <net/mac80211.h> |
16 | |
17 | #include <linux/netdevice.h> |
18 | #include <linux/etherdevice.h> |
19 | #include <linux/delay.h> |
20 | |
21 | #include <linux/workqueue.h> |
22 | |
23 | #include "commands.h" |
24 | #include "3945.h" |
25 | |
26 | #define RS_NAME "iwl-3945-rs" |
27 | |
28 | static s32 il3945_expected_tpt_g[RATE_COUNT_3945] = { |
29 | 7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202 |
30 | }; |
31 | |
32 | static s32 il3945_expected_tpt_g_prot[RATE_COUNT_3945] = { |
33 | 7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125 |
34 | }; |
35 | |
36 | static s32 il3945_expected_tpt_a[RATE_COUNT_3945] = { |
37 | 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186 |
38 | }; |
39 | |
40 | static s32 il3945_expected_tpt_b[RATE_COUNT_3945] = { |
41 | 7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0 |
42 | }; |
43 | |
44 | struct il3945_tpt_entry { |
45 | s8 ; |
46 | u8 idx; |
47 | }; |
48 | |
49 | static struct il3945_tpt_entry il3945_tpt_table_a[] = { |
50 | {-60, RATE_54M_IDX}, |
51 | {-64, RATE_48M_IDX}, |
52 | {-72, RATE_36M_IDX}, |
53 | {-80, RATE_24M_IDX}, |
54 | {-84, RATE_18M_IDX}, |
55 | {-85, RATE_12M_IDX}, |
56 | {-87, RATE_9M_IDX}, |
57 | {-89, RATE_6M_IDX} |
58 | }; |
59 | |
60 | static struct il3945_tpt_entry il3945_tpt_table_g[] = { |
61 | {-60, RATE_54M_IDX}, |
62 | {-64, RATE_48M_IDX}, |
63 | {-68, RATE_36M_IDX}, |
64 | {-80, RATE_24M_IDX}, |
65 | {-84, RATE_18M_IDX}, |
66 | {-85, RATE_12M_IDX}, |
67 | {-86, RATE_11M_IDX}, |
68 | {-88, RATE_5M_IDX}, |
69 | {-90, RATE_2M_IDX}, |
70 | {-92, RATE_1M_IDX} |
71 | }; |
72 | |
73 | #define RATE_MAX_WINDOW 62 |
74 | #define RATE_FLUSH (3*HZ) |
75 | #define RATE_WIN_FLUSH (HZ/2) |
76 | #define IL39_RATE_HIGH_TH 11520 |
77 | #define IL_SUCCESS_UP_TH 8960 |
78 | #define IL_SUCCESS_DOWN_TH 10880 |
79 | #define RATE_MIN_FAILURE_TH 6 |
80 | #define RATE_MIN_SUCCESS_TH 8 |
81 | #define RATE_DECREASE_TH 1920 |
82 | #define RATE_RETRY_TH 15 |
83 | |
84 | static u8 |
85 | (s32 , enum nl80211_band band) |
86 | { |
87 | u32 idx = 0; |
88 | u32 table_size = 0; |
89 | struct il3945_tpt_entry *tpt_table = NULL; |
90 | |
91 | if (rssi < IL_MIN_RSSI_VAL || rssi > IL_MAX_RSSI_VAL) |
92 | rssi = IL_MIN_RSSI_VAL; |
93 | |
94 | switch (band) { |
95 | case NL80211_BAND_2GHZ: |
96 | tpt_table = il3945_tpt_table_g; |
97 | table_size = ARRAY_SIZE(il3945_tpt_table_g); |
98 | break; |
99 | case NL80211_BAND_5GHZ: |
100 | tpt_table = il3945_tpt_table_a; |
101 | table_size = ARRAY_SIZE(il3945_tpt_table_a); |
102 | break; |
103 | default: |
104 | BUG(); |
105 | break; |
106 | } |
107 | |
108 | while (idx < table_size && rssi < tpt_table[idx].min_rssi) |
109 | idx++; |
110 | |
111 | idx = min(idx, table_size - 1); |
112 | |
113 | return tpt_table[idx].idx; |
114 | } |
115 | |
116 | static void |
117 | il3945_clear_win(struct il3945_rate_scale_data *win) |
118 | { |
119 | win->data = 0; |
120 | win->success_counter = 0; |
121 | win->success_ratio = -1; |
122 | win->counter = 0; |
123 | win->average_tpt = IL_INVALID_VALUE; |
124 | win->stamp = 0; |
125 | } |
126 | |
127 | /* |
128 | * il3945_rate_scale_flush_wins - flush out the rate scale wins |
129 | * |
130 | * Returns the number of wins that have gathered data but were |
131 | * not flushed. If there were any that were not flushed, then |
132 | * reschedule the rate flushing routine. |
133 | */ |
134 | static int |
135 | il3945_rate_scale_flush_wins(struct il3945_rs_sta *rs_sta) |
136 | { |
137 | int unflushed = 0; |
138 | int i; |
139 | unsigned long flags; |
140 | struct il_priv *il __maybe_unused = rs_sta->il; |
141 | |
142 | /* |
143 | * For each rate, if we have collected data on that rate |
144 | * and it has been more than RATE_WIN_FLUSH |
145 | * since we flushed, clear out the gathered stats |
146 | */ |
147 | for (i = 0; i < RATE_COUNT_3945; i++) { |
148 | if (!rs_sta->win[i].counter) |
149 | continue; |
150 | |
151 | spin_lock_irqsave(&rs_sta->lock, flags); |
152 | if (time_after(jiffies, rs_sta->win[i].stamp + RATE_WIN_FLUSH)) { |
153 | D_RATE("flushing %d samples of rate " "idx %d\n" , |
154 | rs_sta->win[i].counter, i); |
155 | il3945_clear_win(win: &rs_sta->win[i]); |
156 | } else |
157 | unflushed++; |
158 | spin_unlock_irqrestore(lock: &rs_sta->lock, flags); |
159 | } |
160 | |
161 | return unflushed; |
162 | } |
163 | |
164 | #define RATE_FLUSH_MAX 5000 /* msec */ |
165 | #define RATE_FLUSH_MIN 50 /* msec */ |
166 | #define IL_AVERAGE_PACKETS 1500 |
167 | |
168 | static void |
169 | il3945_bg_rate_scale_flush(struct timer_list *t) |
170 | { |
171 | struct il3945_rs_sta *rs_sta = from_timer(rs_sta, t, rate_scale_flush); |
172 | struct il_priv *il __maybe_unused = rs_sta->il; |
173 | int unflushed = 0; |
174 | unsigned long flags; |
175 | u32 packet_count, duration, pps; |
176 | |
177 | D_RATE("enter\n" ); |
178 | |
179 | unflushed = il3945_rate_scale_flush_wins(rs_sta); |
180 | |
181 | spin_lock_irqsave(&rs_sta->lock, flags); |
182 | |
183 | /* Number of packets Rx'd since last time this timer ran */ |
184 | packet_count = (rs_sta->tx_packets - rs_sta->last_tx_packets) + 1; |
185 | |
186 | rs_sta->last_tx_packets = rs_sta->tx_packets + 1; |
187 | |
188 | if (unflushed) { |
189 | duration = |
190 | jiffies_to_msecs(j: jiffies - rs_sta->last_partial_flush); |
191 | |
192 | D_RATE("Tx'd %d packets in %dms\n" , packet_count, duration); |
193 | |
194 | /* Determine packets per second */ |
195 | if (duration) |
196 | pps = (packet_count * 1000) / duration; |
197 | else |
198 | pps = 0; |
199 | |
200 | if (pps) { |
201 | duration = (IL_AVERAGE_PACKETS * 1000) / pps; |
202 | if (duration < RATE_FLUSH_MIN) |
203 | duration = RATE_FLUSH_MIN; |
204 | else if (duration > RATE_FLUSH_MAX) |
205 | duration = RATE_FLUSH_MAX; |
206 | } else |
207 | duration = RATE_FLUSH_MAX; |
208 | |
209 | rs_sta->flush_time = msecs_to_jiffies(m: duration); |
210 | |
211 | D_RATE("new flush period: %d msec ave %d\n" , duration, |
212 | packet_count); |
213 | |
214 | mod_timer(timer: &rs_sta->rate_scale_flush, |
215 | expires: jiffies + rs_sta->flush_time); |
216 | |
217 | rs_sta->last_partial_flush = jiffies; |
218 | } else { |
219 | rs_sta->flush_time = RATE_FLUSH; |
220 | rs_sta->flush_pending = 0; |
221 | } |
222 | /* If there weren't any unflushed entries, we don't schedule the timer |
223 | * to run again */ |
224 | |
225 | rs_sta->last_flush = jiffies; |
226 | |
227 | spin_unlock_irqrestore(lock: &rs_sta->lock, flags); |
228 | |
229 | D_RATE("leave\n" ); |
230 | } |
231 | |
232 | /* |
233 | * il3945_collect_tx_data - Update the success/failure sliding win |
234 | * |
235 | * We keep a sliding win of the last 64 packets transmitted |
236 | * at this rate. win->data contains the bitmask of successful |
237 | * packets. |
238 | */ |
239 | static void |
240 | il3945_collect_tx_data(struct il3945_rs_sta *rs_sta, |
241 | struct il3945_rate_scale_data *win, int success, |
242 | int retries, int idx) |
243 | { |
244 | unsigned long flags; |
245 | s32 fail_count; |
246 | struct il_priv *il __maybe_unused = rs_sta->il; |
247 | |
248 | if (!retries) { |
249 | D_RATE("leave: retries == 0 -- should be at least 1\n" ); |
250 | return; |
251 | } |
252 | |
253 | spin_lock_irqsave(&rs_sta->lock, flags); |
254 | |
255 | /* |
256 | * Keep track of only the latest 62 tx frame attempts in this rate's |
257 | * history win; anything older isn't really relevant any more. |
258 | * If we have filled up the sliding win, drop the oldest attempt; |
259 | * if the oldest attempt (highest bit in bitmap) shows "success", |
260 | * subtract "1" from the success counter (this is the main reason |
261 | * we keep these bitmaps!). |
262 | * */ |
263 | while (retries > 0) { |
264 | if (win->counter >= RATE_MAX_WINDOW) { |
265 | |
266 | /* remove earliest */ |
267 | win->counter = RATE_MAX_WINDOW - 1; |
268 | |
269 | if (win->data & (1ULL << (RATE_MAX_WINDOW - 1))) { |
270 | win->data &= ~(1ULL << (RATE_MAX_WINDOW - 1)); |
271 | win->success_counter--; |
272 | } |
273 | } |
274 | |
275 | /* Increment frames-attempted counter */ |
276 | win->counter++; |
277 | |
278 | /* Shift bitmap by one frame (throw away oldest history), |
279 | * OR in "1", and increment "success" if this |
280 | * frame was successful. */ |
281 | win->data <<= 1; |
282 | if (success > 0) { |
283 | win->success_counter++; |
284 | win->data |= 0x1; |
285 | success--; |
286 | } |
287 | |
288 | retries--; |
289 | } |
290 | |
291 | /* Calculate current success ratio, avoid divide-by-0! */ |
292 | if (win->counter > 0) |
293 | win->success_ratio = |
294 | 128 * (100 * win->success_counter) / win->counter; |
295 | else |
296 | win->success_ratio = IL_INVALID_VALUE; |
297 | |
298 | fail_count = win->counter - win->success_counter; |
299 | |
300 | /* Calculate average throughput, if we have enough history. */ |
301 | if (fail_count >= RATE_MIN_FAILURE_TH || |
302 | win->success_counter >= RATE_MIN_SUCCESS_TH) |
303 | win->average_tpt = |
304 | ((win->success_ratio * rs_sta->expected_tpt[idx] + |
305 | 64) / 128); |
306 | else |
307 | win->average_tpt = IL_INVALID_VALUE; |
308 | |
309 | /* Tag this win as having been updated */ |
310 | win->stamp = jiffies; |
311 | |
312 | spin_unlock_irqrestore(lock: &rs_sta->lock, flags); |
313 | } |
314 | |
315 | /* |
316 | * Called after adding a new station to initialize rate scaling |
317 | */ |
318 | void |
319 | il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id) |
320 | { |
321 | struct ieee80211_hw *hw = il->hw; |
322 | struct ieee80211_conf *conf = &il->hw->conf; |
323 | struct il3945_sta_priv *psta; |
324 | struct il3945_rs_sta *rs_sta; |
325 | struct ieee80211_supported_band *sband; |
326 | int i; |
327 | |
328 | D_INFO("enter\n" ); |
329 | if (sta_id == il->hw_params.bcast_id) |
330 | goto out; |
331 | |
332 | psta = (struct il3945_sta_priv *)sta->drv_priv; |
333 | rs_sta = &psta->rs_sta; |
334 | sband = hw->wiphy->bands[conf->chandef.chan->band]; |
335 | |
336 | rs_sta->il = il; |
337 | |
338 | rs_sta->start_rate = RATE_INVALID; |
339 | |
340 | /* default to just 802.11b */ |
341 | rs_sta->expected_tpt = il3945_expected_tpt_b; |
342 | |
343 | rs_sta->last_partial_flush = jiffies; |
344 | rs_sta->last_flush = jiffies; |
345 | rs_sta->flush_time = RATE_FLUSH; |
346 | rs_sta->last_tx_packets = 0; |
347 | |
348 | for (i = 0; i < RATE_COUNT_3945; i++) |
349 | il3945_clear_win(win: &rs_sta->win[i]); |
350 | |
351 | /* TODO: what is a good starting rate for STA? About middle? Maybe not |
352 | * the lowest or the highest rate.. Could consider using RSSI from |
353 | * previous packets? Need to have IEEE 802.1X auth succeed immediately |
354 | * after assoc.. */ |
355 | |
356 | for (i = sband->n_bitrates - 1; i >= 0; i--) { |
357 | if (sta->deflink.supp_rates[sband->band] & (1 << i)) { |
358 | rs_sta->last_txrate_idx = i; |
359 | break; |
360 | } |
361 | } |
362 | |
363 | il->_3945.sta_supp_rates = sta->deflink.supp_rates[sband->band]; |
364 | /* For 5 GHz band it start at IL_FIRST_OFDM_RATE */ |
365 | if (sband->band == NL80211_BAND_5GHZ) { |
366 | rs_sta->last_txrate_idx += IL_FIRST_OFDM_RATE; |
367 | il->_3945.sta_supp_rates <<= IL_FIRST_OFDM_RATE; |
368 | } |
369 | |
370 | out: |
371 | il->stations[sta_id].used &= ~IL_STA_UCODE_INPROGRESS; |
372 | |
373 | D_INFO("leave\n" ); |
374 | } |
375 | |
376 | static void * |
377 | il3945_rs_alloc(struct ieee80211_hw *hw) |
378 | { |
379 | return hw->priv; |
380 | } |
381 | |
382 | /* rate scale requires free function to be implemented */ |
383 | static void |
384 | il3945_rs_free(void *il) |
385 | { |
386 | } |
387 | |
388 | static void * |
389 | il3945_rs_alloc_sta(void *il_priv, struct ieee80211_sta *sta, gfp_t gfp) |
390 | { |
391 | struct il3945_rs_sta *rs_sta; |
392 | struct il3945_sta_priv *psta = (void *)sta->drv_priv; |
393 | struct il_priv *il __maybe_unused = il_priv; |
394 | |
395 | D_RATE("enter\n" ); |
396 | |
397 | rs_sta = &psta->rs_sta; |
398 | |
399 | spin_lock_init(&rs_sta->lock); |
400 | timer_setup(&rs_sta->rate_scale_flush, il3945_bg_rate_scale_flush, 0); |
401 | D_RATE("leave\n" ); |
402 | |
403 | return rs_sta; |
404 | } |
405 | |
406 | static void |
407 | il3945_rs_free_sta(void *il_priv, struct ieee80211_sta *sta, void *il_sta) |
408 | { |
409 | struct il3945_rs_sta *rs_sta = il_sta; |
410 | |
411 | /* |
412 | * Be careful not to use any members of il3945_rs_sta (like trying |
413 | * to use il_priv to print out debugging) since it may not be fully |
414 | * initialized at this point. |
415 | */ |
416 | del_timer_sync(timer: &rs_sta->rate_scale_flush); |
417 | } |
418 | |
419 | /* |
420 | * il3945_rs_tx_status - Update rate control values based on Tx results |
421 | * |
422 | * NOTE: Uses il_priv->retry_rate for the # of retries attempted by |
423 | * the hardware for each rate. |
424 | */ |
425 | static void |
426 | il3945_rs_tx_status(void *il_rate, struct ieee80211_supported_band *sband, |
427 | struct ieee80211_sta *sta, void *il_sta, |
428 | struct sk_buff *skb) |
429 | { |
430 | s8 retries = 0, current_count; |
431 | int scale_rate_idx, first_idx, last_idx; |
432 | unsigned long flags; |
433 | struct il_priv *il = (struct il_priv *)il_rate; |
434 | struct il3945_rs_sta *rs_sta = il_sta; |
435 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
436 | |
437 | D_RATE("enter\n" ); |
438 | |
439 | retries = info->status.rates[0].count; |
440 | /* Sanity Check for retries */ |
441 | if (retries > RATE_RETRY_TH) |
442 | retries = RATE_RETRY_TH; |
443 | |
444 | first_idx = sband->bitrates[info->status.rates[0].idx].hw_value; |
445 | if (first_idx < 0 || first_idx >= RATE_COUNT_3945) { |
446 | D_RATE("leave: Rate out of bounds: %d\n" , first_idx); |
447 | return; |
448 | } |
449 | |
450 | if (!il_sta) { |
451 | D_RATE("leave: No STA il data to update!\n" ); |
452 | return; |
453 | } |
454 | |
455 | /* Treat uninitialized rate scaling data same as non-existing. */ |
456 | if (!rs_sta->il) { |
457 | D_RATE("leave: STA il data uninitialized!\n" ); |
458 | return; |
459 | } |
460 | |
461 | rs_sta->tx_packets++; |
462 | |
463 | scale_rate_idx = first_idx; |
464 | last_idx = first_idx; |
465 | |
466 | /* |
467 | * Update the win for each rate. We determine which rates |
468 | * were Tx'd based on the total number of retries vs. the number |
469 | * of retries configured for each rate -- currently set to the |
470 | * il value 'retry_rate' vs. rate specific |
471 | * |
472 | * On exit from this while loop last_idx indicates the rate |
473 | * at which the frame was finally transmitted (or failed if no |
474 | * ACK) |
475 | */ |
476 | while (retries > 1) { |
477 | if ((retries - 1) < il->retry_rate) { |
478 | current_count = (retries - 1); |
479 | last_idx = scale_rate_idx; |
480 | } else { |
481 | current_count = il->retry_rate; |
482 | last_idx = il3945_rs_next_rate(il, rate: scale_rate_idx); |
483 | } |
484 | |
485 | /* Update this rate accounting for as many retries |
486 | * as was used for it (per current_count) */ |
487 | il3945_collect_tx_data(rs_sta, win: &rs_sta->win[scale_rate_idx], success: 0, |
488 | retries: current_count, idx: scale_rate_idx); |
489 | D_RATE("Update rate %d for %d retries.\n" , scale_rate_idx, |
490 | current_count); |
491 | |
492 | retries -= current_count; |
493 | |
494 | scale_rate_idx = last_idx; |
495 | } |
496 | |
497 | /* Update the last idx win with success/failure based on ACK */ |
498 | D_RATE("Update rate %d with %s.\n" , last_idx, |
499 | (info->flags & IEEE80211_TX_STAT_ACK) ? "success" : "failure" ); |
500 | il3945_collect_tx_data(rs_sta, win: &rs_sta->win[last_idx], |
501 | success: info->flags & IEEE80211_TX_STAT_ACK, retries: 1, |
502 | idx: last_idx); |
503 | |
504 | /* We updated the rate scale win -- if its been more than |
505 | * flush_time since the last run, schedule the flush |
506 | * again */ |
507 | spin_lock_irqsave(&rs_sta->lock, flags); |
508 | |
509 | if (!rs_sta->flush_pending && |
510 | time_after(jiffies, rs_sta->last_flush + rs_sta->flush_time)) { |
511 | |
512 | rs_sta->last_partial_flush = jiffies; |
513 | rs_sta->flush_pending = 1; |
514 | mod_timer(timer: &rs_sta->rate_scale_flush, |
515 | expires: jiffies + rs_sta->flush_time); |
516 | } |
517 | |
518 | spin_unlock_irqrestore(lock: &rs_sta->lock, flags); |
519 | |
520 | D_RATE("leave\n" ); |
521 | } |
522 | |
523 | static u16 |
524 | il3945_get_adjacent_rate(struct il3945_rs_sta *rs_sta, u8 idx, u16 rate_mask, |
525 | enum nl80211_band band) |
526 | { |
527 | u8 high = RATE_INVALID; |
528 | u8 low = RATE_INVALID; |
529 | struct il_priv *il __maybe_unused = rs_sta->il; |
530 | |
531 | /* 802.11A walks to the next literal adjacent rate in |
532 | * the rate table */ |
533 | if (unlikely(band == NL80211_BAND_5GHZ)) { |
534 | int i; |
535 | u32 mask; |
536 | |
537 | /* Find the previous rate that is in the rate mask */ |
538 | i = idx - 1; |
539 | for (mask = (1 << i); i >= 0; i--, mask >>= 1) { |
540 | if (rate_mask & mask) { |
541 | low = i; |
542 | break; |
543 | } |
544 | } |
545 | |
546 | /* Find the next rate that is in the rate mask */ |
547 | i = idx + 1; |
548 | for (mask = (1 << i); i < RATE_COUNT_3945; i++, mask <<= 1) { |
549 | if (rate_mask & mask) { |
550 | high = i; |
551 | break; |
552 | } |
553 | } |
554 | |
555 | return (high << 8) | low; |
556 | } |
557 | |
558 | low = idx; |
559 | while (low != RATE_INVALID) { |
560 | if (rs_sta->tgg) |
561 | low = il3945_rates[low].prev_rs_tgg; |
562 | else |
563 | low = il3945_rates[low].prev_rs; |
564 | if (low == RATE_INVALID) |
565 | break; |
566 | if (rate_mask & (1 << low)) |
567 | break; |
568 | D_RATE("Skipping masked lower rate: %d\n" , low); |
569 | } |
570 | |
571 | high = idx; |
572 | while (high != RATE_INVALID) { |
573 | if (rs_sta->tgg) |
574 | high = il3945_rates[high].next_rs_tgg; |
575 | else |
576 | high = il3945_rates[high].next_rs; |
577 | if (high == RATE_INVALID) |
578 | break; |
579 | if (rate_mask & (1 << high)) |
580 | break; |
581 | D_RATE("Skipping masked higher rate: %d\n" , high); |
582 | } |
583 | |
584 | return (high << 8) | low; |
585 | } |
586 | |
587 | /* |
588 | * il3945_rs_get_rate - find the rate for the requested packet |
589 | * |
590 | * Returns the ieee80211_rate structure allocated by the driver. |
591 | * |
592 | * The rate control algorithm has no internal mapping between hw_mode's |
593 | * rate ordering and the rate ordering used by the rate control algorithm. |
594 | * |
595 | * The rate control algorithm uses a single table of rates that goes across |
596 | * the entire A/B/G spectrum vs. being limited to just one particular |
597 | * hw_mode. |
598 | * |
599 | * As such, we can't convert the idx obtained below into the hw_mode's |
600 | * rate table and must reference the driver allocated rate table |
601 | * |
602 | */ |
603 | static void |
604 | il3945_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta, |
605 | struct ieee80211_tx_rate_control *txrc) |
606 | { |
607 | struct ieee80211_supported_band *sband = txrc->sband; |
608 | struct sk_buff *skb = txrc->skb; |
609 | u8 low = RATE_INVALID; |
610 | u8 high = RATE_INVALID; |
611 | u16 high_low; |
612 | int idx; |
613 | struct il3945_rs_sta *rs_sta = il_sta; |
614 | struct il3945_rate_scale_data *win = NULL; |
615 | int current_tpt = IL_INVALID_VALUE; |
616 | int low_tpt = IL_INVALID_VALUE; |
617 | int high_tpt = IL_INVALID_VALUE; |
618 | u32 fail_count; |
619 | s8 scale_action = 0; |
620 | unsigned long flags; |
621 | u16 rate_mask; |
622 | s8 max_rate_idx = -1; |
623 | struct il_priv *il __maybe_unused = (struct il_priv *)il_r; |
624 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
625 | |
626 | D_RATE("enter\n" ); |
627 | |
628 | /* Treat uninitialized rate scaling data same as non-existing. */ |
629 | if (rs_sta && !rs_sta->il) { |
630 | D_RATE("Rate scaling information not initialized yet.\n" ); |
631 | il_sta = NULL; |
632 | } |
633 | |
634 | rate_mask = sta->deflink.supp_rates[sband->band]; |
635 | |
636 | /* get user max rate if set */ |
637 | max_rate_idx = fls(x: txrc->rate_idx_mask) - 1; |
638 | if (sband->band == NL80211_BAND_5GHZ && max_rate_idx != -1) |
639 | max_rate_idx += IL_FIRST_OFDM_RATE; |
640 | if (max_rate_idx < 0 || max_rate_idx >= RATE_COUNT) |
641 | max_rate_idx = -1; |
642 | |
643 | idx = min(rs_sta->last_txrate_idx & 0xffff, RATE_COUNT_3945 - 1); |
644 | |
645 | if (sband->band == NL80211_BAND_5GHZ) |
646 | rate_mask = rate_mask << IL_FIRST_OFDM_RATE; |
647 | |
648 | spin_lock_irqsave(&rs_sta->lock, flags); |
649 | |
650 | /* for recent assoc, choose best rate regarding |
651 | * to rssi value |
652 | */ |
653 | if (rs_sta->start_rate != RATE_INVALID) { |
654 | if (rs_sta->start_rate < idx && |
655 | (rate_mask & (1 << rs_sta->start_rate))) |
656 | idx = rs_sta->start_rate; |
657 | rs_sta->start_rate = RATE_INVALID; |
658 | } |
659 | |
660 | /* force user max rate if set by user */ |
661 | if (max_rate_idx != -1 && max_rate_idx < idx) { |
662 | if (rate_mask & (1 << max_rate_idx)) |
663 | idx = max_rate_idx; |
664 | } |
665 | |
666 | win = &(rs_sta->win[idx]); |
667 | |
668 | fail_count = win->counter - win->success_counter; |
669 | |
670 | if (fail_count < RATE_MIN_FAILURE_TH && |
671 | win->success_counter < RATE_MIN_SUCCESS_TH) { |
672 | spin_unlock_irqrestore(lock: &rs_sta->lock, flags); |
673 | |
674 | D_RATE("Invalid average_tpt on rate %d: " |
675 | "counter: %d, success_counter: %d, " |
676 | "expected_tpt is %sNULL\n" , idx, win->counter, |
677 | win->success_counter, |
678 | rs_sta->expected_tpt ? "not " : "" ); |
679 | |
680 | /* Can't calculate this yet; not enough history */ |
681 | win->average_tpt = IL_INVALID_VALUE; |
682 | goto out; |
683 | |
684 | } |
685 | |
686 | current_tpt = win->average_tpt; |
687 | |
688 | high_low = |
689 | il3945_get_adjacent_rate(rs_sta, idx, rate_mask, band: sband->band); |
690 | low = high_low & 0xff; |
691 | high = (high_low >> 8) & 0xff; |
692 | |
693 | /* If user set max rate, dont allow higher than user constrain */ |
694 | if (max_rate_idx != -1 && max_rate_idx < high) |
695 | high = RATE_INVALID; |
696 | |
697 | /* Collect Measured throughputs of adjacent rates */ |
698 | if (low != RATE_INVALID) |
699 | low_tpt = rs_sta->win[low].average_tpt; |
700 | |
701 | if (high != RATE_INVALID) |
702 | high_tpt = rs_sta->win[high].average_tpt; |
703 | |
704 | spin_unlock_irqrestore(lock: &rs_sta->lock, flags); |
705 | |
706 | scale_action = 0; |
707 | |
708 | /* Low success ratio , need to drop the rate */ |
709 | if (win->success_ratio < RATE_DECREASE_TH || !current_tpt) { |
710 | D_RATE("decrease rate because of low success_ratio\n" ); |
711 | scale_action = -1; |
712 | /* No throughput measured yet for adjacent rates, |
713 | * try increase */ |
714 | } else if (low_tpt == IL_INVALID_VALUE && high_tpt == IL_INVALID_VALUE) { |
715 | |
716 | if (high != RATE_INVALID && |
717 | win->success_ratio >= RATE_INCREASE_TH) |
718 | scale_action = 1; |
719 | else if (low != RATE_INVALID) |
720 | scale_action = 0; |
721 | |
722 | /* Both adjacent throughputs are measured, but neither one has |
723 | * better throughput; we're using the best rate, don't change |
724 | * it! */ |
725 | } else if (low_tpt != IL_INVALID_VALUE && high_tpt != IL_INVALID_VALUE |
726 | && low_tpt < current_tpt && high_tpt < current_tpt) { |
727 | |
728 | D_RATE("No action -- low [%d] & high [%d] < " |
729 | "current_tpt [%d]\n" , low_tpt, high_tpt, current_tpt); |
730 | scale_action = 0; |
731 | |
732 | /* At least one of the rates has better throughput */ |
733 | } else { |
734 | if (high_tpt != IL_INVALID_VALUE) { |
735 | |
736 | /* High rate has better throughput, Increase |
737 | * rate */ |
738 | if (high_tpt > current_tpt && |
739 | win->success_ratio >= RATE_INCREASE_TH) |
740 | scale_action = 1; |
741 | else { |
742 | D_RATE("decrease rate because of high tpt\n" ); |
743 | scale_action = 0; |
744 | } |
745 | } else if (low_tpt != IL_INVALID_VALUE) { |
746 | if (low_tpt > current_tpt) { |
747 | D_RATE("decrease rate because of low tpt\n" ); |
748 | scale_action = -1; |
749 | } else if (win->success_ratio >= RATE_INCREASE_TH) { |
750 | /* Lower rate has better |
751 | * throughput,decrease rate */ |
752 | scale_action = 1; |
753 | } |
754 | } |
755 | } |
756 | |
757 | /* Sanity check; asked for decrease, but success rate or throughput |
758 | * has been good at old rate. Don't change it. */ |
759 | if (scale_action == -1 && low != RATE_INVALID && |
760 | (win->success_ratio > RATE_HIGH_TH || |
761 | current_tpt > 100 * rs_sta->expected_tpt[low])) |
762 | scale_action = 0; |
763 | |
764 | switch (scale_action) { |
765 | case -1: |
766 | /* Decrease rate */ |
767 | if (low != RATE_INVALID) |
768 | idx = low; |
769 | break; |
770 | case 1: |
771 | /* Increase rate */ |
772 | if (high != RATE_INVALID) |
773 | idx = high; |
774 | |
775 | break; |
776 | case 0: |
777 | default: |
778 | /* No change */ |
779 | break; |
780 | } |
781 | |
782 | D_RATE("Selected %d (action %d) - low %d high %d\n" , idx, scale_action, |
783 | low, high); |
784 | |
785 | out: |
786 | |
787 | if (sband->band == NL80211_BAND_5GHZ) { |
788 | if (WARN_ON_ONCE(idx < IL_FIRST_OFDM_RATE)) |
789 | idx = IL_FIRST_OFDM_RATE; |
790 | rs_sta->last_txrate_idx = idx; |
791 | info->control.rates[0].idx = idx - IL_FIRST_OFDM_RATE; |
792 | } else { |
793 | rs_sta->last_txrate_idx = idx; |
794 | info->control.rates[0].idx = rs_sta->last_txrate_idx; |
795 | } |
796 | info->control.rates[0].count = 1; |
797 | |
798 | D_RATE("leave: %d\n" , idx); |
799 | } |
800 | |
801 | #ifdef CONFIG_MAC80211_DEBUGFS |
802 | |
803 | static ssize_t |
804 | il3945_sta_dbgfs_stats_table_read(struct file *file, char __user *user_buf, |
805 | size_t count, loff_t *ppos) |
806 | { |
807 | char *buff; |
808 | int desc = 0; |
809 | int j; |
810 | ssize_t ret; |
811 | struct il3945_rs_sta *lq_sta = file->private_data; |
812 | |
813 | buff = kmalloc(size: 1024, GFP_KERNEL); |
814 | if (!buff) |
815 | return -ENOMEM; |
816 | |
817 | desc += |
818 | sprintf(buf: buff + desc, |
819 | fmt: "tx packets=%d last rate idx=%d\n" |
820 | "rate=0x%X flush time %d\n" , lq_sta->tx_packets, |
821 | lq_sta->last_txrate_idx, lq_sta->start_rate, |
822 | jiffies_to_msecs(j: lq_sta->flush_time)); |
823 | for (j = 0; j < RATE_COUNT_3945; j++) { |
824 | desc += |
825 | sprintf(buf: buff + desc, fmt: "counter=%d success=%d %%=%d\n" , |
826 | lq_sta->win[j].counter, |
827 | lq_sta->win[j].success_counter, |
828 | lq_sta->win[j].success_ratio); |
829 | } |
830 | ret = simple_read_from_buffer(to: user_buf, count, ppos, from: buff, available: desc); |
831 | kfree(objp: buff); |
832 | return ret; |
833 | } |
834 | |
835 | static const struct file_operations rs_sta_dbgfs_stats_table_ops = { |
836 | .read = il3945_sta_dbgfs_stats_table_read, |
837 | .open = simple_open, |
838 | .llseek = default_llseek, |
839 | }; |
840 | |
841 | static void |
842 | il3945_add_debugfs(void *il, void *il_sta, struct dentry *dir) |
843 | { |
844 | struct il3945_rs_sta *lq_sta = il_sta; |
845 | |
846 | debugfs_create_file(name: "rate_stats_table" , mode: 0600, parent: dir, data: lq_sta, |
847 | fops: &rs_sta_dbgfs_stats_table_ops); |
848 | } |
849 | #endif |
850 | |
851 | /* |
852 | * Initialization of rate scaling information is done by driver after |
853 | * the station is added. Since mac80211 calls this function before a |
854 | * station is added we ignore it. |
855 | */ |
856 | static void |
857 | il3945_rs_rate_init_stub(void *il_r, struct ieee80211_supported_band *sband, |
858 | struct cfg80211_chan_def *chandef, |
859 | struct ieee80211_sta *sta, void *il_sta) |
860 | { |
861 | } |
862 | |
863 | static const struct rate_control_ops rs_ops = { |
864 | .name = RS_NAME, |
865 | .tx_status = il3945_rs_tx_status, |
866 | .get_rate = il3945_rs_get_rate, |
867 | .rate_init = il3945_rs_rate_init_stub, |
868 | .alloc = il3945_rs_alloc, |
869 | .free = il3945_rs_free, |
870 | .alloc_sta = il3945_rs_alloc_sta, |
871 | .free_sta = il3945_rs_free_sta, |
872 | #ifdef CONFIG_MAC80211_DEBUGFS |
873 | .add_sta_debugfs = il3945_add_debugfs, |
874 | #endif |
875 | |
876 | }; |
877 | |
878 | void |
879 | il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) |
880 | { |
881 | struct il_priv *il = hw->priv; |
882 | s32 = 0; |
883 | unsigned long flags; |
884 | struct il3945_rs_sta *rs_sta; |
885 | struct ieee80211_sta *sta; |
886 | struct il3945_sta_priv *psta; |
887 | |
888 | D_RATE("enter\n" ); |
889 | |
890 | rcu_read_lock(); |
891 | |
892 | sta = ieee80211_find_sta(vif: il->vif, addr: il->stations[sta_id].sta.sta.addr); |
893 | if (!sta) { |
894 | D_RATE("Unable to find station to initialize rate scaling.\n" ); |
895 | rcu_read_unlock(); |
896 | return; |
897 | } |
898 | |
899 | psta = (void *)sta->drv_priv; |
900 | rs_sta = &psta->rs_sta; |
901 | |
902 | spin_lock_irqsave(&rs_sta->lock, flags); |
903 | |
904 | rs_sta->tgg = 0; |
905 | switch (il->band) { |
906 | case NL80211_BAND_2GHZ: |
907 | /* TODO: this always does G, not a regression */ |
908 | if (il->active.flags & RXON_FLG_TGG_PROTECT_MSK) { |
909 | rs_sta->tgg = 1; |
910 | rs_sta->expected_tpt = il3945_expected_tpt_g_prot; |
911 | } else |
912 | rs_sta->expected_tpt = il3945_expected_tpt_g; |
913 | break; |
914 | case NL80211_BAND_5GHZ: |
915 | rs_sta->expected_tpt = il3945_expected_tpt_a; |
916 | break; |
917 | default: |
918 | BUG(); |
919 | break; |
920 | } |
921 | |
922 | spin_unlock_irqrestore(lock: &rs_sta->lock, flags); |
923 | |
924 | rssi = il->_3945.last_rx_rssi; |
925 | if (rssi == 0) |
926 | rssi = IL_MIN_RSSI_VAL; |
927 | |
928 | D_RATE("Network RSSI: %d\n" , rssi); |
929 | |
930 | rs_sta->start_rate = il3945_get_rate_idx_by_rssi(rssi, band: il->band); |
931 | |
932 | D_RATE("leave: rssi %d assign rate idx: " "%d (plcp 0x%x)\n" , rssi, |
933 | rs_sta->start_rate, il3945_rates[rs_sta->start_rate].plcp); |
934 | rcu_read_unlock(); |
935 | } |
936 | |
937 | int |
938 | il3945_rate_control_register(void) |
939 | { |
940 | return ieee80211_rate_control_register(ops: &rs_ops); |
941 | } |
942 | |
943 | void |
944 | il3945_rate_control_unregister(void) |
945 | { |
946 | ieee80211_rate_control_unregister(ops: &rs_ops); |
947 | } |
948 | |