27 #include <linux/kernel.h>
30 #include <linux/slab.h>
33 #include <linux/netdevice.h>
42 #define RS_NAME "iwl-3945-rs"
45 7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202
49 7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125
53 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186
57 7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0
89 #define RATE_MAX_WINDOW 62
90 #define RATE_FLUSH (3*HZ)
91 #define RATE_WIN_FLUSH (HZ/2)
92 #define IL39_RATE_HIGH_TH 11520
93 #define IL_SUCCESS_UP_TH 8960
94 #define IL_SUCCESS_DOWN_TH 10880
95 #define RATE_MIN_FAILURE_TH 6
96 #define RATE_MIN_SUCCESS_TH 8
97 #define RATE_DECREASE_TH 1920
98 #define RATE_RETRY_TH 15
112 tpt_table = il3945_tpt_table_g;
116 tpt_table = il3945_tpt_table_a;
124 while (idx < table_size && rssi < tpt_table[idx].
min_rssi)
127 idx =
min(idx, table_size - 1);
129 return tpt_table[
idx].
idx;
164 if (!rs_sta->
win[i].counter)
169 D_RATE(
"flushing %d samples of rate " "idx %d\n",
170 rs_sta->
win[i].counter, i);
171 il3945_clear_win(&rs_sta->
win[i]);
174 spin_unlock_irqrestore(&rs_sta->
lock, flags);
180 #define RATE_FLUSH_MAX 5000
181 #define RATE_FLUSH_MIN 50
182 #define IL_AVERAGE_PACKETS 1500
185 il3945_bg_rate_scale_flush(
unsigned long data)
188 struct il_priv *il __maybe_unused = rs_sta->
il;
195 unflushed = il3945_rate_scale_flush_wins(rs_sta);
208 D_RATE(
"Tx'd %d packets in %dms\n", packet_count, duration);
212 pps = (packet_count * 1000) / duration;
227 D_RATE(
"new flush period: %d msec ave %d\n", duration,
243 spin_unlock_irqrestore(&rs_sta->
lock, flags);
262 struct il_priv *il __maybe_unused = rs_sta->
il;
265 D_RATE(
"leave: retries == 0 -- should be at least 1\n");
279 while (retries > 0) {
328 spin_unlock_irqrestore(&rs_sta->
lock, flags);
368 il3945_clear_win(&rs_sta->
win[i]);
375 for (i = sband->
n_bitrates - 1; i >= 0; i--) {
403 il3945_rs_free(
void *il)
412 struct il_priv *il __maybe_unused = il_priv;
427 il3945_rs_free_sta(
void *il_priv,
struct ieee80211_sta *sta,
void *il_sta)
450 s8 retries = 0, current_count;
451 int scale_rate_idx, first_idx, last_idx;
453 struct il_priv *il = (
struct il_priv *)il_rate;
459 retries = info->
status.rates[0].count;
465 if (first_idx < 0 || first_idx >= RATE_COUNT_3945) {
466 D_RATE(
"leave: Rate out of bounds: %d\n", first_idx);
471 D_RATE(
"leave: No STA il data to update!\n");
477 D_RATE(
"leave: STA il data uninitialized!\n");
483 scale_rate_idx = first_idx;
484 last_idx = first_idx;
496 while (retries > 1) {
498 current_count = (retries - 1);
499 last_idx = scale_rate_idx;
507 il3945_collect_tx_data(rs_sta, &rs_sta->
win[scale_rate_idx], 0,
508 current_count, scale_rate_idx);
509 D_RATE(
"Update rate %d for %d retries.\n", scale_rate_idx,
512 retries -= current_count;
514 scale_rate_idx = last_idx;
518 D_RATE(
"Update rate %d with %s.\n", last_idx,
520 il3945_collect_tx_data(rs_sta, &rs_sta->
win[last_idx],
538 spin_unlock_irqrestore(&rs_sta->
lock, flags);
549 struct il_priv *il __maybe_unused = rs_sta->
il;
559 for (mask = (1 << i); i >= 0; i--, mask >>= 1) {
560 if (rate_mask & mask) {
569 if (rate_mask & mask) {
575 return (high << 8) |
low;
586 if (rate_mask & (1 << low))
588 D_RATE(
"Skipping masked lower rate: %d\n", low);
599 if (rate_mask & (1 << high))
601 D_RATE(
"Skipping masked higher rate: %d\n", high);
604 return (high << 8) |
low;
624 il3945_rs_get_rate(
void *il_r,
struct ieee80211_sta *sta,
void *il_sta,
642 s8 max_rate_idx = -1;
643 struct il_priv *il __maybe_unused = (
struct il_priv *)il_r;
649 if (rs_sta && !rs_sta->
il) {
650 D_RATE(
"Rate scaling information not initialized yet.\n");
663 if (max_rate_idx < 0 || max_rate_idx >=
RATE_COUNT)
684 if (max_rate_idx != -1 && max_rate_idx < idx) {
685 if (rate_mask & (1 << max_rate_idx))
689 win = &(rs_sta->
win[
idx]);
695 spin_unlock_irqrestore(&rs_sta->
lock, flags);
697 D_RATE(
"Invalid average_tpt on rate %d: "
698 "counter: %d, success_counter: %d, "
699 "expected_tpt is %sNULL\n", idx, win->
counter,
712 il3945_get_adjacent_rate(rs_sta, idx, rate_mask, sband->
band);
713 low = high_low & 0xff;
714 high = (high_low >> 8) & 0xff;
717 if (max_rate_idx != -1 && max_rate_idx < high)
722 low_tpt = rs_sta->
win[
low].average_tpt;
725 high_tpt = rs_sta->
win[
high].average_tpt;
727 spin_unlock_irqrestore(&rs_sta->
lock, flags);
733 D_RATE(
"decrease rate because of low success_ratio\n");
749 && low_tpt < current_tpt && high_tpt < current_tpt) {
751 D_RATE(
"No action -- low [%d] & high [%d] < "
752 "current_tpt [%d]\n", low_tpt, high_tpt, current_tpt);
761 if (high_tpt > current_tpt &&
765 D_RATE(
"decrease rate because of high tpt\n");
769 if (low_tpt > current_tpt) {
770 D_RATE(
"decrease rate because of low tpt\n");
787 switch (scale_action) {
805 D_RATE(
"Selected %d (action %d) - low %d high %d\n", idx, scale_action,
820 D_RATE(
"leave: %d\n", idx);
823 #ifdef CONFIG_MAC80211_DEBUGFS
826 il3945_sta_dbgfs_stats_table_read(
struct file *
file,
char __user *user_buf,
827 size_t count, loff_t *ppos)
841 "tx packets=%d last rate idx=%d\n"
842 "rate=0x%X flush time %d\n", lq_sta->
tx_packets,
847 sprintf(buff + desc,
"counter=%d success=%d %%=%d\n",
848 lq_sta->
win[j].counter,
849 lq_sta->
win[j].success_counter,
850 lq_sta->
win[j].success_ratio);
858 .
read = il3945_sta_dbgfs_stats_table_read,
864 il3945_add_debugfs(
void *il,
void *il_sta,
struct dentry *dir)
868 lq_sta->rs_sta_dbgfs_stats_table_file =
870 &rs_sta_dbgfs_stats_table_ops);
875 il3945_remove_debugfs(
void *il,
void *il_sta)
896 .tx_status = il3945_rs_tx_status,
897 .get_rate = il3945_rs_get_rate,
898 .rate_init = il3945_rs_rate_init_stub,
899 .alloc = il3945_rs_alloc,
900 .free = il3945_rs_free,
901 .alloc_sta = il3945_rs_alloc_sta,
902 .free_sta = il3945_rs_free_sta,
903 #ifdef CONFIG_MAC80211_DEBUGFS
904 .add_sta_debugfs = il3945_add_debugfs,
905 .remove_sta_debugfs = il3945_remove_debugfs,
913 struct il_priv *il = hw->
priv;
926 D_RATE(
"Unable to find station to initialize rate scaling.\n");
931 psta = (
void *)sta->drv_priv;
954 spin_unlock_irqrestore(&rs_sta->
lock, flags);
956 rssi = il->_3945.last_rx_rssi;
960 D_RATE(
"Network RSSI: %d\n", rssi);
964 D_RATE(
"leave: rssi %d assign rate idx: " "%d (plcp 0x%x)\n", rssi,