diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-rs.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 584 |
1 files changed, 236 insertions, 348 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 81726ee32858..fe511cbf012e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -75,104 +75,6 @@ static const u8 ant_toggle_lookup[] = { | |||
75 | /*ANT_ABC -> */ ANT_ABC, | 75 | /*ANT_ABC -> */ ANT_ABC, |
76 | }; | 76 | }; |
77 | 77 | ||
78 | /** | ||
79 | * struct iwl_rate_scale_data -- tx success history for one rate | ||
80 | */ | ||
81 | struct iwl_rate_scale_data { | ||
82 | u64 data; /* bitmap of successful frames */ | ||
83 | s32 success_counter; /* number of frames successful */ | ||
84 | s32 success_ratio; /* per-cent * 128 */ | ||
85 | s32 counter; /* number of frames attempted */ | ||
86 | s32 average_tpt; /* success ratio * expected throughput */ | ||
87 | unsigned long stamp; | ||
88 | }; | ||
89 | |||
90 | /** | ||
91 | * struct iwl_scale_tbl_info -- tx params and success history for all rates | ||
92 | * | ||
93 | * There are two of these in struct iwl_lq_sta, | ||
94 | * one for "active", and one for "search". | ||
95 | */ | ||
96 | struct iwl_scale_tbl_info { | ||
97 | enum iwl_table_type lq_type; | ||
98 | u8 ant_type; | ||
99 | u8 is_SGI; /* 1 = short guard interval */ | ||
100 | u8 is_ht40; /* 1 = 40 MHz channel width */ | ||
101 | u8 is_dup; /* 1 = duplicated data streams */ | ||
102 | u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ | ||
103 | u8 max_search; /* maximun number of tables we can search */ | ||
104 | s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ | ||
105 | u32 current_rate; /* rate_n_flags, uCode API format */ | ||
106 | struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ | ||
107 | }; | ||
108 | |||
109 | struct iwl_traffic_load { | ||
110 | unsigned long time_stamp; /* age of the oldest statistics */ | ||
111 | u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time | ||
112 | * slice */ | ||
113 | u32 total; /* total num of packets during the | ||
114 | * last TID_MAX_TIME_DIFF */ | ||
115 | u8 queue_count; /* number of queues that has | ||
116 | * been used since the last cleanup */ | ||
117 | u8 head; /* start of the circular buffer */ | ||
118 | }; | ||
119 | |||
120 | /** | ||
121 | * struct iwl_lq_sta -- driver's rate scaling private structure | ||
122 | * | ||
123 | * Pointer to this gets passed back and forth between driver and mac80211. | ||
124 | */ | ||
125 | struct iwl_lq_sta { | ||
126 | u8 active_tbl; /* index of active table, range 0-1 */ | ||
127 | u8 enable_counter; /* indicates HT mode */ | ||
128 | u8 stay_in_tbl; /* 1: disallow, 0: allow search for new mode */ | ||
129 | u8 search_better_tbl; /* 1: currently trying alternate mode */ | ||
130 | s32 last_tpt; | ||
131 | |||
132 | /* The following determine when to search for a new mode */ | ||
133 | u32 table_count_limit; | ||
134 | u32 max_failure_limit; /* # failed frames before new search */ | ||
135 | u32 max_success_limit; /* # successful frames before new search */ | ||
136 | u32 table_count; | ||
137 | u32 total_failed; /* total failed frames, any/all rates */ | ||
138 | u32 total_success; /* total successful frames, any/all rates */ | ||
139 | u64 flush_timer; /* time staying in mode before new search */ | ||
140 | |||
141 | u8 action_counter; /* # mode-switch actions tried */ | ||
142 | u8 is_green; | ||
143 | u8 is_dup; | ||
144 | enum ieee80211_band band; | ||
145 | u8 ibss_sta_added; | ||
146 | |||
147 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ | ||
148 | u32 supp_rates; | ||
149 | u16 active_legacy_rate; | ||
150 | u16 active_siso_rate; | ||
151 | u16 active_mimo2_rate; | ||
152 | u16 active_mimo3_rate; | ||
153 | u16 active_rate_basic; | ||
154 | s8 max_rate_idx; /* Max rate set by user */ | ||
155 | u8 missed_rate_counter; | ||
156 | |||
157 | struct iwl_link_quality_cmd lq; | ||
158 | struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ | ||
159 | struct iwl_traffic_load load[TID_MAX_LOAD_COUNT]; | ||
160 | u8 tx_agg_tid_en; | ||
161 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
162 | struct dentry *rs_sta_dbgfs_scale_table_file; | ||
163 | struct dentry *rs_sta_dbgfs_stats_table_file; | ||
164 | struct dentry *rs_sta_dbgfs_rate_scale_data_file; | ||
165 | struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; | ||
166 | u32 dbg_fixed_rate; | ||
167 | #endif | ||
168 | struct iwl_priv *drv; | ||
169 | |||
170 | /* used to be in sta_info */ | ||
171 | int last_txrate_idx; | ||
172 | /* last tx rate_n_flags */ | ||
173 | u32 last_rate_n_flags; | ||
174 | }; | ||
175 | |||
176 | static void rs_rate_scale_perform(struct iwl_priv *priv, | 78 | static void rs_rate_scale_perform(struct iwl_priv *priv, |
177 | struct sk_buff *skb, | 79 | struct sk_buff *skb, |
178 | struct ieee80211_sta *sta, | 80 | struct ieee80211_sta *sta, |
@@ -190,84 +92,78 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, | |||
190 | {} | 92 | {} |
191 | #endif | 93 | #endif |
192 | 94 | ||
193 | /* | 95 | /** |
194 | * Expected throughput metrics for following rates: | 96 | * The following tables contain the expected throughput metrics for all rates |
195 | * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits | 97 | * |
196 | * "G" is the only table that supports CCK (the first 4 rates). | 98 | * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits |
99 | * | ||
100 | * where invalid entries are zeros. | ||
101 | * | ||
102 | * CCK rates are only valid in legacy table and will only be used in G | ||
103 | * (2.4 GHz) band. | ||
197 | */ | 104 | */ |
198 | 105 | ||
199 | static s32 expected_tpt_A[IWL_RATE_COUNT] = { | 106 | static s32 expected_tpt_legacy[IWL_RATE_COUNT] = { |
200 | 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186 | 107 | 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0 |
201 | }; | ||
202 | |||
203 | static s32 expected_tpt_G[IWL_RATE_COUNT] = { | ||
204 | 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 186 | ||
205 | }; | ||
206 | |||
207 | static s32 expected_tpt_siso20MHz[IWL_RATE_COUNT] = { | ||
208 | 0, 0, 0, 0, 42, 42, 76, 102, 124, 159, 183, 193, 202 | ||
209 | }; | ||
210 | |||
211 | static s32 expected_tpt_siso20MHzSGI[IWL_RATE_COUNT] = { | ||
212 | 0, 0, 0, 0, 46, 46, 82, 110, 132, 168, 192, 202, 211 | ||
213 | }; | ||
214 | |||
215 | static s32 expected_tpt_mimo2_20MHz[IWL_RATE_COUNT] = { | ||
216 | 0, 0, 0, 0, 74, 74, 123, 155, 179, 214, 236, 244, 251 | ||
217 | }; | ||
218 | |||
219 | static s32 expected_tpt_mimo2_20MHzSGI[IWL_RATE_COUNT] = { | ||
220 | 0, 0, 0, 0, 81, 81, 131, 164, 188, 222, 243, 251, 257 | ||
221 | }; | 108 | }; |
222 | 109 | ||
223 | static s32 expected_tpt_siso40MHz[IWL_RATE_COUNT] = { | 110 | static s32 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = { |
224 | 0, 0, 0, 0, 77, 77, 127, 160, 184, 220, 242, 250, 257 | 111 | {0, 0, 0, 0, 42, 0, 76, 102, 124, 158, 183, 193, 202}, /* Norm */ |
112 | {0, 0, 0, 0, 46, 0, 82, 110, 132, 167, 192, 202, 210}, /* SGI */ | ||
113 | {0, 0, 0, 0, 48, 0, 93, 135, 176, 251, 319, 351, 381}, /* AGG */ | ||
114 | {0, 0, 0, 0, 53, 0, 102, 149, 193, 275, 348, 381, 413}, /* AGG+SGI */ | ||
225 | }; | 115 | }; |
226 | 116 | ||
227 | static s32 expected_tpt_siso40MHzSGI[IWL_RATE_COUNT] = { | 117 | static s32 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = { |
228 | 0, 0, 0, 0, 83, 83, 135, 169, 193, 229, 250, 257, 264 | 118 | {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257}, /* Norm */ |
119 | {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264}, /* SGI */ | ||
120 | {0, 0, 0, 0, 96, 0, 182, 259, 328, 451, 553, 598, 640}, /* AGG */ | ||
121 | {0, 0, 0, 0, 106, 0, 199, 282, 357, 487, 593, 640, 683}, /* AGG+SGI */ | ||
229 | }; | 122 | }; |
230 | 123 | ||
231 | static s32 expected_tpt_mimo2_40MHz[IWL_RATE_COUNT] = { | 124 | static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = { |
232 | 0, 0, 0, 0, 123, 123, 182, 214, 235, 264, 279, 285, 289 | 125 | {0, 0, 0, 0, 74, 0, 123, 155, 179, 213, 235, 243, 250}, /* Norm */ |
126 | {0, 0, 0, 0, 81, 0, 131, 164, 187, 221, 242, 250, 256}, /* SGI */ | ||
127 | {0, 0, 0, 0, 92, 0, 175, 250, 317, 436, 534, 578, 619}, /* AGG */ | ||
128 | {0, 0, 0, 0, 102, 0, 192, 273, 344, 470, 573, 619, 660}, /* AGG+SGI*/ | ||
233 | }; | 129 | }; |
234 | 130 | ||
235 | static s32 expected_tpt_mimo2_40MHzSGI[IWL_RATE_COUNT] = { | 131 | static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = { |
236 | 0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293 | 132 | {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289}, /* Norm */ |
133 | {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293}, /* SGI */ | ||
134 | {0, 0, 0, 0, 180, 0, 327, 446, 545, 708, 828, 878, 922}, /* AGG */ | ||
135 | {0, 0, 0, 0, 197, 0, 355, 481, 584, 752, 872, 922, 966}, /* AGG+SGI */ | ||
237 | }; | 136 | }; |
238 | 137 | ||
239 | /* Expected throughput metric MIMO3 */ | 138 | static s32 expected_tpt_mimo3_20MHz[4][IWL_RATE_COUNT] = { |
240 | static s32 expected_tpt_mimo3_20MHz[IWL_RATE_COUNT] = { | 139 | {0, 0, 0, 0, 99, 0, 153, 186, 208, 239, 256, 263, 268}, /* Norm */ |
241 | 0, 0, 0, 0, 99, 99, 153, 186, 208, 239, 256, 263, 268 | 140 | {0, 0, 0, 0, 106, 0, 162, 194, 215, 246, 262, 268, 273}, /* SGI */ |
141 | {0, 0, 0, 0, 134, 0, 249, 346, 431, 574, 685, 732, 775}, /* AGG */ | ||
142 | {0, 0, 0, 0, 148, 0, 272, 376, 465, 614, 727, 775, 818}, /* AGG+SGI */ | ||
242 | }; | 143 | }; |
243 | 144 | ||
244 | static s32 expected_tpt_mimo3_20MHzSGI[IWL_RATE_COUNT] = { | 145 | static s32 expected_tpt_mimo3_40MHz[4][IWL_RATE_COUNT] = { |
245 | 0, 0, 0, 0, 106, 106, 162, 194, 215, 246, 262, 268, 273 | 146 | {0, 0, 0, 0, 152, 0, 211, 239, 255, 279, 290, 294, 297}, /* Norm */ |
246 | }; | 147 | {0, 0, 0, 0, 160, 0, 219, 245, 261, 284, 294, 297, 300}, /* SGI */ |
247 | 148 | {0, 0, 0, 0, 254, 0, 443, 584, 695, 868, 984, 1030, 1070}, /* AGG */ | |
248 | static s32 expected_tpt_mimo3_40MHz[IWL_RATE_COUNT] = { | 149 | {0, 0, 0, 0, 277, 0, 478, 624, 737, 911, 1026, 1070, 1109}, /* AGG+SGI */ |
249 | 0, 0, 0, 0, 152, 152, 211, 239, 255, 279, 290, 294, 297 | ||
250 | }; | ||
251 | |||
252 | static s32 expected_tpt_mimo3_40MHzSGI[IWL_RATE_COUNT] = { | ||
253 | 0, 0, 0, 0, 160, 160, 219, 245, 261, 284, 294, 297, 300 | ||
254 | }; | 150 | }; |
255 | 151 | ||
256 | /* mbps, mcs */ | 152 | /* mbps, mcs */ |
257 | const static struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { | 153 | const static struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { |
258 | {"1", ""}, | 154 | { "1", "BPSK DSSS"}, |
259 | {"2", ""}, | 155 | { "2", "QPSK DSSS"}, |
260 | {"5.5", ""}, | 156 | {"5.5", "BPSK CCK"}, |
261 | {"11", ""}, | 157 | { "11", "QPSK CCK"}, |
262 | {"6", "BPSK 1/2"}, | 158 | { "6", "BPSK 1/2"}, |
263 | {"9", "BPSK 1/2"}, | 159 | { "9", "BPSK 1/2"}, |
264 | {"12", "QPSK 1/2"}, | 160 | { "12", "QPSK 1/2"}, |
265 | {"18", "QPSK 3/4"}, | 161 | { "18", "QPSK 3/4"}, |
266 | {"24", "16QAM 1/2"}, | 162 | { "24", "16QAM 1/2"}, |
267 | {"36", "16QAM 3/4"}, | 163 | { "36", "16QAM 3/4"}, |
268 | {"48", "64QAM 2/3"}, | 164 | { "48", "64QAM 2/3"}, |
269 | {"54", "64QAM 3/4"}, | 165 | { "54", "64QAM 3/4"}, |
270 | {"60", "64QAM 5/6"} | 166 | { "60", "64QAM 5/6"}, |
271 | }; | 167 | }; |
272 | 168 | ||
273 | #define MCS_INDEX_PER_STREAM (8) | 169 | #define MCS_INDEX_PER_STREAM (8) |
@@ -405,7 +301,7 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, | |||
405 | if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { | 301 | if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { |
406 | IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", | 302 | IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", |
407 | sta->addr, tid); | 303 | sta->addr, tid); |
408 | ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid); | 304 | ieee80211_start_tx_ba_session(sta, tid); |
409 | } | 305 | } |
410 | } | 306 | } |
411 | 307 | ||
@@ -444,7 +340,7 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags) | |||
444 | * packets. | 340 | * packets. |
445 | */ | 341 | */ |
446 | static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, | 342 | static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, |
447 | int scale_index, s32 tpt, int retries, | 343 | int scale_index, s32 tpt, int attempts, |
448 | int successes) | 344 | int successes) |
449 | { | 345 | { |
450 | struct iwl_rate_scale_data *window = NULL; | 346 | struct iwl_rate_scale_data *window = NULL; |
@@ -454,7 +350,7 @@ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, | |||
454 | if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) | 350 | if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) |
455 | return -EINVAL; | 351 | return -EINVAL; |
456 | 352 | ||
457 | /* Select data for current tx bit rate */ | 353 | /* Select window for current tx bit rate */ |
458 | window = &(windows[scale_index]); | 354 | window = &(windows[scale_index]); |
459 | 355 | ||
460 | /* | 356 | /* |
@@ -465,7 +361,7 @@ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, | |||
465 | * subtract "1" from the success counter (this is the main reason | 361 | * subtract "1" from the success counter (this is the main reason |
466 | * we keep these bitmaps!). | 362 | * we keep these bitmaps!). |
467 | */ | 363 | */ |
468 | while (retries > 0) { | 364 | while (attempts > 0) { |
469 | if (window->counter >= IWL_RATE_MAX_WINDOW) { | 365 | if (window->counter >= IWL_RATE_MAX_WINDOW) { |
470 | 366 | ||
471 | /* remove earliest */ | 367 | /* remove earliest */ |
@@ -480,17 +376,17 @@ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, | |||
480 | /* Increment frames-attempted counter */ | 376 | /* Increment frames-attempted counter */ |
481 | window->counter++; | 377 | window->counter++; |
482 | 378 | ||
483 | /* Shift bitmap by one frame (throw away oldest history), | 379 | /* Shift bitmap by one frame to throw away oldest history */ |
484 | * OR in "1", and increment "success" if this | ||
485 | * frame was successful. */ | ||
486 | window->data <<= 1; | 380 | window->data <<= 1; |
381 | |||
382 | /* Mark the most recent #successes attempts as successful */ | ||
487 | if (successes > 0) { | 383 | if (successes > 0) { |
488 | window->success_counter++; | 384 | window->success_counter++; |
489 | window->data |= 0x1; | 385 | window->data |= 0x1; |
490 | successes--; | 386 | successes--; |
491 | } | 387 | } |
492 | 388 | ||
493 | retries--; | 389 | attempts--; |
494 | } | 390 | } |
495 | 391 | ||
496 | /* Calculate current success ratio, avoid divide-by-0! */ | 392 | /* Calculate current success ratio, avoid divide-by-0! */ |
@@ -671,7 +567,7 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, | |||
671 | * there are no non-GF stations present in the BSS. | 567 | * there are no non-GF stations present in the BSS. |
672 | */ | 568 | */ |
673 | static inline u8 rs_use_green(struct ieee80211_sta *sta, | 569 | static inline u8 rs_use_green(struct ieee80211_sta *sta, |
674 | struct iwl_ht_info *ht_conf) | 570 | struct iwl_ht_config *ht_conf) |
675 | { | 571 | { |
676 | return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && | 572 | return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && |
677 | !(ht_conf->non_GF_STA_present); | 573 | !(ht_conf->non_GF_STA_present); |
@@ -821,27 +717,45 @@ out: | |||
821 | } | 717 | } |
822 | 718 | ||
823 | /* | 719 | /* |
720 | * Simple function to compare two rate scale table types | ||
721 | */ | ||
722 | static bool table_type_matches(struct iwl_scale_tbl_info *a, | ||
723 | struct iwl_scale_tbl_info *b) | ||
724 | { | ||
725 | return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) && | ||
726 | (a->is_SGI == b->is_SGI); | ||
727 | } | ||
728 | /* | ||
729 | * Static function to get the expected throughput from an iwl_scale_tbl_info | ||
730 | * that wraps a NULL pointer check | ||
731 | */ | ||
732 | static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index) | ||
733 | { | ||
734 | if (tbl->expected_tpt) | ||
735 | return tbl->expected_tpt[rs_index]; | ||
736 | return 0; | ||
737 | } | ||
738 | |||
739 | /* | ||
824 | * mac80211 sends us Tx status | 740 | * mac80211 sends us Tx status |
825 | */ | 741 | */ |
826 | static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | 742 | static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, |
827 | struct ieee80211_sta *sta, void *priv_sta, | 743 | struct ieee80211_sta *sta, void *priv_sta, |
828 | struct sk_buff *skb) | 744 | struct sk_buff *skb) |
829 | { | 745 | { |
830 | int status; | 746 | int legacy_success; |
831 | u8 retries; | 747 | int retries; |
832 | int rs_index, mac_index, index = 0; | 748 | int rs_index, mac_index, i; |
833 | struct iwl_lq_sta *lq_sta = priv_sta; | 749 | struct iwl_lq_sta *lq_sta = priv_sta; |
834 | struct iwl_link_quality_cmd *table; | 750 | struct iwl_link_quality_cmd *table; |
835 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 751 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
836 | struct iwl_priv *priv = (struct iwl_priv *)priv_r; | 752 | struct iwl_priv *priv = (struct iwl_priv *)priv_r; |
837 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 753 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
838 | struct iwl_rate_scale_data *window = NULL; | 754 | struct iwl_rate_scale_data *window = NULL; |
839 | struct iwl_rate_scale_data *search_win = NULL; | ||
840 | enum mac80211_rate_control_flags mac_flags; | 755 | enum mac80211_rate_control_flags mac_flags; |
841 | u32 tx_rate; | 756 | u32 tx_rate; |
842 | struct iwl_scale_tbl_info tbl_type; | 757 | struct iwl_scale_tbl_info tbl_type; |
843 | struct iwl_scale_tbl_info *curr_tbl, *search_tbl; | 758 | struct iwl_scale_tbl_info *curr_tbl, *other_tbl; |
844 | u8 active_index = 0; | ||
845 | s32 tpt = 0; | 759 | s32 tpt = 0; |
846 | 760 | ||
847 | IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); | 761 | IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); |
@@ -850,30 +764,14 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
850 | info->flags & IEEE80211_TX_CTL_NO_ACK) | 764 | info->flags & IEEE80211_TX_CTL_NO_ACK) |
851 | return; | 765 | return; |
852 | 766 | ||
853 | /* This packet was aggregated but doesn't carry rate scale info */ | 767 | /* This packet was aggregated but doesn't carry status info */ |
854 | if ((info->flags & IEEE80211_TX_CTL_AMPDU) && | 768 | if ((info->flags & IEEE80211_TX_CTL_AMPDU) && |
855 | !(info->flags & IEEE80211_TX_STAT_AMPDU)) | 769 | !(info->flags & IEEE80211_TX_STAT_AMPDU)) |
856 | return; | 770 | return; |
857 | 771 | ||
858 | if (info->flags & IEEE80211_TX_STAT_AMPDU) | ||
859 | retries = 0; | ||
860 | else | ||
861 | retries = info->status.rates[0].count - 1; | ||
862 | |||
863 | if (retries > 15) | ||
864 | retries = 15; | ||
865 | |||
866 | if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && | 772 | if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && |
867 | !lq_sta->ibss_sta_added) | 773 | !lq_sta->ibss_sta_added) |
868 | goto out; | 774 | return; |
869 | |||
870 | table = &lq_sta->lq; | ||
871 | active_index = lq_sta->active_tbl; | ||
872 | |||
873 | curr_tbl = &(lq_sta->lq_info[active_index]); | ||
874 | search_tbl = &(lq_sta->lq_info[(1 - active_index)]); | ||
875 | window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]); | ||
876 | search_win = (struct iwl_rate_scale_data *)&(search_tbl->win[0]); | ||
877 | 775 | ||
878 | /* | 776 | /* |
879 | * Ignore this Tx frame response if its initial rate doesn't match | 777 | * Ignore this Tx frame response if its initial rate doesn't match |
@@ -883,6 +781,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
883 | * to check "search" mode, or a prior "search" mode after we've moved | 781 | * to check "search" mode, or a prior "search" mode after we've moved |
884 | * to a new "search" mode (which might become the new "active" mode). | 782 | * to a new "search" mode (which might become the new "active" mode). |
885 | */ | 783 | */ |
784 | table = &lq_sta->lq; | ||
886 | tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); | 785 | tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); |
887 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index); | 786 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index); |
888 | if (priv->band == IEEE80211_BAND_5GHZ) | 787 | if (priv->band == IEEE80211_BAND_5GHZ) |
@@ -901,7 +800,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
901 | if (priv->band == IEEE80211_BAND_2GHZ) | 800 | if (priv->band == IEEE80211_BAND_2GHZ) |
902 | mac_index += IWL_FIRST_OFDM_RATE; | 801 | mac_index += IWL_FIRST_OFDM_RATE; |
903 | } | 802 | } |
904 | 803 | /* Here we actually compare this rate to the latest LQ command */ | |
905 | if ((mac_index < 0) || | 804 | if ((mac_index < 0) || |
906 | (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) || | 805 | (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) || |
907 | (tbl_type.is_ht40 != !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) || | 806 | (tbl_type.is_ht40 != !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) || |
@@ -911,124 +810,106 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, | |||
911 | (!!(tx_rate & RATE_MCS_GF_MSK) != !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) || | 810 | (!!(tx_rate & RATE_MCS_GF_MSK) != !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) || |
912 | (rs_index != mac_index)) { | 811 | (rs_index != mac_index)) { |
913 | IWL_DEBUG_RATE(priv, "initial rate %d does not match %d (0x%x)\n", mac_index, rs_index, tx_rate); | 812 | IWL_DEBUG_RATE(priv, "initial rate %d does not match %d (0x%x)\n", mac_index, rs_index, tx_rate); |
914 | /* the last LQ command could failed so the LQ in ucode not | 813 | /* |
915 | * the same in driver sync up | 814 | * Since rates mis-match, the last LQ command may have failed. |
815 | * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with | ||
816 | * ... driver. | ||
916 | */ | 817 | */ |
917 | lq_sta->missed_rate_counter++; | 818 | lq_sta->missed_rate_counter++; |
918 | if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { | 819 | if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { |
919 | lq_sta->missed_rate_counter = 0; | 820 | lq_sta->missed_rate_counter = 0; |
920 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); | 821 | iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); |
921 | } | 822 | } |
922 | goto out; | 823 | /* Regardless, ignore this status info for outdated rate */ |
824 | return; | ||
825 | } else | ||
826 | /* Rate did match, so reset the missed_rate_counter */ | ||
827 | lq_sta->missed_rate_counter = 0; | ||
828 | |||
829 | /* Figure out if rate scale algorithm is in active or search table */ | ||
830 | if (table_type_matches(&tbl_type, | ||
831 | &(lq_sta->lq_info[lq_sta->active_tbl]))) { | ||
832 | curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); | ||
833 | other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); | ||
834 | } else if (table_type_matches(&tbl_type, | ||
835 | &lq_sta->lq_info[1 - lq_sta->active_tbl])) { | ||
836 | curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); | ||
837 | other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); | ||
838 | } else { | ||
839 | IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n"); | ||
840 | return; | ||
923 | } | 841 | } |
842 | window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]); | ||
924 | 843 | ||
925 | lq_sta->missed_rate_counter = 0; | 844 | /* |
926 | /* Update frame history window with "failure" for each Tx retry. */ | 845 | * Updating the frame history depends on whether packets were |
927 | while (retries) { | 846 | * aggregated. |
928 | /* Look up the rate and other info used for each tx attempt. | 847 | * |
929 | * Each tx attempt steps one entry deeper in the rate table. */ | 848 | * For aggregation, all packets were transmitted at the same rate, the |
930 | tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags); | 849 | * first index into rate scale table. |
931 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, | 850 | */ |
932 | &tbl_type, &rs_index); | 851 | if (info->flags & IEEE80211_TX_STAT_AMPDU) { |
933 | 852 | tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags); | |
934 | /* If type matches "search" table, | 853 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, |
935 | * add failure to "search" history */ | 854 | &rs_index); |
936 | if ((tbl_type.lq_type == search_tbl->lq_type) && | 855 | tpt = get_expected_tpt(curr_tbl, rs_index); |
937 | (tbl_type.ant_type == search_tbl->ant_type) && | 856 | rs_collect_tx_data(window, rs_index, tpt, |
938 | (tbl_type.is_SGI == search_tbl->is_SGI)) { | 857 | info->status.ampdu_ack_len, |
939 | if (search_tbl->expected_tpt) | 858 | info->status.ampdu_ack_map); |
940 | tpt = search_tbl->expected_tpt[rs_index]; | 859 | |
941 | else | 860 | /* Update success/fail counts if not searching for new mode */ |
942 | tpt = 0; | 861 | if (lq_sta->stay_in_tbl) { |
943 | rs_collect_tx_data(search_win, rs_index, tpt, 1, 0); | 862 | lq_sta->total_success += info->status.ampdu_ack_map; |
944 | 863 | lq_sta->total_failed += (info->status.ampdu_ack_len - | |
945 | /* Else if type matches "current/active" table, | 864 | info->status.ampdu_ack_map); |
946 | * add failure to "current/active" history */ | ||
947 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && | ||
948 | (tbl_type.ant_type == curr_tbl->ant_type) && | ||
949 | (tbl_type.is_SGI == curr_tbl->is_SGI)) { | ||
950 | if (curr_tbl->expected_tpt) | ||
951 | tpt = curr_tbl->expected_tpt[rs_index]; | ||
952 | else | ||
953 | tpt = 0; | ||
954 | rs_collect_tx_data(window, rs_index, tpt, 1, 0); | ||
955 | } | 865 | } |
956 | 866 | } else { | |
957 | /* If not searching for a new mode, increment failed counter | ||
958 | * ... this helps determine when to start searching again */ | ||
959 | if (lq_sta->stay_in_tbl) | ||
960 | lq_sta->total_failed++; | ||
961 | --retries; | ||
962 | index++; | ||
963 | |||
964 | } | ||
965 | |||
966 | /* | 867 | /* |
967 | * Find (by rate) the history window to update with final Tx attempt; | 868 | * For legacy, update frame history with for each Tx retry. |
968 | * if Tx was successful first try, use original rate, | ||
969 | * else look up the rate that was, finally, successful. | ||
970 | */ | 869 | */ |
971 | tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags); | 870 | retries = info->status.rates[0].count - 1; |
972 | lq_sta->last_rate_n_flags = tx_rate; | 871 | /* HW doesn't send more than 15 retries */ |
973 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index); | 872 | retries = min(retries, 15); |
974 | 873 | ||
975 | /* Update frame history window with "success" if Tx got ACKed ... */ | 874 | /* The last transmission may have been successful */ |
976 | status = !!(info->flags & IEEE80211_TX_STAT_ACK); | 875 | legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK); |
977 | 876 | /* Collect data for each rate used during failed TX attempts */ | |
978 | /* If type matches "search" table, | 877 | for (i = 0; i <= retries; ++i) { |
979 | * add final tx status to "search" history */ | 878 | tx_rate = le32_to_cpu(table->rs_table[i].rate_n_flags); |
980 | if ((tbl_type.lq_type == search_tbl->lq_type) && | 879 | rs_get_tbl_info_from_mcs(tx_rate, priv->band, |
981 | (tbl_type.ant_type == search_tbl->ant_type) && | 880 | &tbl_type, &rs_index); |
982 | (tbl_type.is_SGI == search_tbl->is_SGI)) { | 881 | /* |
983 | if (search_tbl->expected_tpt) | 882 | * Only collect stats if retried rate is in the same RS |
984 | tpt = search_tbl->expected_tpt[rs_index]; | 883 | * table as active/search. |
985 | else | 884 | */ |
986 | tpt = 0; | 885 | if (table_type_matches(&tbl_type, curr_tbl)) |
987 | if (info->flags & IEEE80211_TX_STAT_AMPDU) | 886 | tpt = get_expected_tpt(curr_tbl, rs_index); |
988 | rs_collect_tx_data(search_win, rs_index, tpt, | 887 | else if (table_type_matches(&tbl_type, other_tbl)) |
989 | info->status.ampdu_ack_len, | 888 | tpt = get_expected_tpt(other_tbl, rs_index); |
990 | info->status.ampdu_ack_map); | 889 | else |
991 | else | 890 | continue; |
992 | rs_collect_tx_data(search_win, rs_index, tpt, | ||
993 | 1, status); | ||
994 | /* Else if type matches "current/active" table, | ||
995 | * add final tx status to "current/active" history */ | ||
996 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && | ||
997 | (tbl_type.ant_type == curr_tbl->ant_type) && | ||
998 | (tbl_type.is_SGI == curr_tbl->is_SGI)) { | ||
999 | if (curr_tbl->expected_tpt) | ||
1000 | tpt = curr_tbl->expected_tpt[rs_index]; | ||
1001 | else | ||
1002 | tpt = 0; | ||
1003 | if (info->flags & IEEE80211_TX_STAT_AMPDU) | ||
1004 | rs_collect_tx_data(window, rs_index, tpt, | ||
1005 | info->status.ampdu_ack_len, | ||
1006 | info->status.ampdu_ack_map); | ||
1007 | else | ||
1008 | rs_collect_tx_data(window, rs_index, tpt, | ||
1009 | 1, status); | ||
1010 | } | ||
1011 | 891 | ||
1012 | /* If not searching for new mode, increment success/failed counter | 892 | /* Constants mean 1 transmission, 0 successes */ |
1013 | * ... these help determine when to start searching again */ | 893 | if (i < retries) |
1014 | if (lq_sta->stay_in_tbl) { | 894 | rs_collect_tx_data(window, rs_index, tpt, 1, |
1015 | if (info->flags & IEEE80211_TX_STAT_AMPDU) { | 895 | 0); |
1016 | lq_sta->total_success += info->status.ampdu_ack_map; | ||
1017 | lq_sta->total_failed += | ||
1018 | (info->status.ampdu_ack_len - info->status.ampdu_ack_map); | ||
1019 | } else { | ||
1020 | if (status) | ||
1021 | lq_sta->total_success++; | ||
1022 | else | 896 | else |
1023 | lq_sta->total_failed++; | 897 | rs_collect_tx_data(window, rs_index, tpt, 1, |
898 | legacy_success); | ||
899 | } | ||
900 | |||
901 | /* Update success/fail counts if not searching for new mode */ | ||
902 | if (lq_sta->stay_in_tbl) { | ||
903 | lq_sta->total_success += legacy_success; | ||
904 | lq_sta->total_failed += retries + (1 - legacy_success); | ||
1024 | } | 905 | } |
1025 | } | 906 | } |
907 | /* The last TX rate is cached in lq_sta; it's set in if/else above */ | ||
908 | lq_sta->last_rate_n_flags = tx_rate; | ||
1026 | 909 | ||
1027 | /* See if there's a better rate or modulation mode to try. */ | 910 | /* See if there's a better rate or modulation mode to try. */ |
1028 | if (sta && sta->supp_rates[sband->band]) | 911 | if (sta && sta->supp_rates[sband->band]) |
1029 | rs_rate_scale_perform(priv, skb, sta, lq_sta); | 912 | rs_rate_scale_perform(priv, skb, sta, lq_sta); |
1030 | out: | ||
1031 | return; | ||
1032 | } | 913 | } |
1033 | 914 | ||
1034 | /* | 915 | /* |
@@ -1066,43 +947,45 @@ static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy, | |||
1066 | static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta, | 947 | static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta, |
1067 | struct iwl_scale_tbl_info *tbl) | 948 | struct iwl_scale_tbl_info *tbl) |
1068 | { | 949 | { |
950 | /* Used to choose among HT tables */ | ||
951 | s32 (*ht_tbl_pointer)[IWL_RATE_COUNT]; | ||
952 | |||
953 | /* Check for invalid LQ type */ | ||
954 | if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_Ht(tbl->lq_type))) { | ||
955 | tbl->expected_tpt = expected_tpt_legacy; | ||
956 | return; | ||
957 | } | ||
958 | |||
959 | /* Legacy rates have only one table */ | ||
1069 | if (is_legacy(tbl->lq_type)) { | 960 | if (is_legacy(tbl->lq_type)) { |
1070 | if (!is_a_band(tbl->lq_type)) | 961 | tbl->expected_tpt = expected_tpt_legacy; |
1071 | tbl->expected_tpt = expected_tpt_G; | 962 | return; |
1072 | else | 963 | } |
1073 | tbl->expected_tpt = expected_tpt_A; | 964 | |
1074 | } else if (is_siso(tbl->lq_type)) { | 965 | /* Choose among many HT tables depending on number of streams |
1075 | if (tbl->is_ht40 && !lq_sta->is_dup) | 966 | * (SISO/MIMO2/MIMO3), channel width (20/40), SGI, and aggregation |
1076 | if (tbl->is_SGI) | 967 | * status */ |
1077 | tbl->expected_tpt = expected_tpt_siso40MHzSGI; | 968 | if (is_siso(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup)) |
1078 | else | 969 | ht_tbl_pointer = expected_tpt_siso20MHz; |
1079 | tbl->expected_tpt = expected_tpt_siso40MHz; | 970 | else if (is_siso(tbl->lq_type)) |
1080 | else if (tbl->is_SGI) | 971 | ht_tbl_pointer = expected_tpt_siso40MHz; |
1081 | tbl->expected_tpt = expected_tpt_siso20MHzSGI; | 972 | else if (is_mimo2(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup)) |
1082 | else | 973 | ht_tbl_pointer = expected_tpt_mimo2_20MHz; |
1083 | tbl->expected_tpt = expected_tpt_siso20MHz; | 974 | else if (is_mimo2(tbl->lq_type)) |
1084 | } else if (is_mimo2(tbl->lq_type)) { | 975 | ht_tbl_pointer = expected_tpt_mimo2_40MHz; |
1085 | if (tbl->is_ht40 && !lq_sta->is_dup) | 976 | else if (is_mimo3(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup)) |
1086 | if (tbl->is_SGI) | 977 | ht_tbl_pointer = expected_tpt_mimo3_20MHz; |
1087 | tbl->expected_tpt = expected_tpt_mimo2_40MHzSGI; | 978 | else /* if (is_mimo3(tbl->lq_type)) <-- must be true */ |
1088 | else | 979 | ht_tbl_pointer = expected_tpt_mimo3_40MHz; |
1089 | tbl->expected_tpt = expected_tpt_mimo2_40MHz; | 980 | |
1090 | else if (tbl->is_SGI) | 981 | if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */ |
1091 | tbl->expected_tpt = expected_tpt_mimo2_20MHzSGI; | 982 | tbl->expected_tpt = ht_tbl_pointer[0]; |
1092 | else | 983 | else if (tbl->is_SGI && !lq_sta->is_agg) /* SGI */ |
1093 | tbl->expected_tpt = expected_tpt_mimo2_20MHz; | 984 | tbl->expected_tpt = ht_tbl_pointer[1]; |
1094 | } else if (is_mimo3(tbl->lq_type)) { | 985 | else if (!tbl->is_SGI && lq_sta->is_agg) /* AGG */ |
1095 | if (tbl->is_ht40 && !lq_sta->is_dup) | 986 | tbl->expected_tpt = ht_tbl_pointer[2]; |
1096 | if (tbl->is_SGI) | 987 | else /* AGG+SGI */ |
1097 | tbl->expected_tpt = expected_tpt_mimo3_40MHzSGI; | 988 | tbl->expected_tpt = ht_tbl_pointer[3]; |
1098 | else | ||
1099 | tbl->expected_tpt = expected_tpt_mimo3_40MHz; | ||
1100 | else if (tbl->is_SGI) | ||
1101 | tbl->expected_tpt = expected_tpt_mimo3_20MHzSGI; | ||
1102 | else | ||
1103 | tbl->expected_tpt = expected_tpt_mimo3_20MHz; | ||
1104 | } else | ||
1105 | tbl->expected_tpt = expected_tpt_G; | ||
1106 | } | 989 | } |
1107 | 990 | ||
1108 | /* | 991 | /* |
@@ -2077,6 +1960,14 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2077 | lq_sta->supp_rates = sta->supp_rates[lq_sta->band]; | 1960 | lq_sta->supp_rates = sta->supp_rates[lq_sta->band]; |
2078 | 1961 | ||
2079 | tid = rs_tl_add_packet(lq_sta, hdr); | 1962 | tid = rs_tl_add_packet(lq_sta, hdr); |
1963 | if ((tid != MAX_TID_COUNT) && (lq_sta->tx_agg_tid_en & (1 << tid))) { | ||
1964 | tid_data = &priv->stations[lq_sta->lq.sta_id].tid[tid]; | ||
1965 | if (tid_data->agg.state == IWL_AGG_OFF) | ||
1966 | lq_sta->is_agg = 0; | ||
1967 | else | ||
1968 | lq_sta->is_agg = 1; | ||
1969 | } else | ||
1970 | lq_sta->is_agg = 0; | ||
2080 | 1971 | ||
2081 | /* | 1972 | /* |
2082 | * Select rate-scale / modulation-mode table to work with in | 1973 | * Select rate-scale / modulation-mode table to work with in |
@@ -2177,10 +2068,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2177 | 2068 | ||
2178 | goto out; | 2069 | goto out; |
2179 | } | 2070 | } |
2180 | |||
2181 | /* Else we have enough samples; calculate estimate of | 2071 | /* Else we have enough samples; calculate estimate of |
2182 | * actual average throughput */ | 2072 | * actual average throughput */ |
2183 | 2073 | ||
2074 | /* Sanity-check TPT calculations */ | ||
2184 | BUG_ON(window->average_tpt != ((window->success_ratio * | 2075 | BUG_ON(window->average_tpt != ((window->success_ratio * |
2185 | tbl->expected_tpt[index] + 64) / 128)); | 2076 | tbl->expected_tpt[index] + 64) / 128)); |
2186 | 2077 | ||
@@ -2584,22 +2475,13 @@ static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, | |||
2584 | gfp_t gfp) | 2475 | gfp_t gfp) |
2585 | { | 2476 | { |
2586 | struct iwl_lq_sta *lq_sta; | 2477 | struct iwl_lq_sta *lq_sta; |
2478 | struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv; | ||
2587 | struct iwl_priv *priv; | 2479 | struct iwl_priv *priv; |
2588 | int i, j; | ||
2589 | 2480 | ||
2590 | priv = (struct iwl_priv *)priv_rate; | 2481 | priv = (struct iwl_priv *)priv_rate; |
2591 | IWL_DEBUG_RATE(priv, "create station rate scale window\n"); | 2482 | IWL_DEBUG_RATE(priv, "create station rate scale window\n"); |
2592 | 2483 | ||
2593 | lq_sta = kzalloc(sizeof(struct iwl_lq_sta), gfp); | 2484 | lq_sta = &sta_priv->lq_sta; |
2594 | |||
2595 | if (lq_sta == NULL) | ||
2596 | return NULL; | ||
2597 | lq_sta->lq.sta_id = 0xff; | ||
2598 | |||
2599 | |||
2600 | for (j = 0; j < LQ_SIZE; j++) | ||
2601 | for (i = 0; i < IWL_RATE_COUNT; i++) | ||
2602 | rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); | ||
2603 | 2485 | ||
2604 | return lq_sta; | 2486 | return lq_sta; |
2605 | } | 2487 | } |
@@ -2613,6 +2495,12 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, | |||
2613 | struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; | 2495 | struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; |
2614 | struct iwl_lq_sta *lq_sta = priv_sta; | 2496 | struct iwl_lq_sta *lq_sta = priv_sta; |
2615 | 2497 | ||
2498 | lq_sta->lq.sta_id = 0xff; | ||
2499 | |||
2500 | for (j = 0; j < LQ_SIZE; j++) | ||
2501 | for (i = 0; i < IWL_RATE_COUNT; i++) | ||
2502 | rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); | ||
2503 | |||
2616 | lq_sta->flush_timer = 0; | 2504 | lq_sta->flush_timer = 0; |
2617 | lq_sta->supp_rates = sta->supp_rates[sband->band]; | 2505 | lq_sta->supp_rates = sta->supp_rates[sband->band]; |
2618 | for (j = 0; j < LQ_SIZE; j++) | 2506 | for (j = 0; j < LQ_SIZE; j++) |
@@ -2690,6 +2578,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, | |||
2690 | lq_sta->last_txrate_idx = rate_lowest_index(sband, sta); | 2578 | lq_sta->last_txrate_idx = rate_lowest_index(sband, sta); |
2691 | if (sband->band == IEEE80211_BAND_5GHZ) | 2579 | if (sband->band == IEEE80211_BAND_5GHZ) |
2692 | lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; | 2580 | lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; |
2581 | lq_sta->is_agg = 0; | ||
2693 | 2582 | ||
2694 | rs_initialize_lq(priv, conf, sta, lq_sta); | 2583 | rs_initialize_lq(priv, conf, sta, lq_sta); |
2695 | } | 2584 | } |
@@ -2808,7 +2697,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, | |||
2808 | repeat_rate--; | 2697 | repeat_rate--; |
2809 | } | 2698 | } |
2810 | 2699 | ||
2811 | lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_MAX; | 2700 | lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; |
2812 | lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; | 2701 | lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; |
2813 | lq_cmd->agg_params.agg_time_limit = | 2702 | lq_cmd->agg_params.agg_time_limit = |
2814 | cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); | 2703 | cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); |
@@ -2827,11 +2716,9 @@ static void rs_free(void *priv_rate) | |||
2827 | static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta, | 2716 | static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta, |
2828 | void *priv_sta) | 2717 | void *priv_sta) |
2829 | { | 2718 | { |
2830 | struct iwl_lq_sta *lq_sta = priv_sta; | ||
2831 | struct iwl_priv *priv __maybe_unused = priv_r; | 2719 | struct iwl_priv *priv __maybe_unused = priv_r; |
2832 | 2720 | ||
2833 | IWL_DEBUG_RATE(priv, "enter\n"); | 2721 | IWL_DEBUG_RATE(priv, "enter\n"); |
2834 | kfree(lq_sta); | ||
2835 | IWL_DEBUG_RATE(priv, "leave\n"); | 2722 | IWL_DEBUG_RATE(priv, "leave\n"); |
2836 | } | 2723 | } |
2837 | 2724 | ||
@@ -2942,8 +2829,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, | |||
2942 | ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3")); | 2829 | ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3")); |
2943 | desc += sprintf(buff+desc, " %s", | 2830 | desc += sprintf(buff+desc, " %s", |
2944 | (tbl->is_ht40) ? "40MHz" : "20MHz"); | 2831 | (tbl->is_ht40) ? "40MHz" : "20MHz"); |
2945 | desc += sprintf(buff+desc, " %s %s\n", (tbl->is_SGI) ? "SGI" : "", | 2832 | desc += sprintf(buff+desc, " %s %s %s\n", (tbl->is_SGI) ? "SGI" : "", |
2946 | (lq_sta->is_green) ? "GF enabled" : ""); | 2833 | (lq_sta->is_green) ? "GF enabled" : "", |
2834 | (lq_sta->is_agg) ? "AGG on" : ""); | ||
2947 | } | 2835 | } |
2948 | desc += sprintf(buff+desc, "last tx rate=0x%X\n", | 2836 | desc += sprintf(buff+desc, "last tx rate=0x%X\n", |
2949 | lq_sta->last_rate_n_flags); | 2837 | lq_sta->last_rate_n_flags); |
@@ -3076,16 +2964,16 @@ static void rs_add_debugfs(void *priv, void *priv_sta, | |||
3076 | { | 2964 | { |
3077 | struct iwl_lq_sta *lq_sta = priv_sta; | 2965 | struct iwl_lq_sta *lq_sta = priv_sta; |
3078 | lq_sta->rs_sta_dbgfs_scale_table_file = | 2966 | lq_sta->rs_sta_dbgfs_scale_table_file = |
3079 | debugfs_create_file("rate_scale_table", 0600, dir, | 2967 | debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir, |
3080 | lq_sta, &rs_sta_dbgfs_scale_table_ops); | 2968 | lq_sta, &rs_sta_dbgfs_scale_table_ops); |
3081 | lq_sta->rs_sta_dbgfs_stats_table_file = | 2969 | lq_sta->rs_sta_dbgfs_stats_table_file = |
3082 | debugfs_create_file("rate_stats_table", 0600, dir, | 2970 | debugfs_create_file("rate_stats_table", S_IRUSR, dir, |
3083 | lq_sta, &rs_sta_dbgfs_stats_table_ops); | 2971 | lq_sta, &rs_sta_dbgfs_stats_table_ops); |
3084 | lq_sta->rs_sta_dbgfs_rate_scale_data_file = | 2972 | lq_sta->rs_sta_dbgfs_rate_scale_data_file = |
3085 | debugfs_create_file("rate_scale_data", 0600, dir, | 2973 | debugfs_create_file("rate_scale_data", S_IRUSR, dir, |
3086 | lq_sta, &rs_sta_dbgfs_rate_scale_data_ops); | 2974 | lq_sta, &rs_sta_dbgfs_rate_scale_data_ops); |
3087 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = | 2975 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = |
3088 | debugfs_create_u8("tx_agg_tid_enable", 0600, dir, | 2976 | debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir, |
3089 | &lq_sta->tx_agg_tid_en); | 2977 | &lq_sta->tx_agg_tid_en); |
3090 | 2978 | ||
3091 | } | 2979 | } |