[PATCH] iwlwifi: add supp_rates to rate scale sta private data
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl-4965-rs.c
1 /******************************************************************************
2 *
3 * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 *****************************************************************************/
26 #include <linux/kernel.h>
27 #include <linux/init.h>
28 #include <linux/skbuff.h>
29 #include <linux/wireless.h>
30 #include <net/mac80211.h>
31 #include <net/ieee80211.h>
32
33 #include <linux/netdevice.h>
34 #include <linux/etherdevice.h>
35 #include <linux/delay.h>
36
37 #include <linux/workqueue.h>
38
39 #include <net/mac80211.h>
40 #include <linux/wireless.h>
41
42 #define IWL 4965
43
44 #include "../net/mac80211/ieee80211_rate.h"
45
46 #include "iwlwifi.h"
47 #include "iwl-helpers.h"
48
49 #define RS_NAME "iwl-4965-rs"
50
51 #define NUM_TRY_BEFORE_ANTENNA_TOGGLE 1
52 #define IWL_NUMBER_TRY 1
53 #define IWL_HT_NUMBER_TRY 3
54
55 #define IWL_RATE_MAX_WINDOW 62
56 #define IWL_RATE_HIGH_TH 10880
57 #define IWL_RATE_MIN_FAILURE_TH 6
58 #define IWL_RATE_MIN_SUCCESS_TH 8
59 #define IWL_RATE_DECREASE_TH 1920
60 #define IWL_RATE_INCREASE_TH 8960
61 #define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ) /*2 seconds */
62
63 static u8 rs_ht_to_legacy[] = {
64 IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
65 IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
66 IWL_RATE_6M_INDEX,
67 IWL_RATE_6M_INDEX, IWL_RATE_9M_INDEX,
68 IWL_RATE_12M_INDEX, IWL_RATE_18M_INDEX,
69 IWL_RATE_24M_INDEX, IWL_RATE_36M_INDEX,
70 IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX
71 };
72
73 struct iwl_rate {
74 u32 rate_n_flags;
75 } __attribute__ ((packed));
76
77 struct iwl_rate_scale_data {
78 u64 data;
79 s32 success_counter;
80 s32 success_ratio;
81 s32 counter;
82 s32 average_tpt;
83 unsigned long stamp;
84 };
85
86 struct iwl_scale_tbl_info {
87 enum iwl_table_type lq_type;
88 enum iwl_antenna_type antenna_type;
89 u8 is_SGI;
90 u8 is_fat;
91 u8 is_dup;
92 u8 action;
93 s32 *expected_tpt;
94 struct iwl_rate current_rate;
95 struct iwl_rate_scale_data win[IWL_RATE_COUNT];
96 };
97
98 struct iwl_rate_scale_priv {
99 u8 active_tbl;
100 u8 enable_counter;
101 u8 stay_in_tbl;
102 u8 search_better_tbl;
103 s32 last_tpt;
104 u32 table_count_limit;
105 u32 max_failure_limit;
106 u32 max_success_limit;
107 u32 table_count;
108 u32 total_failed;
109 u32 total_success;
110 u32 flush_timer;
111 u8 action_counter;
112 u8 antenna;
113 u8 valid_antenna;
114 u8 is_green;
115 u8 is_dup;
116 u8 phymode;
117 u8 ibss_sta_added;
118 u32 supp_rates;
119 u16 active_rate;
120 u16 active_siso_rate;
121 u16 active_mimo_rate;
122 u16 active_rate_basic;
123 struct iwl_link_quality_cmd lq;
124 struct iwl_scale_tbl_info lq_info[LQ_SIZE];
125 #ifdef CONFIG_MAC80211_DEBUGFS
126 struct dentry *rs_sta_dbgfs_scale_table_file;
127 #endif
128 };
129
130 static void rs_rate_scale_perform(struct iwl_priv *priv,
131 struct net_device *dev,
132 struct ieee80211_hdr *hdr,
133 struct sta_info *sta);
134 static int rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
135 struct iwl_rate *tx_mcs,
136 struct iwl_link_quality_cmd *tbl);
137
138
139 static s32 expected_tpt_A[IWL_RATE_COUNT] = {
140 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186
141 };
142
143 static s32 expected_tpt_G[IWL_RATE_COUNT] = {
144 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 186
145 };
146
147 static s32 expected_tpt_siso20MHz[IWL_RATE_COUNT] = {
148 0, 0, 0, 0, 42, 42, 76, 102, 124, 159, 183, 193, 202
149 };
150
151 static s32 expected_tpt_siso20MHzSGI[IWL_RATE_COUNT] = {
152 0, 0, 0, 0, 46, 46, 82, 110, 132, 168, 192, 202, 211
153 };
154
155 static s32 expected_tpt_mimo20MHz[IWL_RATE_COUNT] = {
156 0, 0, 0, 0, 74, 74, 123, 155, 179, 214, 236, 244, 251
157 };
158
159 static s32 expected_tpt_mimo20MHzSGI[IWL_RATE_COUNT] = {
160 0, 0, 0, 0, 81, 81, 131, 164, 188, 222, 243, 251, 257
161 };
162
163 static s32 expected_tpt_siso40MHz[IWL_RATE_COUNT] = {
164 0, 0, 0, 0, 77, 77, 127, 160, 184, 220, 242, 250, 257
165 };
166
167 static s32 expected_tpt_siso40MHzSGI[IWL_RATE_COUNT] = {
168 0, 0, 0, 0, 83, 83, 135, 169, 193, 229, 250, 257, 264
169 };
170
171 static s32 expected_tpt_mimo40MHz[IWL_RATE_COUNT] = {
172 0, 0, 0, 0, 123, 123, 182, 214, 235, 264, 279, 285, 289
173 };
174
175 static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = {
176 0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293
177 };
178
179 static int iwl_lq_sync_callback(struct iwl_priv *priv,
180 struct iwl_cmd *cmd, struct sk_buff *skb)
181 {
182 /*We didn't cache the SKB; let the caller free it */
183 return 1;
184 }
185
186 static inline u8 iwl_rate_get_rate(u32 rate_n_flags)
187 {
188 return (u8)(rate_n_flags & 0xFF);
189 }
190
191 static int rs_send_lq_cmd(struct iwl_priv *priv,
192 struct iwl_link_quality_cmd *lq, u8 flags)
193 {
194 #ifdef CONFIG_IWLWIFI_DEBUG
195 int i;
196 #endif
197 int rc = -1;
198
199 struct iwl_host_cmd cmd = {
200 .id = REPLY_TX_LINK_QUALITY_CMD,
201 .len = sizeof(struct iwl_link_quality_cmd),
202 .meta.flags = flags,
203 .data = lq,
204 };
205
206 if ((lq->sta_id == 0xFF) &&
207 (priv->iw_mode == IEEE80211_IF_TYPE_IBSS))
208 return rc;
209
210 if (lq->sta_id == 0xFF)
211 lq->sta_id = IWL_AP_ID;
212
213 IWL_DEBUG_RATE("lq station id 0x%x\n", lq->sta_id);
214 IWL_DEBUG_RATE("lq dta 0x%X 0x%X\n",
215 lq->general_params.single_stream_ant_msk,
216 lq->general_params.dual_stream_ant_msk);
217 #ifdef CONFIG_IWLWIFI_DEBUG
218 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
219 IWL_DEBUG_RATE("lq index %d 0x%X\n",
220 i, lq->rs_table[i].rate_n_flags);
221 #endif
222
223 if (flags & CMD_ASYNC)
224 cmd.meta.u.callback = iwl_lq_sync_callback;
225
226 if (iwl_is_associated(priv) && priv->assoc_station_added &&
227 priv->lq_mngr.lq_ready)
228 rc = iwl_send_cmd(priv, &cmd);
229
230 return rc;
231 }
232
233 static int rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
234 {
235 window->data = 0;
236 window->success_counter = 0;
237 window->success_ratio = IWL_INVALID_VALUE;
238 window->counter = 0;
239 window->average_tpt = IWL_INVALID_VALUE;
240 window->stamp = 0;
241
242 return 0;
243 }
244
245 static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
246 int scale_index, s32 tpt, u32 status)
247 {
248 int rc = 0;
249 struct iwl_rate_scale_data *window = NULL;
250 u64 mask;
251 u8 win_size = IWL_RATE_MAX_WINDOW;
252 s32 fail_count;
253
254 if (scale_index < 0)
255 return -1;
256
257 if (scale_index >= IWL_RATE_COUNT)
258 return -1;
259
260 window = &(windows[scale_index]);
261
262 if (window->counter >= win_size) {
263
264 window->counter = win_size - 1;
265 mask = 1;
266 mask = (mask << (win_size - 1));
267 if ((window->data & mask)) {
268 window->data &= ~mask;
269 window->success_counter = window->success_counter - 1;
270 }
271 }
272
273 window->counter = window->counter + 1;
274 mask = window->data;
275 window->data = (mask << 1);
276 if (status != 0) {
277 window->success_counter = window->success_counter + 1;
278 window->data |= 0x1;
279 }
280
281 if (window->counter > 0)
282 window->success_ratio = 128 * (100 * window->success_counter)
283 / window->counter;
284 else
285 window->success_ratio = IWL_INVALID_VALUE;
286
287 fail_count = window->counter - window->success_counter;
288
289 if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||
290 (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))
291 window->average_tpt = (window->success_ratio * tpt + 64) / 128;
292 else
293 window->average_tpt = IWL_INVALID_VALUE;
294
295 window->stamp = jiffies;
296
297 return rc;
298 }
299
300 int static rs_mcs_from_tbl(struct iwl_rate *mcs_rate,
301 struct iwl_scale_tbl_info *tbl,
302 int index, u8 use_green)
303 {
304 int rc = 0;
305
306 if (is_legacy(tbl->lq_type)) {
307 mcs_rate->rate_n_flags = iwl_rates[index].plcp;
308 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
309 mcs_rate->rate_n_flags |= RATE_MCS_CCK_MSK;
310
311 } else if (is_siso(tbl->lq_type)) {
312 if (index > IWL_LAST_OFDM_RATE)
313 index = IWL_LAST_OFDM_RATE;
314 mcs_rate->rate_n_flags = iwl_rates[index].plcp_siso |
315 RATE_MCS_HT_MSK;
316 } else {
317 if (index > IWL_LAST_OFDM_RATE)
318 index = IWL_LAST_OFDM_RATE;
319 mcs_rate->rate_n_flags = iwl_rates[index].plcp_mimo |
320 RATE_MCS_HT_MSK;
321 }
322
323 switch (tbl->antenna_type) {
324 case ANT_BOTH:
325 mcs_rate->rate_n_flags |= RATE_MCS_ANT_AB_MSK;
326 break;
327 case ANT_MAIN:
328 mcs_rate->rate_n_flags |= RATE_MCS_ANT_A_MSK;
329 break;
330 case ANT_AUX:
331 mcs_rate->rate_n_flags |= RATE_MCS_ANT_B_MSK;
332 break;
333 case ANT_NONE:
334 break;
335 }
336
337 if (is_legacy(tbl->lq_type))
338 return rc;
339
340 if (tbl->is_fat) {
341 if (tbl->is_dup)
342 mcs_rate->rate_n_flags |= RATE_MCS_DUP_MSK;
343 else
344 mcs_rate->rate_n_flags |= RATE_MCS_FAT_MSK;
345 }
346 if (tbl->is_SGI)
347 mcs_rate->rate_n_flags |= RATE_MCS_SGI_MSK;
348
349 if (use_green) {
350 mcs_rate->rate_n_flags |= RATE_MCS_GF_MSK;
351 if (is_siso(tbl->lq_type))
352 mcs_rate->rate_n_flags &= ~RATE_MCS_SGI_MSK;
353 }
354 return rc;
355 }
356
357 static int rs_get_tbl_info_from_mcs(const struct iwl_rate *mcs_rate,
358 int phymode, struct iwl_scale_tbl_info *tbl,
359 int *rate_idx)
360 {
361 int index;
362 u32 ant_msk;
363
364 index = iwl_rate_index_from_plcp(mcs_rate->rate_n_flags);
365
366 if (index == IWL_RATE_INVALID) {
367 *rate_idx = -1;
368 return -1;
369 }
370 tbl->is_SGI = 0;
371 tbl->is_fat = 0;
372 tbl->is_dup = 0;
373 tbl->antenna_type = ANT_BOTH;
374
375 if (!(mcs_rate->rate_n_flags & RATE_MCS_HT_MSK)) {
376 ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_AB_MSK);
377
378 if (ant_msk == RATE_MCS_ANT_AB_MSK)
379 tbl->lq_type = LQ_NONE;
380 else {
381
382 if (phymode == MODE_IEEE80211A)
383 tbl->lq_type = LQ_A;
384 else
385 tbl->lq_type = LQ_G;
386
387 if (mcs_rate->rate_n_flags & RATE_MCS_ANT_A_MSK)
388 tbl->antenna_type = ANT_MAIN;
389 else
390 tbl->antenna_type = ANT_AUX;
391 }
392 *rate_idx = index;
393
394 } else if (iwl_rate_get_rate(mcs_rate->rate_n_flags)
395 <= IWL_RATE_SISO_60M_PLCP) {
396 tbl->lq_type = LQ_SISO;
397
398 ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_AB_MSK);
399 if (ant_msk == RATE_MCS_ANT_AB_MSK)
400 tbl->lq_type = LQ_NONE;
401 else {
402 if (mcs_rate->rate_n_flags & RATE_MCS_ANT_A_MSK)
403 tbl->antenna_type = ANT_MAIN;
404 else
405 tbl->antenna_type = ANT_AUX;
406 }
407 if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK)
408 tbl->is_SGI = 1;
409
410 if ((mcs_rate->rate_n_flags & RATE_MCS_FAT_MSK) ||
411 (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK))
412 tbl->is_fat = 1;
413
414 if (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK)
415 tbl->is_dup = 1;
416
417 *rate_idx = index;
418 } else {
419 tbl->lq_type = LQ_MIMO;
420 if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK)
421 tbl->is_SGI = 1;
422
423 if ((mcs_rate->rate_n_flags & RATE_MCS_FAT_MSK) ||
424 (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK))
425 tbl->is_fat = 1;
426
427 if (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK)
428 tbl->is_dup = 1;
429 *rate_idx = index;
430 }
431 return 0;
432 }
433
434 static inline void rs_toggle_antenna(struct iwl_rate *new_rate,
435 struct iwl_scale_tbl_info *tbl)
436 {
437 if (tbl->antenna_type == ANT_AUX) {
438 tbl->antenna_type = ANT_MAIN;
439 new_rate->rate_n_flags &= ~RATE_MCS_ANT_B_MSK;
440 new_rate->rate_n_flags |= RATE_MCS_ANT_A_MSK;
441 } else {
442 tbl->antenna_type = ANT_AUX;
443 new_rate->rate_n_flags &= ~RATE_MCS_ANT_A_MSK;
444 new_rate->rate_n_flags |= RATE_MCS_ANT_B_MSK;
445 }
446 }
447
448 static inline s8 rs_use_green(struct iwl_priv *priv)
449 {
450 s8 rc = 0;
451 #ifdef CONFIG_IWLWIFI_HT
452 if (!priv->is_ht_enabled || !priv->current_assoc_ht.is_ht)
453 return 0;
454
455 if ((priv->current_assoc_ht.is_green_field) &&
456 !(priv->current_assoc_ht.operating_mode & 0x4))
457 rc = 1;
458 #endif /*CONFIG_IWLWIFI_HT */
459 return rc;
460 }
461
462 /**
463 * rs_get_supported_rates - get the available rates
464 *
465 * if management frame or broadcast frame only return
466 * basic available rates.
467 *
468 */
469 static void rs_get_supported_rates(struct iwl_rate_scale_priv *lq_data,
470 struct ieee80211_hdr *hdr,
471 enum iwl_table_type rate_type,
472 u16 *data_rate)
473 {
474 if (is_legacy(rate_type))
475 *data_rate = lq_data->active_rate;
476 else {
477 if (is_siso(rate_type))
478 *data_rate = lq_data->active_siso_rate;
479 else
480 *data_rate = lq_data->active_mimo_rate;
481 }
482
483 if (hdr && is_multicast_ether_addr(hdr->addr1) &&
484 lq_data->active_rate_basic)
485 *data_rate = lq_data->active_rate_basic;
486 }
487
488 static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type)
489 {
490 u8 high = IWL_RATE_INVALID;
491 u8 low = IWL_RATE_INVALID;
492
493 /* 802.11A or ht walks to the next literal adjascent rate in
494 * the rate table */
495 if (is_a_band(rate_type) || !is_legacy(rate_type)) {
496 int i;
497 u32 mask;
498
499 /* Find the previous rate that is in the rate mask */
500 i = index - 1;
501 for (mask = (1 << i); i >= 0; i--, mask >>= 1) {
502 if (rate_mask & mask) {
503 low = i;
504 break;
505 }
506 }
507
508 /* Find the next rate that is in the rate mask */
509 i = index + 1;
510 for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) {
511 if (rate_mask & mask) {
512 high = i;
513 break;
514 }
515 }
516
517 return (high << 8) | low;
518 }
519
520 low = index;
521 while (low != IWL_RATE_INVALID) {
522 low = iwl_rates[low].prev_rs;
523 if (low == IWL_RATE_INVALID)
524 break;
525 if (rate_mask & (1 << low))
526 break;
527 IWL_DEBUG_RATE("Skipping masked lower rate: %d\n", low);
528 }
529
530 high = index;
531 while (high != IWL_RATE_INVALID) {
532 high = iwl_rates[high].next_rs;
533 if (high == IWL_RATE_INVALID)
534 break;
535 if (rate_mask & (1 << high))
536 break;
537 IWL_DEBUG_RATE("Skipping masked higher rate: %d\n", high);
538 }
539
540 return (high << 8) | low;
541 }
542
543 static int rs_get_lower_rate(struct iwl_rate_scale_priv *lq_data,
544 struct iwl_scale_tbl_info *tbl, u8 scale_index,
545 u8 ht_possible, struct iwl_rate *mcs_rate)
546 {
547 s32 low;
548 u16 rate_mask;
549 u16 high_low;
550 u8 switch_to_legacy = 0;
551 u8 is_green = lq_data->is_green;
552
553 /* check if we need to switch from HT to legacy rates.
554 * assumption is that mandatory rates (1Mbps or 6Mbps)
555 * are always supported (spec demand) */
556 if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) {
557 switch_to_legacy = 1;
558 scale_index = rs_ht_to_legacy[scale_index];
559 if (lq_data->phymode == MODE_IEEE80211A)
560 tbl->lq_type = LQ_A;
561 else
562 tbl->lq_type = LQ_G;
563
564 if ((tbl->antenna_type == ANT_BOTH) ||
565 (tbl->antenna_type == ANT_NONE))
566 tbl->antenna_type = ANT_MAIN;
567
568 tbl->is_fat = 0;
569 tbl->is_SGI = 0;
570 }
571
572 rs_get_supported_rates(lq_data, NULL, tbl->lq_type, &rate_mask);
573
574 /* mask with station rate restriction */
575 if (is_legacy(tbl->lq_type)) {
576 if (lq_data->phymode == (u8) MODE_IEEE80211A)
577 rate_mask = (u16)(rate_mask &
578 (lq_data->supp_rates << IWL_FIRST_OFDM_RATE));
579 else
580 rate_mask = (u16)(rate_mask & lq_data->supp_rates);
581 }
582
583 /* if we did switched from HT to legacy check current rate */
584 if ((switch_to_legacy) &&
585 (rate_mask & (1 << scale_index))) {
586 rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green);
587 return 0;
588 }
589
590 high_low = rs_get_adjacent_rate(scale_index, rate_mask, tbl->lq_type);
591 low = high_low & 0xff;
592
593 if (low != IWL_RATE_INVALID)
594 rs_mcs_from_tbl(mcs_rate, tbl, low, is_green);
595 else
596 rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green);
597
598 return 0;
599 }
600
601 static void rs_tx_status(void *priv_rate,
602 struct net_device *dev,
603 struct sk_buff *skb,
604 struct ieee80211_tx_status *tx_resp)
605 {
606 int status;
607 u8 retries;
608 int rs_index, index = 0;
609 struct iwl_rate_scale_priv *lq;
610 struct iwl_link_quality_cmd *table;
611 struct sta_info *sta;
612 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
613 struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
614 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
615 struct iwl_rate_scale_data *window = NULL;
616 struct iwl_rate_scale_data *search_win = NULL;
617 struct iwl_rate tx_mcs;
618 struct iwl_scale_tbl_info tbl_type;
619 struct iwl_scale_tbl_info *curr_tbl, *search_tbl;
620 u8 active_index = 0;
621 u16 fc = le16_to_cpu(hdr->frame_control);
622 s32 tpt = 0;
623
624 IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n");
625
626 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
627 return;
628
629 retries = tx_resp->retry_count;
630
631 if (retries > 15)
632 retries = 15;
633
634
635 sta = sta_info_get(local, hdr->addr1);
636
637 if (!sta || !sta->rate_ctrl_priv) {
638 if (sta)
639 sta_info_put(sta);
640 return;
641 }
642
643 lq = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv;
644
645 if (!priv->lq_mngr.lq_ready)
646 return;
647
648 if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && !lq->ibss_sta_added)
649 return;
650
651 table = &lq->lq;
652 active_index = lq->active_tbl;
653
654 lq->antenna = (lq->valid_antenna & local->hw.conf.antenna_sel_tx);
655 if (!lq->antenna)
656 lq->antenna = lq->valid_antenna;
657
658 lq->antenna = lq->valid_antenna;
659 curr_tbl = &(lq->lq_info[active_index]);
660 search_tbl = &(lq->lq_info[(1 - active_index)]);
661 window = (struct iwl_rate_scale_data *)
662 &(curr_tbl->win[0]);
663 search_win = (struct iwl_rate_scale_data *)
664 &(search_tbl->win[0]);
665
666 tx_mcs.rate_n_flags = tx_resp->control.tx_rate;
667
668 rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode,
669 &tbl_type, &rs_index);
670 if ((rs_index < 0) || (rs_index >= IWL_RATE_COUNT)) {
671 IWL_DEBUG_RATE("bad rate index at: %d rate 0x%X\n",
672 rs_index, tx_mcs.rate_n_flags);
673 sta_info_put(sta);
674 return;
675 }
676
677 if (retries &&
678 (tx_mcs.rate_n_flags !=
679 le32_to_cpu(table->rs_table[0].rate_n_flags))) {
680 IWL_DEBUG_RATE("initial rate does not match 0x%x 0x%x\n",
681 tx_mcs.rate_n_flags,
682 le32_to_cpu(table->rs_table[0].rate_n_flags));
683 sta_info_put(sta);
684 return;
685 }
686
687 while (retries) {
688 tx_mcs.rate_n_flags =
689 le32_to_cpu(table->rs_table[index].rate_n_flags);
690 rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode,
691 &tbl_type, &rs_index);
692
693 if ((tbl_type.lq_type == search_tbl->lq_type) &&
694 (tbl_type.antenna_type == search_tbl->antenna_type) &&
695 (tbl_type.is_SGI == search_tbl->is_SGI)) {
696 if (search_tbl->expected_tpt)
697 tpt = search_tbl->expected_tpt[rs_index];
698 else
699 tpt = 0;
700 rs_collect_tx_data(search_win,
701 rs_index, tpt, 0);
702 } else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
703 (tbl_type.antenna_type == curr_tbl->antenna_type) &&
704 (tbl_type.is_SGI == curr_tbl->is_SGI)) {
705 if (curr_tbl->expected_tpt)
706 tpt = curr_tbl->expected_tpt[rs_index];
707 else
708 tpt = 0;
709 rs_collect_tx_data(window, rs_index, tpt, 0);
710 }
711 if (lq->stay_in_tbl)
712 lq->total_failed++;
713 --retries;
714 index++;
715
716 }
717
718 if (!tx_resp->retry_count)
719 tx_mcs.rate_n_flags = tx_resp->control.tx_rate;
720 else
721 tx_mcs.rate_n_flags =
722 le32_to_cpu(table->rs_table[index].rate_n_flags);
723
724 rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode,
725 &tbl_type, &rs_index);
726
727 if (tx_resp->flags & IEEE80211_TX_STATUS_ACK)
728 status = 1;
729 else
730 status = 0;
731
732 if ((tbl_type.lq_type == search_tbl->lq_type) &&
733 (tbl_type.antenna_type == search_tbl->antenna_type) &&
734 (tbl_type.is_SGI == search_tbl->is_SGI)) {
735 if (search_tbl->expected_tpt)
736 tpt = search_tbl->expected_tpt[rs_index];
737 else
738 tpt = 0;
739 rs_collect_tx_data(search_win,
740 rs_index, tpt, status);
741 } else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
742 (tbl_type.antenna_type == curr_tbl->antenna_type) &&
743 (tbl_type.is_SGI == curr_tbl->is_SGI)) {
744 if (curr_tbl->expected_tpt)
745 tpt = curr_tbl->expected_tpt[rs_index];
746 else
747 tpt = 0;
748 rs_collect_tx_data(window, rs_index, tpt, status);
749 }
750
751 if (lq->stay_in_tbl) {
752 if (status)
753 lq->total_success++;
754 else
755 lq->total_failed++;
756 }
757
758 rs_rate_scale_perform(priv, dev, hdr, sta);
759 sta_info_put(sta);
760 return;
761 }
762
763 static u8 rs_is_ant_connected(u8 valid_antenna,
764 enum iwl_antenna_type antenna_type)
765 {
766 if (antenna_type == ANT_AUX)
767 return ((valid_antenna & 0x2) ? 1:0);
768 else if (antenna_type == ANT_MAIN)
769 return ((valid_antenna & 0x1) ? 1:0);
770 else if (antenna_type == ANT_BOTH) {
771 if ((valid_antenna & 0x3) == 0x3)
772 return 1;
773 else
774 return 0;
775 }
776
777 return 1;
778 }
779
780 static u8 rs_is_other_ant_connected(u8 valid_antenna,
781 enum iwl_antenna_type antenna_type)
782 {
783 if (antenna_type == ANT_AUX)
784 return (rs_is_ant_connected(valid_antenna, ANT_MAIN));
785 else
786 return (rs_is_ant_connected(valid_antenna, ANT_AUX));
787
788 return 0;
789 }
790
791 static void rs_set_stay_in_table(u8 is_legacy,
792 struct iwl_rate_scale_priv *lq_data)
793 {
794 IWL_DEBUG_HT("we are staying in the same table\n");
795 lq_data->stay_in_tbl = 1;
796 if (is_legacy) {
797 lq_data->table_count_limit = IWL_LEGACY_TABLE_COUNT;
798 lq_data->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT;
799 lq_data->max_success_limit = IWL_LEGACY_TABLE_COUNT;
800 } else {
801 lq_data->table_count_limit = IWL_NONE_LEGACY_TABLE_COUNT;
802 lq_data->max_failure_limit = IWL_NONE_LEGACY_FAILURE_LIMIT;
803 lq_data->max_success_limit = IWL_NONE_LEGACY_SUCCESS_LIMIT;
804 }
805 lq_data->table_count = 0;
806 lq_data->total_failed = 0;
807 lq_data->total_success = 0;
808 }
809
810 static void rs_get_expected_tpt_table(struct iwl_rate_scale_priv *lq_data,
811 struct iwl_scale_tbl_info *tbl)
812 {
813 if (is_legacy(tbl->lq_type)) {
814 if (!is_a_band(tbl->lq_type))
815 tbl->expected_tpt = expected_tpt_G;
816 else
817 tbl->expected_tpt = expected_tpt_A;
818 } else if (is_siso(tbl->lq_type)) {
819 if (tbl->is_fat && !lq_data->is_dup)
820 if (tbl->is_SGI)
821 tbl->expected_tpt = expected_tpt_siso40MHzSGI;
822 else
823 tbl->expected_tpt = expected_tpt_siso40MHz;
824 else if (tbl->is_SGI)
825 tbl->expected_tpt = expected_tpt_siso20MHzSGI;
826 else
827 tbl->expected_tpt = expected_tpt_siso20MHz;
828
829 } else if (is_mimo(tbl->lq_type)) {
830 if (tbl->is_fat && !lq_data->is_dup)
831 if (tbl->is_SGI)
832 tbl->expected_tpt = expected_tpt_mimo40MHzSGI;
833 else
834 tbl->expected_tpt = expected_tpt_mimo40MHz;
835 else if (tbl->is_SGI)
836 tbl->expected_tpt = expected_tpt_mimo20MHzSGI;
837 else
838 tbl->expected_tpt = expected_tpt_mimo20MHz;
839 } else
840 tbl->expected_tpt = expected_tpt_G;
841 }
842
843 #ifdef CONFIG_IWLWIFI_HT
844 static s32 rs_get_best_rate(struct iwl_priv *priv,
845 struct iwl_rate_scale_priv *lq_data,
846 struct iwl_scale_tbl_info *tbl,
847 u16 rate_mask, s8 index, s8 rate)
848 {
849 struct iwl_scale_tbl_info *active_tbl =
850 &(lq_data->lq_info[lq_data->active_tbl]);
851 s32 new_rate, high, low, start_hi;
852 s32 active_sr = active_tbl->win[index].success_ratio;
853 s32 *tpt_tbl = tbl->expected_tpt;
854 s32 active_tpt = active_tbl->expected_tpt[index];
855 u16 high_low;
856
857 new_rate = high = low = start_hi = IWL_RATE_INVALID;
858
859 for (; ;) {
860 high_low = rs_get_adjacent_rate(rate, rate_mask, tbl->lq_type);
861
862 low = high_low & 0xff;
863 high = (high_low >> 8) & 0xff;
864
865 if ((((100 * tpt_tbl[rate]) > lq_data->last_tpt) &&
866 ((active_sr > IWL_RATE_DECREASE_TH) &&
867 (active_sr <= IWL_RATE_HIGH_TH) &&
868 (tpt_tbl[rate] <= active_tpt))) ||
869 ((active_sr >= IWL_RATE_SCALE_SWITCH) &&
870 (tpt_tbl[rate] > active_tpt))) {
871
872 if (start_hi != IWL_RATE_INVALID) {
873 new_rate = start_hi;
874 break;
875 }
876 new_rate = rate;
877 if (low != IWL_RATE_INVALID)
878 rate = low;
879 else
880 break;
881 } else {
882 if (new_rate != IWL_RATE_INVALID)
883 break;
884 else if (high != IWL_RATE_INVALID) {
885 start_hi = high;
886 rate = high;
887 } else {
888 new_rate = rate;
889 break;
890 }
891 }
892 }
893
894 return new_rate;
895 }
896 #endif /* CONFIG_IWLWIFI_HT */
897
898 static inline u8 rs_is_both_ant_supp(u8 valid_antenna)
899 {
900 return (rs_is_ant_connected(valid_antenna, ANT_BOTH));
901 }
902
903 static int rs_switch_to_mimo(struct iwl_priv *priv,
904 struct iwl_rate_scale_priv *lq_data,
905 struct iwl_scale_tbl_info *tbl, int index)
906 {
907 int rc = -1;
908 #ifdef CONFIG_IWLWIFI_HT
909 u16 rate_mask;
910 s32 rate;
911 s8 is_green = lq_data->is_green;
912
913 if (!priv->is_ht_enabled || !priv->current_assoc_ht.is_ht)
914 return -1;
915
916 IWL_DEBUG_HT("LQ: try to switch to MIMO\n");
917 tbl->lq_type = LQ_MIMO;
918 rs_get_supported_rates(lq_data, NULL, tbl->lq_type,
919 &rate_mask);
920
921 if (priv->current_assoc_ht.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC)
922 return -1;
923
924 if (!rs_is_both_ant_supp(lq_data->antenna))
925 return -1;
926
927 rc = 0;
928 tbl->is_dup = lq_data->is_dup;
929 tbl->action = 0;
930 if (priv->current_channel_width == IWL_CHANNEL_WIDTH_40MHZ)
931 tbl->is_fat = 1;
932 else
933 tbl->is_fat = 0;
934
935 if (tbl->is_fat) {
936 if (priv->current_assoc_ht.sgf & HT_SHORT_GI_40MHZ_ONLY)
937 tbl->is_SGI = 1;
938 else
939 tbl->is_SGI = 0;
940 } else if (priv->current_assoc_ht.sgf & HT_SHORT_GI_20MHZ_ONLY)
941 tbl->is_SGI = 1;
942 else
943 tbl->is_SGI = 0;
944
945 rs_get_expected_tpt_table(lq_data, tbl);
946
947 rate = rs_get_best_rate(priv, lq_data, tbl, rate_mask, index, index);
948
949 IWL_DEBUG_HT("LQ: MIMO best rate %d mask %X\n", rate, rate_mask);
950 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask))
951 return -1;
952 rs_mcs_from_tbl(&tbl->current_rate, tbl, rate, is_green);
953
954 IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n",
955 tbl->current_rate.rate_n_flags, is_green);
956
957 #endif /*CONFIG_IWLWIFI_HT */
958 return rc;
959 }
960
961 static int rs_switch_to_siso(struct iwl_priv *priv,
962 struct iwl_rate_scale_priv *lq_data,
963 struct iwl_scale_tbl_info *tbl, int index)
964 {
965 int rc = -1;
966 #ifdef CONFIG_IWLWIFI_HT
967 u16 rate_mask;
968 u8 is_green = lq_data->is_green;
969 s32 rate;
970
971 IWL_DEBUG_HT("LQ: try to switch to SISO\n");
972 if (!priv->is_ht_enabled || !priv->current_assoc_ht.is_ht)
973 return -1;
974
975 rc = 0;
976 tbl->is_dup = lq_data->is_dup;
977 tbl->lq_type = LQ_SISO;
978 tbl->action = 0;
979 rs_get_supported_rates(lq_data, NULL, tbl->lq_type,
980 &rate_mask);
981
982 if (priv->current_channel_width == IWL_CHANNEL_WIDTH_40MHZ)
983 tbl->is_fat = 1;
984 else
985 tbl->is_fat = 0;
986
987 if (tbl->is_fat) {
988 if (priv->current_assoc_ht.sgf & HT_SHORT_GI_40MHZ_ONLY)
989 tbl->is_SGI = 1;
990 else
991 tbl->is_SGI = 0;
992 } else if (priv->current_assoc_ht.sgf & HT_SHORT_GI_20MHZ_ONLY)
993 tbl->is_SGI = 1;
994 else
995 tbl->is_SGI = 0;
996
997 if (is_green)
998 tbl->is_SGI = 0;
999
1000 rs_get_expected_tpt_table(lq_data, tbl);
1001 rate = rs_get_best_rate(priv, lq_data, tbl, rate_mask, index, index);
1002
1003 IWL_DEBUG_HT("LQ: get best rate %d mask %X\n", rate, rate_mask);
1004 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
1005 IWL_DEBUG_HT("can not switch with index %d rate mask %x\n",
1006 rate, rate_mask);
1007 return -1;
1008 }
1009 rs_mcs_from_tbl(&tbl->current_rate, tbl, rate, is_green);
1010 IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n",
1011 tbl->current_rate.rate_n_flags, is_green);
1012
1013 #endif /*CONFIG_IWLWIFI_HT */
1014 return rc;
1015 }
1016
1017 static int rs_move_legacy_other(struct iwl_priv *priv,
1018 struct iwl_rate_scale_priv *lq_data,
1019 int index)
1020 {
1021 int rc = 0;
1022 struct iwl_scale_tbl_info *tbl =
1023 &(lq_data->lq_info[lq_data->active_tbl]);
1024 struct iwl_scale_tbl_info *search_tbl =
1025 &(lq_data->lq_info[(1 - lq_data->active_tbl)]);
1026 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1027 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1028 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1029 u8 start_action = tbl->action;
1030
1031 for (; ;) {
1032 switch (tbl->action) {
1033 case IWL_LEGACY_SWITCH_ANTENNA:
1034 IWL_DEBUG_HT("LQ Legacy switch Antenna\n");
1035
1036 search_tbl->lq_type = LQ_NONE;
1037 lq_data->action_counter++;
1038 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1039 break;
1040 if (!rs_is_other_ant_connected(lq_data->antenna,
1041 tbl->antenna_type))
1042 break;
1043
1044 memcpy(search_tbl, tbl, sz);
1045
1046 rs_toggle_antenna(&(search_tbl->current_rate),
1047 search_tbl);
1048 rs_get_expected_tpt_table(lq_data, search_tbl);
1049 lq_data->search_better_tbl = 1;
1050 goto out;
1051
1052 case IWL_LEGACY_SWITCH_SISO:
1053 IWL_DEBUG_HT("LQ: Legacy switch to SISO\n");
1054 memcpy(search_tbl, tbl, sz);
1055 search_tbl->lq_type = LQ_SISO;
1056 search_tbl->is_SGI = 0;
1057 search_tbl->is_fat = 0;
1058 rc = rs_switch_to_siso(priv, lq_data, search_tbl,
1059 index);
1060 if (!rc) {
1061 lq_data->search_better_tbl = 1;
1062 lq_data->action_counter = 0;
1063 }
1064 if (!rc)
1065 goto out;
1066
1067 break;
1068 case IWL_LEGACY_SWITCH_MIMO:
1069 IWL_DEBUG_HT("LQ: Legacy switch MIMO\n");
1070 memcpy(search_tbl, tbl, sz);
1071 search_tbl->lq_type = LQ_MIMO;
1072 search_tbl->is_SGI = 0;
1073 search_tbl->is_fat = 0;
1074 search_tbl->antenna_type = ANT_BOTH;
1075 rc = rs_switch_to_mimo(priv, lq_data, search_tbl,
1076 index);
1077 if (!rc) {
1078 lq_data->search_better_tbl = 1;
1079 lq_data->action_counter = 0;
1080 }
1081 if (!rc)
1082 goto out;
1083 break;
1084 }
1085 tbl->action++;
1086 if (tbl->action > IWL_LEGACY_SWITCH_MIMO)
1087 tbl->action = IWL_LEGACY_SWITCH_ANTENNA;
1088
1089 if (tbl->action == start_action)
1090 break;
1091
1092 }
1093 return 0;
1094
1095 out:
1096 tbl->action++;
1097 if (tbl->action > IWL_LEGACY_SWITCH_MIMO)
1098 tbl->action = IWL_LEGACY_SWITCH_ANTENNA;
1099 return 0;
1100
1101 }
1102
1103 static int rs_move_siso_to_other(struct iwl_priv *priv,
1104 struct iwl_rate_scale_priv *lq_data,
1105 int index)
1106 {
1107 int rc = -1;
1108 u8 is_green = lq_data->is_green;
1109 struct iwl_scale_tbl_info *tbl =
1110 &(lq_data->lq_info[lq_data->active_tbl]);
1111 struct iwl_scale_tbl_info *search_tbl =
1112 &(lq_data->lq_info[(1 - lq_data->active_tbl)]);
1113 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1114 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1115 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1116 u8 start_action = tbl->action;
1117
1118 for (;;) {
1119 lq_data->action_counter++;
1120 switch (tbl->action) {
1121 case IWL_SISO_SWITCH_ANTENNA:
1122 IWL_DEBUG_HT("LQ: SISO SWITCH ANTENNA SISO\n");
1123 search_tbl->lq_type = LQ_NONE;
1124 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1125 break;
1126 if (!rs_is_other_ant_connected(lq_data->antenna,
1127 tbl->antenna_type))
1128 break;
1129
1130 memcpy(search_tbl, tbl, sz);
1131 search_tbl->action = IWL_SISO_SWITCH_MIMO;
1132 rs_toggle_antenna(&(search_tbl->current_rate),
1133 search_tbl);
1134 lq_data->search_better_tbl = 1;
1135
1136 goto out;
1137
1138 case IWL_SISO_SWITCH_MIMO:
1139 IWL_DEBUG_HT("LQ: SISO SWITCH TO MIMO FROM SISO\n");
1140 memcpy(search_tbl, tbl, sz);
1141 search_tbl->lq_type = LQ_MIMO;
1142 search_tbl->is_SGI = 0;
1143 search_tbl->is_fat = 0;
1144 search_tbl->antenna_type = ANT_BOTH;
1145 rc = rs_switch_to_mimo(priv, lq_data, search_tbl,
1146 index);
1147 if (!rc)
1148 lq_data->search_better_tbl = 1;
1149
1150 if (!rc)
1151 goto out;
1152 break;
1153 case IWL_SISO_SWITCH_GI:
1154 IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n");
1155 memcpy(search_tbl, tbl, sz);
1156 search_tbl->action = 0;
1157 if (search_tbl->is_SGI)
1158 search_tbl->is_SGI = 0;
1159 else if (!is_green)
1160 search_tbl->is_SGI = 1;
1161 else
1162 break;
1163 lq_data->search_better_tbl = 1;
1164 if ((tbl->lq_type == LQ_SISO) &&
1165 (tbl->is_SGI)) {
1166 s32 tpt = lq_data->last_tpt / 100;
1167 if (((!tbl->is_fat) &&
1168 (tpt >= expected_tpt_siso20MHz[index])) ||
1169 ((tbl->is_fat) &&
1170 (tpt >= expected_tpt_siso40MHz[index])))
1171 lq_data->search_better_tbl = 0;
1172 }
1173 rs_get_expected_tpt_table(lq_data, search_tbl);
1174 rs_mcs_from_tbl(&search_tbl->current_rate,
1175 search_tbl, index, is_green);
1176 goto out;
1177 }
1178 tbl->action++;
1179 if (tbl->action > IWL_SISO_SWITCH_GI)
1180 tbl->action = IWL_SISO_SWITCH_ANTENNA;
1181
1182 if (tbl->action == start_action)
1183 break;
1184 }
1185 return 0;
1186
1187 out:
1188 tbl->action++;
1189 if (tbl->action > IWL_SISO_SWITCH_GI)
1190 tbl->action = IWL_SISO_SWITCH_ANTENNA;
1191 return 0;
1192 }
1193
1194 static int rs_move_mimo_to_other(struct iwl_priv *priv,
1195 struct iwl_rate_scale_priv *lq_data,
1196 int index)
1197 {
1198 int rc = -1;
1199 s8 is_green = lq_data->is_green;
1200 struct iwl_scale_tbl_info *tbl =
1201 &(lq_data->lq_info[lq_data->active_tbl]);
1202 struct iwl_scale_tbl_info *search_tbl =
1203 &(lq_data->lq_info[(1 - lq_data->active_tbl)]);
1204 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1205 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1206 u8 start_action = tbl->action;
1207
1208 for (;;) {
1209 lq_data->action_counter++;
1210 switch (tbl->action) {
1211 case IWL_MIMO_SWITCH_ANTENNA_A:
1212 case IWL_MIMO_SWITCH_ANTENNA_B:
1213 IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n");
1214 memcpy(search_tbl, tbl, sz);
1215 search_tbl->lq_type = LQ_SISO;
1216 search_tbl->is_SGI = 0;
1217 search_tbl->is_fat = 0;
1218 if (tbl->action == IWL_MIMO_SWITCH_ANTENNA_A)
1219 search_tbl->antenna_type = ANT_MAIN;
1220 else
1221 search_tbl->antenna_type = ANT_AUX;
1222
1223 rc = rs_switch_to_siso(priv, lq_data, search_tbl,
1224 index);
1225 if (!rc) {
1226 lq_data->search_better_tbl = 1;
1227 goto out;
1228 }
1229 break;
1230
1231 case IWL_MIMO_SWITCH_GI:
1232 IWL_DEBUG_HT("LQ: MIMO SWITCH TO GI\n");
1233 memcpy(search_tbl, tbl, sz);
1234 search_tbl->lq_type = LQ_MIMO;
1235 search_tbl->antenna_type = ANT_BOTH;
1236 search_tbl->action = 0;
1237 if (search_tbl->is_SGI)
1238 search_tbl->is_SGI = 0;
1239 else
1240 search_tbl->is_SGI = 1;
1241 lq_data->search_better_tbl = 1;
1242 if ((tbl->lq_type == LQ_MIMO) &&
1243 (tbl->is_SGI)) {
1244 s32 tpt = lq_data->last_tpt / 100;
1245 if (((!tbl->is_fat) &&
1246 (tpt >= expected_tpt_mimo20MHz[index])) ||
1247 ((tbl->is_fat) &&
1248 (tpt >= expected_tpt_mimo40MHz[index])))
1249 lq_data->search_better_tbl = 0;
1250 }
1251 rs_get_expected_tpt_table(lq_data, search_tbl);
1252 rs_mcs_from_tbl(&search_tbl->current_rate,
1253 search_tbl, index, is_green);
1254 goto out;
1255
1256 }
1257 tbl->action++;
1258 if (tbl->action > IWL_MIMO_SWITCH_GI)
1259 tbl->action = IWL_MIMO_SWITCH_ANTENNA_A;
1260
1261 if (tbl->action == start_action)
1262 break;
1263 }
1264
1265 return 0;
1266 out:
1267 tbl->action++;
1268 if (tbl->action > IWL_MIMO_SWITCH_GI)
1269 tbl->action = IWL_MIMO_SWITCH_ANTENNA_A;
1270 return 0;
1271
1272 }
1273
1274 static void rs_stay_in_table(struct iwl_rate_scale_priv *lq_data)
1275 {
1276 struct iwl_scale_tbl_info *tbl;
1277 int i;
1278 int active_tbl;
1279 int flush_interval_passed = 0;
1280
1281 active_tbl = lq_data->active_tbl;
1282
1283 tbl = &(lq_data->lq_info[active_tbl]);
1284
1285 if (lq_data->stay_in_tbl) {
1286
1287 if (lq_data->flush_timer)
1288 flush_interval_passed =
1289 time_after(jiffies,
1290 (unsigned long)(lq_data->flush_timer +
1291 IWL_RATE_SCALE_FLUSH_INTVL));
1292
1293 flush_interval_passed = 0;
1294 if ((lq_data->total_failed > lq_data->max_failure_limit) ||
1295 (lq_data->total_success > lq_data->max_success_limit) ||
1296 ((!lq_data->search_better_tbl) && (lq_data->flush_timer)
1297 && (flush_interval_passed))) {
1298 IWL_DEBUG_HT("LQ: stay is expired %d %d %d\n:",
1299 lq_data->total_failed,
1300 lq_data->total_success,
1301 flush_interval_passed);
1302 lq_data->stay_in_tbl = 0;
1303 lq_data->total_failed = 0;
1304 lq_data->total_success = 0;
1305 lq_data->flush_timer = 0;
1306 } else if (lq_data->table_count > 0) {
1307 lq_data->table_count++;
1308 if (lq_data->table_count >=
1309 lq_data->table_count_limit) {
1310 lq_data->table_count = 0;
1311
1312 IWL_DEBUG_HT("LQ: stay in table clear win\n");
1313 for (i = 0; i < IWL_RATE_COUNT; i++)
1314 rs_rate_scale_clear_window(
1315 &(tbl->win[i]));
1316 }
1317 }
1318
1319 if (!lq_data->stay_in_tbl) {
1320 for (i = 0; i < IWL_RATE_COUNT; i++)
1321 rs_rate_scale_clear_window(&(tbl->win[i]));
1322 }
1323 }
1324 }
1325
1326 static void rs_rate_scale_perform(struct iwl_priv *priv,
1327 struct net_device *dev,
1328 struct ieee80211_hdr *hdr,
1329 struct sta_info *sta)
1330 {
1331 int low = IWL_RATE_INVALID;
1332 int high = IWL_RATE_INVALID;
1333 int index;
1334 int i;
1335 struct iwl_rate_scale_data *window = NULL;
1336 int current_tpt = IWL_INVALID_VALUE;
1337 int low_tpt = IWL_INVALID_VALUE;
1338 int high_tpt = IWL_INVALID_VALUE;
1339 u32 fail_count;
1340 s8 scale_action = 0;
1341 u16 fc, rate_mask;
1342 u8 update_lq = 0;
1343 struct iwl_rate_scale_priv *lq_data;
1344 struct iwl_scale_tbl_info *tbl, *tbl1;
1345 u16 rate_scale_index_msk = 0;
1346 struct iwl_rate mcs_rate;
1347 u8 is_green = 0;
1348 u8 active_tbl = 0;
1349 u8 done_search = 0;
1350 u16 high_low;
1351
1352 IWL_DEBUG_RATE("rate scale calculate new rate for skb\n");
1353
1354 fc = le16_to_cpu(hdr->frame_control);
1355 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {
1356 /* Send management frames and broadcast/multicast data using
1357 * lowest rate. */
1358 /* TODO: this could probably be improved.. */
1359 return;
1360 }
1361
1362 if (!sta || !sta->rate_ctrl_priv)
1363 return;
1364
1365 if (!priv->lq_mngr.lq_ready) {
1366 IWL_DEBUG_RATE("still rate scaling not ready\n");
1367 return;
1368 }
1369 lq_data = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv;
1370
1371 if (!lq_data->search_better_tbl)
1372 active_tbl = lq_data->active_tbl;
1373 else
1374 active_tbl = 1 - lq_data->active_tbl;
1375
1376 tbl = &(lq_data->lq_info[active_tbl]);
1377 is_green = lq_data->is_green;
1378
1379 index = sta->last_txrate;
1380
1381 IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index,
1382 tbl->lq_type);
1383
1384 rs_get_supported_rates(lq_data, hdr, tbl->lq_type,
1385 &rate_mask);
1386
1387 IWL_DEBUG_RATE("mask 0x%04X \n", rate_mask);
1388
1389 /* mask with station rate restriction */
1390 if (is_legacy(tbl->lq_type)) {
1391 if (lq_data->phymode == (u8) MODE_IEEE80211A)
1392 rate_scale_index_msk = (u16) (rate_mask &
1393 (lq_data->supp_rates << IWL_FIRST_OFDM_RATE));
1394 else
1395 rate_scale_index_msk = (u16) (rate_mask &
1396 lq_data->supp_rates);
1397
1398 } else
1399 rate_scale_index_msk = rate_mask;
1400
1401 if (!rate_scale_index_msk)
1402 rate_scale_index_msk = rate_mask;
1403
1404 if (index < 0 || !((1 << index) & rate_scale_index_msk)) {
1405 index = IWL_INVALID_VALUE;
1406 update_lq = 1;
1407
1408 /* get the lowest availabe rate */
1409 for (i = 0; i <= IWL_RATE_COUNT; i++) {
1410 if ((1 << i) & rate_scale_index_msk)
1411 index = i;
1412 }
1413
1414 if (index == IWL_INVALID_VALUE) {
1415 IWL_WARNING("Can not find a suitable rate\n");
1416 return;
1417 }
1418 }
1419
1420 if (!tbl->expected_tpt)
1421 rs_get_expected_tpt_table(lq_data, tbl);
1422
1423 window = &(tbl->win[index]);
1424
1425 fail_count = window->counter - window->success_counter;
1426 if (((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
1427 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))
1428 || (tbl->expected_tpt == NULL)) {
1429 IWL_DEBUG_RATE("LQ: still below TH succ %d total %d "
1430 "for index %d\n",
1431 window->success_counter, window->counter, index);
1432 window->average_tpt = IWL_INVALID_VALUE;
1433 rs_stay_in_table(lq_data);
1434 if (update_lq) {
1435 rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
1436 rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq);
1437 rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC);
1438 }
1439 goto out;
1440
1441 } else
1442 window->average_tpt = ((window->success_ratio *
1443 tbl->expected_tpt[index] + 64) / 128);
1444
1445 if (lq_data->search_better_tbl) {
1446 int success_limit = IWL_RATE_SCALE_SWITCH;
1447
1448 if ((window->success_ratio > success_limit) ||
1449 (window->average_tpt > lq_data->last_tpt)) {
1450 if (!is_legacy(tbl->lq_type)) {
1451 IWL_DEBUG_HT("LQ: we are switching to HT"
1452 " rate suc %d current tpt %d"
1453 " old tpt %d\n",
1454 window->success_ratio,
1455 window->average_tpt,
1456 lq_data->last_tpt);
1457 lq_data->enable_counter = 1;
1458 }
1459 lq_data->active_tbl = active_tbl;
1460 current_tpt = window->average_tpt;
1461 } else {
1462 tbl->lq_type = LQ_NONE;
1463 active_tbl = lq_data->active_tbl;
1464 tbl = &(lq_data->lq_info[active_tbl]);
1465
1466 index = iwl_rate_index_from_plcp(
1467 tbl->current_rate.rate_n_flags);
1468
1469 update_lq = 1;
1470 current_tpt = lq_data->last_tpt;
1471 IWL_DEBUG_HT("XXY GO BACK TO OLD TABLE\n");
1472 }
1473 lq_data->search_better_tbl = 0;
1474 done_search = 1;
1475 goto lq_update;
1476 }
1477
1478 high_low = rs_get_adjacent_rate(index, rate_scale_index_msk,
1479 tbl->lq_type);
1480 low = high_low & 0xff;
1481 high = (high_low >> 8) & 0xff;
1482
1483 current_tpt = window->average_tpt;
1484
1485 if (low != IWL_RATE_INVALID)
1486 low_tpt = tbl->win[low].average_tpt;
1487
1488 if (high != IWL_RATE_INVALID)
1489 high_tpt = tbl->win[high].average_tpt;
1490
1491
1492 scale_action = 1;
1493
1494 if ((window->success_ratio <= IWL_RATE_DECREASE_TH) ||
1495 (current_tpt == 0)) {
1496 IWL_DEBUG_RATE("decrease rate because of low success_ratio\n");
1497 scale_action = -1;
1498 } else if ((low_tpt == IWL_INVALID_VALUE) &&
1499 (high_tpt == IWL_INVALID_VALUE))
1500 scale_action = 1;
1501 else if ((low_tpt != IWL_INVALID_VALUE) &&
1502 (high_tpt != IWL_INVALID_VALUE) &&
1503 (low_tpt < current_tpt) &&
1504 (high_tpt < current_tpt))
1505 scale_action = 0;
1506 else {
1507 if (high_tpt != IWL_INVALID_VALUE) {
1508 if (high_tpt > current_tpt)
1509 scale_action = 1;
1510 else {
1511 IWL_DEBUG_RATE
1512 ("decrease rate because of high tpt\n");
1513 scale_action = -1;
1514 }
1515 } else if (low_tpt != IWL_INVALID_VALUE) {
1516 if (low_tpt > current_tpt) {
1517 IWL_DEBUG_RATE
1518 ("decrease rate because of low tpt\n");
1519 scale_action = -1;
1520 } else
1521 scale_action = 1;
1522 }
1523 }
1524
1525 if (scale_action == -1) {
1526 if ((low != IWL_RATE_INVALID) &&
1527 ((window->success_ratio > IWL_RATE_HIGH_TH) ||
1528 (current_tpt > (100 * tbl->expected_tpt[low]))))
1529 scale_action = 0;
1530 } else if ((scale_action == 1) &&
1531 (window->success_ratio < IWL_RATE_INCREASE_TH))
1532 scale_action = 0;
1533
1534 switch (scale_action) {
1535 case -1:
1536 if (low != IWL_RATE_INVALID) {
1537 update_lq = 1;
1538 index = low;
1539 }
1540 break;
1541 case 1:
1542 if (high != IWL_RATE_INVALID) {
1543 update_lq = 1;
1544 index = high;
1545 }
1546
1547 break;
1548 case 0:
1549 default:
1550 break;
1551 }
1552
1553 IWL_DEBUG_HT("choose rate scale index %d action %d low %d "
1554 "high %d type %d\n",
1555 index, scale_action, low, high, tbl->lq_type);
1556
1557 lq_update:
1558 if (update_lq) {
1559 rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
1560 rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq);
1561 rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC);
1562 }
1563 rs_stay_in_table(lq_data);
1564
1565 if (!update_lq && !done_search && !lq_data->stay_in_tbl) {
1566 lq_data->last_tpt = current_tpt;
1567
1568 if (is_legacy(tbl->lq_type))
1569 rs_move_legacy_other(priv, lq_data, index);
1570 else if (is_siso(tbl->lq_type))
1571 rs_move_siso_to_other(priv, lq_data, index);
1572 else
1573 rs_move_mimo_to_other(priv, lq_data, index);
1574
1575 if (lq_data->search_better_tbl) {
1576 tbl = &(lq_data->lq_info[(1 - lq_data->active_tbl)]);
1577 for (i = 0; i < IWL_RATE_COUNT; i++)
1578 rs_rate_scale_clear_window(&(tbl->win[i]));
1579
1580 index = iwl_rate_index_from_plcp(
1581 tbl->current_rate.rate_n_flags);
1582
1583 IWL_DEBUG_HT("Switch current mcs: %X index: %d\n",
1584 tbl->current_rate.rate_n_flags, index);
1585 rs_fill_link_cmd(lq_data, &tbl->current_rate,
1586 &lq_data->lq);
1587 rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC);
1588 }
1589 tbl1 = &(lq_data->lq_info[lq_data->active_tbl]);
1590
1591 if (is_legacy(tbl1->lq_type) &&
1592 #ifdef CONFIG_IWLWIFI_HT
1593 !priv->current_assoc_ht.is_ht &&
1594 #endif
1595 (lq_data->action_counter >= 1)) {
1596 lq_data->action_counter = 0;
1597 IWL_DEBUG_HT("LQ: STAY in legacy table\n");
1598 rs_set_stay_in_table(1, lq_data);
1599 }
1600
1601 if (lq_data->enable_counter &&
1602 (lq_data->action_counter >= IWL_ACTION_LIMIT)) {
1603 #ifdef CONFIG_IWLWIFI_HT_AGG
1604 if ((lq_data->last_tpt > TID_AGG_TPT_THREHOLD) &&
1605 (priv->lq_mngr.agg_ctrl.auto_agg)) {
1606 priv->lq_mngr.agg_ctrl.tid_retry =
1607 TID_ALL_SPECIFIED;
1608 schedule_work(&priv->agg_work);
1609 }
1610 #endif /*CONFIG_IWLWIFI_HT_AGG */
1611 lq_data->action_counter = 0;
1612 rs_set_stay_in_table(0, lq_data);
1613 }
1614 } else {
1615 if ((!update_lq) && (!done_search) && (!lq_data->flush_timer))
1616 lq_data->flush_timer = jiffies;
1617 }
1618
1619 out:
1620 rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green);
1621 i = index;
1622 sta->last_txrate = i;
1623
1624 /* sta->txrate is an index to A mode rates which start
1625 * at IWL_FIRST_OFDM_RATE
1626 */
1627 if (lq_data->phymode == (u8) MODE_IEEE80211A)
1628 sta->txrate = i - IWL_FIRST_OFDM_RATE;
1629 else
1630 sta->txrate = i;
1631
1632 return;
1633 }
1634
1635
1636 static void rs_initialize_lq(struct iwl_priv *priv,
1637 struct sta_info *sta)
1638 {
1639 int i;
1640 struct iwl_rate_scale_priv *lq;
1641 struct iwl_scale_tbl_info *tbl;
1642 u8 active_tbl = 0;
1643 int rate_idx;
1644 u8 use_green = rs_use_green(priv);
1645 struct iwl_rate mcs_rate;
1646
1647 if (!sta || !sta->rate_ctrl_priv)
1648 goto out;
1649
1650 lq = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv;
1651 i = sta->last_txrate;
1652
1653 if ((lq->lq.sta_id == 0xff) &&
1654 (priv->iw_mode == IEEE80211_IF_TYPE_IBSS))
1655 goto out;
1656
1657 if (!lq->search_better_tbl)
1658 active_tbl = lq->active_tbl;
1659 else
1660 active_tbl = 1 - lq->active_tbl;
1661
1662 tbl = &(lq->lq_info[active_tbl]);
1663
1664 if ((i < 0) || (i >= IWL_RATE_COUNT))
1665 i = 0;
1666
1667 mcs_rate.rate_n_flags = iwl_rates[i].plcp ;
1668 mcs_rate.rate_n_flags |= RATE_MCS_ANT_B_MSK;
1669 mcs_rate.rate_n_flags &= ~RATE_MCS_ANT_A_MSK;
1670
1671 if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE)
1672 mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK;
1673
1674 tbl->antenna_type = ANT_AUX;
1675 rs_get_tbl_info_from_mcs(&mcs_rate, priv->phymode, tbl, &rate_idx);
1676 if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type))
1677 rs_toggle_antenna(&mcs_rate, tbl);
1678
1679 rs_mcs_from_tbl(&mcs_rate, tbl, rate_idx, use_green);
1680 tbl->current_rate.rate_n_flags = mcs_rate.rate_n_flags;
1681 rs_get_expected_tpt_table(lq, tbl);
1682 rs_fill_link_cmd(lq, &mcs_rate, &lq->lq);
1683 rs_send_lq_cmd(priv, &lq->lq, CMD_ASYNC);
1684 out:
1685 return;
1686 }
1687
1688 static struct ieee80211_rate *rs_get_lowest_rate(struct ieee80211_local
1689 *local)
1690 {
1691 struct ieee80211_hw_mode *mode = local->oper_hw_mode;
1692 int i;
1693
1694 for (i = 0; i < mode->num_rates; i++) {
1695 struct ieee80211_rate *rate = &mode->rates[i];
1696
1697 if (rate->flags & IEEE80211_RATE_SUPPORTED)
1698 return rate;
1699 }
1700
1701 return &mode->rates[0];
1702 }
1703
1704 static struct ieee80211_rate *rs_get_rate(void *priv_rate,
1705 struct net_device *dev,
1706 struct sk_buff *skb,
1707 struct rate_control_extra
1708 *extra)
1709 {
1710
1711 int i;
1712 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1713 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1714 struct sta_info *sta;
1715 u16 fc;
1716 struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
1717 struct iwl_rate_scale_priv *lq;
1718
1719 IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
1720
1721 memset(extra, 0, sizeof(*extra));
1722
1723 fc = le16_to_cpu(hdr->frame_control);
1724 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {
1725 /* Send management frames and broadcast/multicast data using
1726 * lowest rate. */
1727 /* TODO: this could probably be improved.. */
1728 return rs_get_lowest_rate(local);
1729 }
1730
1731 sta = sta_info_get(local, hdr->addr1);
1732
1733 if (!sta || !sta->rate_ctrl_priv) {
1734 if (sta)
1735 sta_info_put(sta);
1736 return rs_get_lowest_rate(local);
1737 }
1738
1739 lq = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv;
1740 i = sta->last_txrate;
1741
1742 if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && !lq->ibss_sta_added) {
1743 u8 sta_id = iwl_hw_find_station(priv, hdr->addr1);
1744 DECLARE_MAC_BUF(mac);
1745
1746 if (sta_id == IWL_INVALID_STATION) {
1747 IWL_DEBUG_RATE("LQ: ADD station %s\n",
1748 print_mac(mac, hdr->addr1));
1749 sta_id = iwl_add_station(priv,
1750 hdr->addr1, 0, CMD_ASYNC);
1751 }
1752 if ((sta_id != IWL_INVALID_STATION)) {
1753 lq->lq.sta_id = sta_id;
1754 lq->lq.rs_table[0].rate_n_flags = 0;
1755 lq->ibss_sta_added = 1;
1756 rs_initialize_lq(priv, sta);
1757 }
1758 if (!lq->ibss_sta_added)
1759 goto done;
1760 }
1761
1762 done:
1763 sta_info_put(sta);
1764 if ((i < 0) || (i > IWL_RATE_COUNT))
1765 return rs_get_lowest_rate(local);
1766
1767 return &priv->ieee_rates[i];
1768 }
1769
1770 static void *rs_alloc_sta(void *priv, gfp_t gfp)
1771 {
1772 struct iwl_rate_scale_priv *crl;
1773 int i, j;
1774
1775 IWL_DEBUG_RATE("create station rate scale window\n");
1776
1777 crl = kzalloc(sizeof(struct iwl_rate_scale_priv), gfp);
1778
1779 if (crl == NULL)
1780 return NULL;
1781 crl->lq.sta_id = 0xff;
1782
1783
1784 for (j = 0; j < LQ_SIZE; j++)
1785 for (i = 0; i < IWL_RATE_COUNT; i++)
1786 rs_rate_scale_clear_window(&(crl->lq_info[j].win[i]));
1787
1788 return crl;
1789 }
1790
1791 static void rs_rate_init(void *priv_rate, void *priv_sta,
1792 struct ieee80211_local *local,
1793 struct sta_info *sta)
1794 {
1795 int i, j;
1796 struct ieee80211_hw_mode *mode = local->oper_hw_mode;
1797 struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
1798 struct iwl_rate_scale_priv *crl = priv_sta;
1799
1800 crl->flush_timer = 0;
1801 crl->supp_rates = sta->supp_rates;
1802 sta->txrate = 3;
1803 for (j = 0; j < LQ_SIZE; j++)
1804 for (i = 0; i < IWL_RATE_COUNT; i++)
1805 rs_rate_scale_clear_window(&(crl->lq_info[j].win[i]));
1806
1807 IWL_DEBUG_RATE("rate scale global init\n");
1808 /* TODO: what is a good starting rate for STA? About middle? Maybe not
1809 * the lowest or the highest rate.. Could consider using RSSI from
1810 * previous packets? Need to have IEEE 802.1X auth succeed immediately
1811 * after assoc.. */
1812
1813 crl->ibss_sta_added = 0;
1814 if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
1815 u8 sta_id = iwl_hw_find_station(priv, sta->addr);
1816 DECLARE_MAC_BUF(mac);
1817
1818 /* for IBSS the call are from tasklet */
1819 IWL_DEBUG_HT("LQ: ADD station %s\n",
1820 print_mac(mac, sta->addr));
1821
1822 if (sta_id == IWL_INVALID_STATION) {
1823 IWL_DEBUG_RATE("LQ: ADD station %s\n",
1824 print_mac(mac, sta->addr));
1825 sta_id = iwl_add_station(priv,
1826 sta->addr, 0, CMD_ASYNC);
1827 }
1828 if ((sta_id != IWL_INVALID_STATION)) {
1829 crl->lq.sta_id = sta_id;
1830 crl->lq.rs_table[0].rate_n_flags = 0;
1831 }
1832 /* FIXME: this is w/a remove it later */
1833 priv->assoc_station_added = 1;
1834 }
1835
1836 for (i = 0; i < mode->num_rates; i++) {
1837 if ((sta->supp_rates & BIT(i)) &&
1838 (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED))
1839 sta->txrate = i;
1840 }
1841 sta->last_txrate = sta->txrate;
1842 /* For MODE_IEEE80211A mode cck rate are at end
1843 * rate table
1844 */
1845 if (local->hw.conf.phymode == MODE_IEEE80211A)
1846 sta->last_txrate += IWL_FIRST_OFDM_RATE;
1847
1848 crl->is_dup = priv->is_dup;
1849 crl->valid_antenna = priv->valid_antenna;
1850 crl->antenna = priv->antenna;
1851 crl->is_green = rs_use_green(priv);
1852 crl->active_rate = priv->active_rate;
1853 crl->active_rate &= ~(0x1000);
1854 crl->active_rate_basic = priv->active_rate_basic;
1855 crl->phymode = priv->phymode;
1856 #ifdef CONFIG_IWLWIFI_HT
1857 crl->active_siso_rate = (priv->current_assoc_ht.supp_rates[0] << 1);
1858 crl->active_siso_rate |= (priv->current_assoc_ht.supp_rates[0] & 0x1);
1859 crl->active_siso_rate &= ~((u16)0x2);
1860 crl->active_siso_rate = crl->active_siso_rate << IWL_FIRST_OFDM_RATE;
1861
1862 crl->active_mimo_rate = (priv->current_assoc_ht.supp_rates[1] << 1);
1863 crl->active_mimo_rate |= (priv->current_assoc_ht.supp_rates[1] & 0x1);
1864 crl->active_mimo_rate &= ~((u16)0x2);
1865 crl->active_mimo_rate = crl->active_mimo_rate << IWL_FIRST_OFDM_RATE;
1866 IWL_DEBUG_HT("MIMO RATE 0x%X SISO MASK 0x%X\n", crl->active_siso_rate,
1867 crl->active_mimo_rate);
1868 #endif /*CONFIG_IWLWIFI_HT*/
1869
1870 if (priv->assoc_station_added)
1871 priv->lq_mngr.lq_ready = 1;
1872
1873 rs_initialize_lq(priv, sta);
1874 }
1875
1876 static int rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
1877 struct iwl_rate *tx_mcs,
1878 struct iwl_link_quality_cmd *lq_cmd)
1879 {
1880 int index = 0;
1881 int rc = 0;
1882 int rate_idx;
1883 u8 ant_toggle_count = 0;
1884 u8 use_ht_possible = 1;
1885 u8 repeat_cur_rate = 0;
1886 struct iwl_rate new_rate;
1887 struct iwl_scale_tbl_info tbl_type = { 0 };
1888
1889 rs_get_tbl_info_from_mcs(tx_mcs, lq_data->phymode,
1890 &tbl_type, &rate_idx);
1891
1892 if (is_legacy(tbl_type.lq_type)) {
1893 ant_toggle_count = 1;
1894 repeat_cur_rate = IWL_NUMBER_TRY;
1895 } else
1896 repeat_cur_rate = IWL_HT_NUMBER_TRY;
1897
1898 lq_cmd->general_params.mimo_delimiter =
1899 is_mimo(tbl_type.lq_type) ? 1 : 0;
1900 lq_cmd->rs_table[index].rate_n_flags =
1901 cpu_to_le32(tx_mcs->rate_n_flags);
1902 new_rate.rate_n_flags = tx_mcs->rate_n_flags;
1903
1904 if (is_mimo(tbl_type.lq_type) || (tbl_type.antenna_type == ANT_MAIN))
1905 lq_cmd->general_params.single_stream_ant_msk = 1;
1906 else
1907 lq_cmd->general_params.single_stream_ant_msk = 2;
1908
1909 index++;
1910 repeat_cur_rate--;
1911
1912 while (index < LINK_QUAL_MAX_RETRY_NUM) {
1913 while (repeat_cur_rate && (index < LINK_QUAL_MAX_RETRY_NUM)) {
1914 if (is_legacy(tbl_type.lq_type)) {
1915 if (ant_toggle_count <
1916 NUM_TRY_BEFORE_ANTENNA_TOGGLE)
1917 ant_toggle_count++;
1918 else {
1919 rs_toggle_antenna(&new_rate, &tbl_type);
1920 ant_toggle_count = 1;
1921 }
1922 }
1923 lq_cmd->rs_table[index].rate_n_flags =
1924 cpu_to_le32(new_rate.rate_n_flags);
1925 repeat_cur_rate--;
1926 index++;
1927 }
1928
1929 rs_get_tbl_info_from_mcs(&new_rate, lq_data->phymode, &tbl_type,
1930 &rate_idx);
1931
1932 if (is_mimo(tbl_type.lq_type))
1933 lq_cmd->general_params.mimo_delimiter = index;
1934
1935 rs_get_lower_rate(lq_data, &tbl_type, rate_idx,
1936 use_ht_possible, &new_rate);
1937
1938 if (is_legacy(tbl_type.lq_type)) {
1939 if (ant_toggle_count < NUM_TRY_BEFORE_ANTENNA_TOGGLE)
1940 ant_toggle_count++;
1941 else {
1942 rs_toggle_antenna(&new_rate, &tbl_type);
1943 ant_toggle_count = 1;
1944 }
1945 repeat_cur_rate = IWL_NUMBER_TRY;
1946 } else
1947 repeat_cur_rate = IWL_HT_NUMBER_TRY;
1948
1949 use_ht_possible = 0;
1950
1951 lq_cmd->rs_table[index].rate_n_flags =
1952 cpu_to_le32(new_rate.rate_n_flags);
1953 /* lq_cmd->rs_table[index].rate_n_flags = 0x800d; */
1954
1955 index++;
1956 repeat_cur_rate--;
1957 }
1958
1959 /* lq_cmd->rs_table[0].rate_n_flags = 0x800d; */
1960
1961 lq_cmd->general_params.dual_stream_ant_msk = 3;
1962 lq_cmd->agg_params.agg_dis_start_th = 3;
1963 lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000);
1964 return rc;
1965 }
1966
1967 static void *rs_alloc(struct ieee80211_local *local)
1968 {
1969 return local->hw.priv;
1970 }
1971 /* rate scale requires free function to be implemented */
1972 static void rs_free(void *priv_rate)
1973 {
1974 return;
1975 }
1976
1977 static void rs_clear(void *priv_rate)
1978 {
1979 struct iwl_priv *priv = (struct iwl_priv *) priv_rate;
1980
1981 IWL_DEBUG_RATE("enter\n");
1982
1983 priv->lq_mngr.lq_ready = 0;
1984 #ifdef CONFIG_IWLWIFI_HT
1985 #ifdef CONFIG_IWLWIFI_HT_AGG
1986 if (priv->lq_mngr.agg_ctrl.granted_ba)
1987 iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED);
1988 #endif /*CONFIG_IWLWIFI_HT_AGG */
1989 #endif /* CONFIG_IWLWIFI_HT */
1990
1991 IWL_DEBUG_RATE("leave\n");
1992 }
1993
1994 static void rs_free_sta(void *priv, void *priv_sta)
1995 {
1996 struct iwl_rate_scale_priv *rs_priv = priv_sta;
1997
1998 IWL_DEBUG_RATE("enter\n");
1999 kfree(rs_priv);
2000 IWL_DEBUG_RATE("leave\n");
2001 }
2002
2003
2004 #ifdef CONFIG_MAC80211_DEBUGFS
2005 static int open_file_generic(struct inode *inode, struct file *file)
2006 {
2007 file->private_data = inode->i_private;
2008 return 0;
2009 }
2010
2011 static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2012 char __user *user_buf, size_t count, loff_t *ppos)
2013 {
2014 char buff[1024];
2015 int desc = 0;
2016 int i = 0;
2017
2018 struct iwl_rate_scale_priv *rs_priv = file->private_data;
2019
2020 desc += sprintf(buff+desc, "sta_id %d\n", rs_priv->lq.sta_id);
2021 desc += sprintf(buff+desc, "failed=%d success=%d rate=%X\n",
2022 rs_priv->total_failed, rs_priv->total_success,
2023 rs_priv->active_rate);
2024 desc += sprintf(buff+desc, "general:"
2025 "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
2026 rs_priv->lq.general_params.flags,
2027 rs_priv->lq.general_params.mimo_delimiter,
2028 rs_priv->lq.general_params.single_stream_ant_msk,
2029 rs_priv->lq.general_params.dual_stream_ant_msk);
2030
2031 desc += sprintf(buff+desc, "agg:"
2032 "time_limit=%d dist_start_th=%d frame_cnt_limit=%d\n",
2033 le16_to_cpu(rs_priv->lq.agg_params.agg_time_limit),
2034 rs_priv->lq.agg_params.agg_dis_start_th,
2035 rs_priv->lq.agg_params.agg_frame_cnt_limit);
2036
2037 desc += sprintf(buff+desc,
2038 "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",
2039 rs_priv->lq.general_params.start_rate_index[0],
2040 rs_priv->lq.general_params.start_rate_index[1],
2041 rs_priv->lq.general_params.start_rate_index[2],
2042 rs_priv->lq.general_params.start_rate_index[3]);
2043
2044
2045 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
2046 desc += sprintf(buff+desc, " rate[%d] 0x%X\n",
2047 i, le32_to_cpu(rs_priv->lq.rs_table[i].rate_n_flags));
2048
2049 return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
2050 }
2051
2052 static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
2053 .read = rs_sta_dbgfs_scale_table_read,
2054 .open = open_file_generic,
2055 };
2056
2057 static void rs_add_debugfs(void *priv, void *priv_sta,
2058 struct dentry *dir)
2059 {
2060 struct iwl_rate_scale_priv *rs_priv = priv_sta;
2061 rs_priv->rs_sta_dbgfs_scale_table_file =
2062 debugfs_create_file("rate_scale_table", 0444, dir,
2063 rs_priv, &rs_sta_dbgfs_scale_table_ops);
2064 }
2065
2066 static void rs_remove_debugfs(void *priv, void *priv_sta)
2067 {
2068 struct iwl_rate_scale_priv *rs_priv = priv_sta;
2069 debugfs_remove(rs_priv->rs_sta_dbgfs_scale_table_file);
2070 }
2071 #endif
2072
2073 static struct rate_control_ops rs_ops = {
2074 .module = NULL,
2075 .name = RS_NAME,
2076 .tx_status = rs_tx_status,
2077 .get_rate = rs_get_rate,
2078 .rate_init = rs_rate_init,
2079 .clear = rs_clear,
2080 .alloc = rs_alloc,
2081 .free = rs_free,
2082 .alloc_sta = rs_alloc_sta,
2083 .free_sta = rs_free_sta,
2084 #ifdef CONFIG_MAC80211_DEBUGFS
2085 .add_sta_debugfs = rs_add_debugfs,
2086 .remove_sta_debugfs = rs_remove_debugfs,
2087 #endif
2088 };
2089
2090 int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
2091 {
2092 struct ieee80211_local *local = hw_to_local(hw);
2093 struct iwl_priv *priv = hw->priv;
2094 struct iwl_rate_scale_priv *rs_priv;
2095 struct sta_info *sta;
2096 int count = 0, i;
2097 u32 samples = 0, success = 0, good = 0;
2098 unsigned long now = jiffies;
2099 u32 max_time = 0;
2100 u8 lq_type, antenna;
2101
2102 sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
2103 if (!sta || !sta->rate_ctrl_priv) {
2104 if (sta) {
2105 sta_info_put(sta);
2106 IWL_DEBUG_RATE("leave - no private rate data!\n");
2107 } else
2108 IWL_DEBUG_RATE("leave - no station!\n");
2109 return sprintf(buf, "station %d not found\n", sta_id);
2110 }
2111
2112 rs_priv = (void *)sta->rate_ctrl_priv;
2113
2114 lq_type = rs_priv->lq_info[rs_priv->active_tbl].lq_type;
2115 antenna = rs_priv->lq_info[rs_priv->active_tbl].antenna_type;
2116
2117 if (is_legacy(lq_type))
2118 i = IWL_RATE_54M_INDEX;
2119 else
2120 i = IWL_RATE_60M_INDEX;
2121 while (1) {
2122 u64 mask;
2123 int j;
2124 int active = rs_priv->active_tbl;
2125
2126 count +=
2127 sprintf(&buf[count], " %2dMbs: ", iwl_rates[i].ieee / 2);
2128
2129 mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1));
2130 for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1)
2131 buf[count++] =
2132 (rs_priv->lq_info[active].win[i].data & mask)
2133 ? '1' : '0';
2134
2135 samples += rs_priv->lq_info[active].win[i].counter;
2136 good += rs_priv->lq_info[active].win[i].success_counter;
2137 success += rs_priv->lq_info[active].win[i].success_counter *
2138 iwl_rates[i].ieee;
2139
2140 if (rs_priv->lq_info[active].win[i].stamp) {
2141 int delta =
2142 jiffies_to_msecs(now -
2143 rs_priv->lq_info[active].win[i].stamp);
2144
2145 if (delta > max_time)
2146 max_time = delta;
2147
2148 count += sprintf(&buf[count], "%5dms\n", delta);
2149 } else
2150 buf[count++] = '\n';
2151
2152 j = iwl_get_prev_ieee_rate(i);
2153 if (j == i)
2154 break;
2155 i = j;
2156 }
2157
2158 /* Display the average rate of all samples taken.
2159 *
2160 * NOTE: We multiple # of samples by 2 since the IEEE measurement
2161 * added from iwl_rates is actually 2X the rate */
2162 if (samples)
2163 count += sprintf(&buf[count],
2164 "\nAverage rate is %3d.%02dMbs over last %4dms\n"
2165 "%3d%% success (%d good packets over %d tries)\n",
2166 success / (2 * samples), (success * 5 / samples) % 10,
2167 max_time, good * 100 / samples, good, samples);
2168 else
2169 count += sprintf(&buf[count], "\nAverage rate: 0Mbs\n");
2170 count += sprintf(&buf[count], "\nrate scale type %d anntena %d "
2171 "active_search %d rate index %d\n", lq_type, antenna,
2172 rs_priv->search_better_tbl, sta->last_txrate);
2173
2174 sta_info_put(sta);
2175 return count;
2176 }
2177
2178 void iwl_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
2179 {
2180 struct iwl_priv *priv = hw->priv;
2181
2182 priv->lq_mngr.lq_ready = 1;
2183 }
2184
2185 void iwl_rate_control_register(struct ieee80211_hw *hw)
2186 {
2187 ieee80211_rate_control_register(&rs_ops);
2188 }
2189
2190 void iwl_rate_control_unregister(struct ieee80211_hw *hw)
2191 {
2192 ieee80211_rate_control_unregister(&rs_ops);
2193 }
2194
This page took 0.287311 seconds and 5 git commands to generate.