]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - drivers/net/wireless/iwlwifi/iwl-agn-rs.c
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[mirror_ubuntu-zesty-kernel.git] / drivers / net / wireless / iwlwifi / iwl-agn-rs.c
CommitLineData
b481de9c
ZY
1/******************************************************************************
2 *
1f447808 3 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
b481de9c
ZY
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:
759ef89f 22 * Intel Linux Wireless <ilw@linux.intel.com>
b481de9c
ZY
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>
5a0e3ad6 29#include <linux/slab.h>
b481de9c
ZY
30#include <linux/wireless.h>
31#include <net/mac80211.h>
b481de9c
ZY
32
33#include <linux/netdevice.h>
34#include <linux/etherdevice.h>
35#include <linux/delay.h>
36
37#include <linux/workqueue.h>
38
3e0d4cb1 39#include "iwl-dev.h"
be1f3ab6 40#include "iwl-sta.h"
857485c0 41#include "iwl-core.h"
b481de9c 42
e227ceac 43#define RS_NAME "iwl-agn-rs"
b481de9c 44
aade00ce 45#define NUM_TRY_BEFORE_ANT_TOGGLE 1
b481de9c
ZY
46#define IWL_NUMBER_TRY 1
47#define IWL_HT_NUMBER_TRY 3
48
77626355
BC
49#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */
50#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */
51#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */
52
7d049e5a
AM
53/* max allowed rate miss before sync LQ cmd */
54#define IWL_MISSED_RATE_MAX 15
77626355 55/* max time to accum history 2 seconds */
447fee70 56#define IWL_RATE_SCALE_FLUSH_INTVL (3*HZ)
b481de9c
ZY
57
58static u8 rs_ht_to_legacy[] = {
59 IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
60 IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
61 IWL_RATE_6M_INDEX,
62 IWL_RATE_6M_INDEX, IWL_RATE_9M_INDEX,
63 IWL_RATE_12M_INDEX, IWL_RATE_18M_INDEX,
64 IWL_RATE_24M_INDEX, IWL_RATE_36M_INDEX,
65 IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX
66};
67
aade00ce
GC
68static const u8 ant_toggle_lookup[] = {
69 /*ANT_NONE -> */ ANT_NONE,
70 /*ANT_A -> */ ANT_B,
71 /*ANT_B -> */ ANT_C,
72 /*ANT_AB -> */ ANT_BC,
73 /*ANT_C -> */ ANT_A,
74 /*ANT_AC -> */ ANT_AB,
75 /*ANT_BC -> */ ANT_AC,
76 /*ANT_ABC -> */ ANT_ABC,
77};
78
c79dd5b5 79static void rs_rate_scale_perform(struct iwl_priv *priv,
514d65c1 80 struct sk_buff *skb,
4b7679a5
JB
81 struct ieee80211_sta *sta,
82 struct iwl_lq_sta *lq_sta);
46f9381a 83static void rs_fill_link_cmd(struct iwl_priv *priv,
e227ceac 84 struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
b481de9c
ZY
85
86
98d7e09a 87#ifdef CONFIG_MAC80211_DEBUGFS
e227ceac
TW
88static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
89 u32 *rate_n_flags, int index);
98d7e09a 90#else
e227ceac
TW
91static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
92 u32 *rate_n_flags, int index)
98d7e09a
ZY
93{}
94#endif
77626355 95
e3949d62
DH
96/**
97 * The following tables contain the expected throughput metrics for all rates
98 *
99 * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits
100 *
101 * where invalid entries are zeros.
102 *
103 * CCK rates are only valid in legacy table and will only be used in G
104 * (2.4 GHz) band.
77626355 105 */
584a0f00 106
e3949d62
DH
107static s32 expected_tpt_legacy[IWL_RATE_COUNT] = {
108 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0
b481de9c
ZY
109};
110
e3949d62
DH
111static s32 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = {
112 {0, 0, 0, 0, 42, 0, 76, 102, 124, 158, 183, 193, 202}, /* Norm */
113 {0, 0, 0, 0, 46, 0, 82, 110, 132, 167, 192, 202, 210}, /* SGI */
114 {0, 0, 0, 0, 48, 0, 93, 135, 176, 251, 319, 351, 381}, /* AGG */
115 {0, 0, 0, 0, 53, 0, 102, 149, 193, 275, 348, 381, 413}, /* AGG+SGI */
b481de9c
ZY
116};
117
e3949d62
DH
118static s32 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = {
119 {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257}, /* Norm */
120 {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264}, /* SGI */
121 {0, 0, 0, 0, 96, 0, 182, 259, 328, 451, 553, 598, 640}, /* AGG */
122 {0, 0, 0, 0, 106, 0, 199, 282, 357, 487, 593, 640, 683}, /* AGG+SGI */
b481de9c
ZY
123};
124
e3949d62
DH
125static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = {
126 {0, 0, 0, 0, 74, 0, 123, 155, 179, 213, 235, 243, 250}, /* Norm */
127 {0, 0, 0, 0, 81, 0, 131, 164, 187, 221, 242, 250, 256}, /* SGI */
128 {0, 0, 0, 0, 92, 0, 175, 250, 317, 436, 534, 578, 619}, /* AGG */
129 {0, 0, 0, 0, 102, 0, 192, 273, 344, 470, 573, 619, 660}, /* AGG+SGI*/
b481de9c
ZY
130};
131
e3949d62
DH
132static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = {
133 {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289}, /* Norm */
134 {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293}, /* SGI */
135 {0, 0, 0, 0, 180, 0, 327, 446, 545, 708, 828, 878, 922}, /* AGG */
136 {0, 0, 0, 0, 197, 0, 355, 481, 584, 752, 872, 922, 966}, /* AGG+SGI */
b481de9c
ZY
137};
138
e3949d62
DH
139static s32 expected_tpt_mimo3_20MHz[4][IWL_RATE_COUNT] = {
140 {0, 0, 0, 0, 99, 0, 153, 186, 208, 239, 256, 263, 268}, /* Norm */
141 {0, 0, 0, 0, 106, 0, 162, 194, 215, 246, 262, 268, 273}, /* SGI */
142 {0, 0, 0, 0, 134, 0, 249, 346, 431, 574, 685, 732, 775}, /* AGG */
143 {0, 0, 0, 0, 148, 0, 272, 376, 465, 614, 727, 775, 818}, /* AGG+SGI */
584a0f00
WYG
144};
145
e3949d62
DH
146static s32 expected_tpt_mimo3_40MHz[4][IWL_RATE_COUNT] = {
147 {0, 0, 0, 0, 152, 0, 211, 239, 255, 279, 290, 294, 297}, /* Norm */
148 {0, 0, 0, 0, 160, 0, 219, 245, 261, 284, 294, 297, 300}, /* SGI */
149 {0, 0, 0, 0, 254, 0, 443, 584, 695, 868, 984, 1030, 1070}, /* AGG */
150 {0, 0, 0, 0, 277, 0, 478, 624, 737, 911, 1026, 1070, 1109}, /* AGG+SGI */
584a0f00
WYG
151};
152
12b96817 153/* mbps, mcs */
79496738 154static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
e3949d62
DH
155 { "1", "BPSK DSSS"},
156 { "2", "QPSK DSSS"},
157 {"5.5", "BPSK CCK"},
158 { "11", "QPSK CCK"},
159 { "6", "BPSK 1/2"},
160 { "9", "BPSK 1/2"},
161 { "12", "QPSK 1/2"},
162 { "18", "QPSK 3/4"},
163 { "24", "16QAM 1/2"},
164 { "36", "16QAM 3/4"},
165 { "48", "64QAM 2/3"},
166 { "54", "64QAM 3/4"},
167 { "60", "64QAM 5/6"},
12b96817
WYG
168};
169
a9c146b3
WYG
170#define MCS_INDEX_PER_STREAM (8)
171
39e88504 172static inline u8 rs_extract_rate(u32 rate_n_flags)
b481de9c
ZY
173{
174 return (u8)(rate_n_flags & 0xFF);
175}
176
e227ceac 177static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
b481de9c
ZY
178{
179 window->data = 0;
180 window->success_counter = 0;
181 window->success_ratio = IWL_INVALID_VALUE;
182 window->counter = 0;
183 window->average_tpt = IWL_INVALID_VALUE;
184 window->stamp = 0;
b481de9c
ZY
185}
186
aade00ce
GC
187static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
188{
3ac7f146 189 return (ant_type & valid_antenna) == ant_type;
aade00ce
GC
190}
191
0c11b4de
RR
192/*
193 * removes the old data from the statistics. All data that is older than
194 * TID_MAX_TIME_DIFF, will be deleted.
195 */
e227ceac 196static void rs_tl_rm_old_stats(struct iwl_traffic_load *tl, u32 curr_time)
0c11b4de
RR
197{
198 /* The oldest age we want to keep */
199 u32 oldest_time = curr_time - TID_MAX_TIME_DIFF;
200
201 while (tl->queue_count &&
202 (tl->time_stamp < oldest_time)) {
203 tl->total -= tl->packet_count[tl->head];
204 tl->packet_count[tl->head] = 0;
205 tl->time_stamp += TID_QUEUE_CELL_SPACING;
206 tl->queue_count--;
207 tl->head++;
208 if (tl->head >= TID_QUEUE_MAX_SIZE)
209 tl->head = 0;
210 }
211}
212
213/*
214 * increment traffic load value for tid and also remove
215 * any old values if passed the certain time period
216 */
e227ceac 217static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
faa29718 218 struct ieee80211_hdr *hdr)
0c11b4de
RR
219{
220 u32 curr_time = jiffies_to_msecs(jiffies);
221 u32 time_diff;
222 s32 index;
e227ceac 223 struct iwl_traffic_load *tl = NULL;
54dbb525 224 u8 tid;
0c11b4de 225
417f114b 226 if (ieee80211_is_data_qos(hdr->frame_control)) {
fd7c8a40 227 u8 *qc = ieee80211_get_qos_ctl(hdr);
54dbb525
TW
228 tid = qc[0] & 0xf;
229 } else
faa29718 230 return MAX_TID_COUNT;
0c11b4de 231
e6a6cf4c
RC
232 if (unlikely(tid >= TID_MAX_LOAD_COUNT))
233 return MAX_TID_COUNT;
234
0c11b4de
RR
235 tl = &lq_data->load[tid];
236
237 curr_time -= curr_time % TID_ROUND_VALUE;
238
239 /* Happens only for the first packet. Initialize the data */
240 if (!(tl->queue_count)) {
241 tl->total = 1;
242 tl->time_stamp = curr_time;
243 tl->queue_count = 1;
244 tl->head = 0;
245 tl->packet_count[0] = 1;
faa29718 246 return MAX_TID_COUNT;
0c11b4de
RR
247 }
248
249 time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);
250 index = time_diff / TID_QUEUE_CELL_SPACING;
251
252 /* The history is too long: remove data that is older than */
253 /* TID_MAX_TIME_DIFF */
254 if (index >= TID_QUEUE_MAX_SIZE)
255 rs_tl_rm_old_stats(tl, curr_time);
256
257 index = (tl->head + index) % TID_QUEUE_MAX_SIZE;
258 tl->packet_count[index] = tl->packet_count[index] + 1;
259 tl->total = tl->total + 1;
260
261 if ((index + 1) > tl->queue_count)
262 tl->queue_count = index + 1;
faa29718
RR
263
264 return tid;
0c11b4de
RR
265}
266
267/*
268 get the traffic load value for tid
269*/
e227ceac 270static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
0c11b4de
RR
271{
272 u32 curr_time = jiffies_to_msecs(jiffies);
273 u32 time_diff;
274 s32 index;
e227ceac 275 struct iwl_traffic_load *tl = NULL;
0c11b4de
RR
276
277 if (tid >= TID_MAX_LOAD_COUNT)
278 return 0;
279
280 tl = &(lq_data->load[tid]);
281
282 curr_time -= curr_time % TID_ROUND_VALUE;
283
284 if (!(tl->queue_count))
285 return 0;
286
287 time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);
288 index = time_diff / TID_QUEUE_CELL_SPACING;
289
290 /* The history is too long: remove data that is older than */
291 /* TID_MAX_TIME_DIFF */
292 if (index >= TID_QUEUE_MAX_SIZE)
293 rs_tl_rm_old_stats(tl, curr_time);
294
295 return tl->total;
296}
297
c79dd5b5 298static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
e227ceac 299 struct iwl_lq_sta *lq_data, u8 tid,
4b7679a5 300 struct ieee80211_sta *sta)
0c11b4de 301{
45d42700
WYG
302 int ret;
303
ff550cb4 304 if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
e1623446 305 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
e174961c 306 sta->addr, tid);
45d42700
WYG
307 ret = ieee80211_start_tx_ba_session(sta, tid);
308 if (ret == -EAGAIN) {
309 /*
310 * driver and mac80211 is out of sync
311 * this might be cause by reloading firmware
312 * stop the tx ba session here
313 */
314 IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n",
315 tid);
316 ret = ieee80211_stop_tx_ba_session(sta, tid,
317 WLAN_BACK_INITIATOR);
318 }
0c11b4de
RR
319 }
320}
321
c79dd5b5 322static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
e227ceac 323 struct iwl_lq_sta *lq_data,
4b7679a5 324 struct ieee80211_sta *sta)
0c11b4de
RR
325{
326 if ((tid < TID_MAX_LOAD_COUNT))
327 rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
328 else if (tid == IWL_AGG_ALL_TID)
329 for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++)
330 rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
47eef9bd
WYG
331 if (priv->cfg->use_rts_for_ht) {
332 /*
333 * switch to RTS/CTS if it is the prefer protection method
334 * for HT traffic
335 */
336 IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n");
337 priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
338 iwlcore_commit_rxon(priv);
339 }
0c11b4de
RR
340}
341
39e88504 342static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
fde0db31 343{
3ac7f146
TW
344 return !!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
345 !!(rate_n_flags & RATE_MCS_ANT_B_MSK) +
346 !!(rate_n_flags & RATE_MCS_ANT_C_MSK);
fde0db31
GC
347}
348
77626355
BC
349/**
350 * rs_collect_tx_data - Update the success/failure sliding window
351 *
352 * We keep a sliding window of the last 62 packets transmitted
353 * at this rate. window->data contains the bitmask of successful
354 * packets.
355 */
e227ceac 356static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
e3949d62 357 int scale_index, s32 tpt, int attempts,
99556438 358 int successes)
b481de9c 359{
e227ceac 360 struct iwl_rate_scale_data *window = NULL;
39e88504 361 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
b481de9c
ZY
362 s32 fail_count;
363
dc2453ae
TW
364 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
365 return -EINVAL;
b481de9c 366
e3949d62 367 /* Select window for current tx bit rate */
b481de9c
ZY
368 window = &(windows[scale_index]);
369
77626355
BC
370 /*
371 * Keep track of only the latest 62 tx frame attempts in this rate's
372 * history window; anything older isn't really relevant any more.
373 * If we have filled up the sliding window, drop the oldest attempt;
374 * if the oldest attempt (highest bit in bitmap) shows "success",
375 * subtract "1" from the success counter (this is the main reason
376 * we keep these bitmaps!).
377 */
e3949d62 378 while (attempts > 0) {
39e88504
GC
379 if (window->counter >= IWL_RATE_MAX_WINDOW) {
380
381 /* remove earliest */
382 window->counter = IWL_RATE_MAX_WINDOW - 1;
383
99556438
RR
384 if (window->data & mask) {
385 window->data &= ~mask;
39e88504 386 window->success_counter--;
99556438 387 }
b481de9c 388 }
b481de9c 389
99556438
RR
390 /* Increment frames-attempted counter */
391 window->counter++;
392
e3949d62 393 /* Shift bitmap by one frame to throw away oldest history */
90d7795e 394 window->data <<= 1;
e3949d62
DH
395
396 /* Mark the most recent #successes attempts as successful */
99556438 397 if (successes > 0) {
39e88504 398 window->success_counter++;
99556438
RR
399 window->data |= 0x1;
400 successes--;
401 }
77626355 402
e3949d62 403 attempts--;
b481de9c
ZY
404 }
405
77626355 406 /* Calculate current success ratio, avoid divide-by-0! */
b481de9c
ZY
407 if (window->counter > 0)
408 window->success_ratio = 128 * (100 * window->success_counter)
409 / window->counter;
410 else
411 window->success_ratio = IWL_INVALID_VALUE;
412
413 fail_count = window->counter - window->success_counter;
414
77626355 415 /* Calculate average throughput, if we have enough history. */
b481de9c
ZY
416 if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||
417 (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))
418 window->average_tpt = (window->success_ratio * tpt + 64) / 128;
419 else
420 window->average_tpt = IWL_INVALID_VALUE;
421
77626355 422 /* Tag this window as having been updated */
b481de9c
ZY
423 window->stamp = jiffies;
424
dc2453ae 425 return 0;
b481de9c
ZY
426}
427
77626355
BC
428/*
429 * Fill uCode API rate_n_flags field, based on "search" or "active" table.
430 */
39e88504 431/* FIXME:RS:remove this function and put the flags statically in the table */
978785a3
TW
432static u32 rate_n_flags_from_tbl(struct iwl_priv *priv,
433 struct iwl_scale_tbl_info *tbl,
434 int index, u8 use_green)
b481de9c 435{
39e88504
GC
436 u32 rate_n_flags = 0;
437
b481de9c 438 if (is_legacy(tbl->lq_type)) {
1826dcc0 439 rate_n_flags = iwl_rates[index].plcp;
b481de9c 440 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
39e88504 441 rate_n_flags |= RATE_MCS_CCK_MSK;
b481de9c 442
fde0db31
GC
443 } else if (is_Ht(tbl->lq_type)) {
444 if (index > IWL_LAST_OFDM_RATE) {
978785a3 445 IWL_ERR(priv, "Invalid HT rate index %d\n", index);
b481de9c 446 index = IWL_LAST_OFDM_RATE;
fde0db31 447 }
39e88504 448 rate_n_flags = RATE_MCS_HT_MSK;
fde0db31
GC
449
450 if (is_siso(tbl->lq_type))
1826dcc0 451 rate_n_flags |= iwl_rates[index].plcp_siso;
fde0db31 452 else if (is_mimo2(tbl->lq_type))
1826dcc0 453 rate_n_flags |= iwl_rates[index].plcp_mimo2;
fde0db31 454 else
1826dcc0 455 rate_n_flags |= iwl_rates[index].plcp_mimo3;
b481de9c 456 } else {
978785a3 457 IWL_ERR(priv, "Invalid tbl->lq_type %d\n", tbl->lq_type);
b481de9c
ZY
458 }
459
39e88504 460 rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) &
fde0db31 461 RATE_MCS_ANT_ABC_MSK);
b481de9c 462
39e88504 463 if (is_Ht(tbl->lq_type)) {
7aafef1c 464 if (tbl->is_ht40) {
39e88504
GC
465 if (tbl->is_dup)
466 rate_n_flags |= RATE_MCS_DUP_MSK;
467 else
7aafef1c 468 rate_n_flags |= RATE_MCS_HT40_MSK;
39e88504
GC
469 }
470 if (tbl->is_SGI)
471 rate_n_flags |= RATE_MCS_SGI_MSK;
472
473 if (use_green) {
474 rate_n_flags |= RATE_MCS_GF_MSK;
475 if (is_siso(tbl->lq_type) && tbl->is_SGI) {
476 rate_n_flags &= ~RATE_MCS_SGI_MSK;
978785a3 477 IWL_ERR(priv, "GF was set with SGI:SISO\n");
39e88504
GC
478 }
479 }
b481de9c 480 }
39e88504 481 return rate_n_flags;
b481de9c
ZY
482}
483
77626355
BC
484/*
485 * Interpret uCode API's rate_n_flags format,
486 * fill "search" or "active" tx mode table.
487 */
39e88504 488static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
8318d78a 489 enum ieee80211_band band,
e227ceac 490 struct iwl_scale_tbl_info *tbl,
b481de9c
ZY
491 int *rate_idx)
492{
39e88504
GC
493 u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK);
494 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);
495 u8 mcs;
b481de9c 496
e7d326ac 497 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
b481de9c 498
fde0db31 499 if (*rate_idx == IWL_RATE_INVALID) {
b481de9c 500 *rate_idx = -1;
dc2453ae 501 return -EINVAL;
b481de9c 502 }
77626355 503 tbl->is_SGI = 0; /* default legacy setup */
7aafef1c 504 tbl->is_ht40 = 0;
b481de9c 505 tbl->is_dup = 0;
fde0db31
GC
506 tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
507 tbl->lq_type = LQ_NONE;
d6e93399 508 tbl->max_search = IWL_MAX_SEARCH;
b481de9c 509
77626355 510 /* legacy rate format */
39e88504 511 if (!(rate_n_flags & RATE_MCS_HT_MSK)) {
fde0db31 512 if (num_of_ant == 1) {
8318d78a 513 if (band == IEEE80211_BAND_5GHZ)
b481de9c
ZY
514 tbl->lq_type = LQ_A;
515 else
516 tbl->lq_type = LQ_G;
b481de9c 517 }
fde0db31 518 /* HT rate format */
b481de9c 519 } else {
39e88504 520 if (rate_n_flags & RATE_MCS_SGI_MSK)
b481de9c
ZY
521 tbl->is_SGI = 1;
522
7aafef1c 523 if ((rate_n_flags & RATE_MCS_HT40_MSK) ||
39e88504 524 (rate_n_flags & RATE_MCS_DUP_MSK))
7aafef1c 525 tbl->is_ht40 = 1;
b481de9c 526
39e88504 527 if (rate_n_flags & RATE_MCS_DUP_MSK)
b481de9c 528 tbl->is_dup = 1;
fde0db31 529
39e88504 530 mcs = rs_extract_rate(rate_n_flags);
fde0db31 531
39e88504
GC
532 /* SISO */
533 if (mcs <= IWL_RATE_SISO_60M_PLCP) {
fde0db31
GC
534 if (num_of_ant == 1)
535 tbl->lq_type = LQ_SISO; /*else NONE*/
536 /* MIMO2 */
39e88504 537 } else if (mcs <= IWL_RATE_MIMO2_60M_PLCP) {
fde0db31
GC
538 if (num_of_ant == 2)
539 tbl->lq_type = LQ_MIMO2;
540 /* MIMO3 */
541 } else {
d6e93399
MA
542 if (num_of_ant == 3) {
543 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
fde0db31 544 tbl->lq_type = LQ_MIMO3;
d6e93399 545 }
fde0db31 546 }
b481de9c
ZY
547 }
548 return 0;
549}
aade00ce
GC
550
551/* switch to another antenna/antennas and return 1 */
552/* if no other valid antenna found, return 0 */
553static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
e227ceac 554 struct iwl_scale_tbl_info *tbl)
b481de9c 555{
aade00ce
GC
556 u8 new_ant_type;
557
558 if (!tbl->ant_type || tbl->ant_type > ANT_ABC)
559 return 0;
560
561 if (!rs_is_valid_ant(valid_ant, tbl->ant_type))
562 return 0;
563
564 new_ant_type = ant_toggle_lookup[tbl->ant_type];
565
566 while ((new_ant_type != tbl->ant_type) &&
567 !rs_is_valid_ant(valid_ant, new_ant_type))
568 new_ant_type = ant_toggle_lookup[new_ant_type];
569
570 if (new_ant_type == tbl->ant_type)
571 return 0;
572
573 tbl->ant_type = new_ant_type;
574 *rate_n_flags &= ~RATE_MCS_ANT_ABC_MSK;
575 *rate_n_flags |= new_ant_type << RATE_MCS_ANT_POS;
576 return 1;
b481de9c
ZY
577}
578
b261793d
DH
579/**
580 * Green-field mode is valid if the station supports it and
581 * there are no non-GF stations present in the BSS.
582 */
583static inline u8 rs_use_green(struct ieee80211_sta *sta,
fad95bf5 584 struct iwl_ht_config *ht_conf)
b481de9c 585{
b261793d
DH
586 return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
587 !(ht_conf->non_GF_STA_present);
b481de9c
ZY
588}
589
590/**
591 * rs_get_supported_rates - get the available rates
592 *
593 * if management frame or broadcast frame only return
594 * basic available rates.
595 *
596 */
e227ceac
TW
597static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
598 struct ieee80211_hdr *hdr,
599 enum iwl_table_type rate_type)
b481de9c 600{
eecd6e57
GC
601 if (hdr && is_multicast_ether_addr(hdr->addr1) &&
602 lq_sta->active_rate_basic)
603 return lq_sta->active_rate_basic;
604
605 if (is_legacy(rate_type)) {
606 return lq_sta->active_legacy_rate;
607 } else {
b481de9c 608 if (is_siso(rate_type))
eecd6e57 609 return lq_sta->active_siso_rate;
fde0db31 610 else if (is_mimo2(rate_type))
eecd6e57 611 return lq_sta->active_mimo2_rate;
b481de9c 612 else
eecd6e57 613 return lq_sta->active_mimo3_rate;
c33104f0 614 }
b481de9c
ZY
615}
616
bf403db8
EK
617static u16 rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask,
618 int rate_type)
b481de9c
ZY
619{
620 u8 high = IWL_RATE_INVALID;
621 u8 low = IWL_RATE_INVALID;
622
01ebd063 623 /* 802.11A or ht walks to the next literal adjacent rate in
b481de9c
ZY
624 * the rate table */
625 if (is_a_band(rate_type) || !is_legacy(rate_type)) {
626 int i;
627 u32 mask;
628
629 /* Find the previous rate that is in the rate mask */
630 i = index - 1;
631 for (mask = (1 << i); i >= 0; i--, mask >>= 1) {
632 if (rate_mask & mask) {
633 low = i;
634 break;
635 }
636 }
637
638 /* Find the next rate that is in the rate mask */
639 i = index + 1;
640 for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) {
641 if (rate_mask & mask) {
642 high = i;
643 break;
644 }
645 }
646
647 return (high << 8) | low;
648 }
649
650 low = index;
651 while (low != IWL_RATE_INVALID) {
1826dcc0 652 low = iwl_rates[low].prev_rs;
b481de9c
ZY
653 if (low == IWL_RATE_INVALID)
654 break;
655 if (rate_mask & (1 << low))
656 break;
e1623446 657 IWL_DEBUG_RATE(priv, "Skipping masked lower rate: %d\n", low);
b481de9c
ZY
658 }
659
660 high = index;
661 while (high != IWL_RATE_INVALID) {
1826dcc0 662 high = iwl_rates[high].next_rs;
b481de9c
ZY
663 if (high == IWL_RATE_INVALID)
664 break;
665 if (rate_mask & (1 << high))
666 break;
e1623446 667 IWL_DEBUG_RATE(priv, "Skipping masked higher rate: %d\n", high);
b481de9c
ZY
668 }
669
670 return (high << 8) | low;
671}
672
e227ceac
TW
673static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
674 struct iwl_scale_tbl_info *tbl,
675 u8 scale_index, u8 ht_possible)
b481de9c 676{
b481de9c
ZY
677 s32 low;
678 u16 rate_mask;
679 u16 high_low;
680 u8 switch_to_legacy = 0;
c33104f0 681 u8 is_green = lq_sta->is_green;
2ff6578b 682 struct iwl_priv *priv = lq_sta->drv;
b481de9c
ZY
683
684 /* check if we need to switch from HT to legacy rates.
685 * assumption is that mandatory rates (1Mbps or 6Mbps)
686 * are always supported (spec demand) */
687 if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) {
688 switch_to_legacy = 1;
689 scale_index = rs_ht_to_legacy[scale_index];
8318d78a 690 if (lq_sta->band == IEEE80211_BAND_5GHZ)
b481de9c
ZY
691 tbl->lq_type = LQ_A;
692 else
693 tbl->lq_type = LQ_G;
694
69fdb309 695 if (num_of_ant(tbl->ant_type) > 1)
2ff6578b
WYG
696 tbl->ant_type =
697 first_antenna(priv->hw_params.valid_tx_ant);
b481de9c 698
7aafef1c 699 tbl->is_ht40 = 0;
b481de9c 700 tbl->is_SGI = 0;
d6e93399 701 tbl->max_search = IWL_MAX_SEARCH;
b481de9c
ZY
702 }
703
eecd6e57 704 rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type);
b481de9c 705
77626355 706 /* Mask with station rate restriction */
b481de9c 707 if (is_legacy(tbl->lq_type)) {
77626355 708 /* supp_rates has no CCK bits in A mode */
8318d78a 709 if (lq_sta->band == IEEE80211_BAND_5GHZ)
b481de9c 710 rate_mask = (u16)(rate_mask &
c33104f0 711 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
b481de9c 712 else
c33104f0 713 rate_mask = (u16)(rate_mask & lq_sta->supp_rates);
b481de9c
ZY
714 }
715
77626355 716 /* If we switched from HT to legacy, check current rate */
dc2453ae 717 if (switch_to_legacy && (rate_mask & (1 << scale_index))) {
39e88504
GC
718 low = scale_index;
719 goto out;
b481de9c
ZY
720 }
721
bf403db8
EK
722 high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask,
723 tbl->lq_type);
b481de9c
ZY
724 low = high_low & 0xff;
725
39e88504
GC
726 if (low == IWL_RATE_INVALID)
727 low = scale_index;
728
729out:
978785a3 730 return rate_n_flags_from_tbl(lq_sta->drv, tbl, low, is_green);
b481de9c
ZY
731}
732
95407aa4
DH
733/*
734 * Simple function to compare two rate scale table types
735 */
736static bool table_type_matches(struct iwl_scale_tbl_info *a,
737 struct iwl_scale_tbl_info *b)
738{
739 return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
740 (a->is_SGI == b->is_SGI);
741}
742/*
743 * Static function to get the expected throughput from an iwl_scale_tbl_info
744 * that wraps a NULL pointer check
745 */
746static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
747{
748 if (tbl->expected_tpt)
749 return tbl->expected_tpt[rs_index];
750 return 0;
751}
752
77626355
BC
753/*
754 * mac80211 sends us Tx status
755 */
4b7679a5
JB
756static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
757 struct ieee80211_sta *sta, void *priv_sta,
e039fa4a 758 struct sk_buff *skb)
b481de9c 759{
95407aa4
DH
760 int legacy_success;
761 int retries;
762 int rs_index, mac_index, i;
417f114b 763 struct iwl_lq_sta *lq_sta = priv_sta;
66c73db7 764 struct iwl_link_quality_cmd *table;
b481de9c 765 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
4b7679a5 766 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
e039fa4a 767 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
e227ceac 768 struct iwl_rate_scale_data *window = NULL;
5027309b 769 enum mac80211_rate_control_flags mac_flags;
39e88504 770 u32 tx_rate;
e227ceac 771 struct iwl_scale_tbl_info tbl_type;
95407aa4 772 struct iwl_scale_tbl_info *curr_tbl, *other_tbl;
b481de9c
ZY
773 s32 tpt = 0;
774
e1623446 775 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
b481de9c 776
417f114b 777 if (!ieee80211_is_data(hdr->frame_control) ||
514d65c1 778 info->flags & IEEE80211_TX_CTL_NO_ACK)
b481de9c
ZY
779 return;
780
e3949d62 781 /* This packet was aggregated but doesn't carry status info */
e039fa4a
JB
782 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
783 !(info->flags & IEEE80211_TX_STAT_AMPDU))
99556438
RR
784 return;
785
05c914fe 786 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
c33104f0 787 !lq_sta->ibss_sta_added)
95407aa4 788 return;
b481de9c 789
77626355
BC
790 /*
791 * Ignore this Tx frame response if its initial rate doesn't match
792 * that of latest Link Quality command. There may be stragglers
793 * from a previous Link Quality command, but we're no longer interested
794 * in those; they're either from the "active" mode while we're trying
795 * to check "search" mode, or a prior "search" mode after we've moved
796 * to a new "search" mode (which might become the new "active" mode).
797 */
95407aa4 798 table = &lq_sta->lq;
39e88504
GC
799 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
800 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);
4c424e4c
RR
801 if (priv->band == IEEE80211_BAND_5GHZ)
802 rs_index -= IWL_FIRST_OFDM_RATE;
5027309b
DH
803 mac_flags = info->status.rates[0].flags;
804 mac_index = info->status.rates[0].idx;
31513be8
DH
805 /* For HT packets, map MCS to PLCP */
806 if (mac_flags & IEEE80211_TX_RC_MCS) {
807 mac_index &= RATE_MCS_CODE_MSK; /* Remove # of streams */
808 if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE))
809 mac_index++;
392a0baf
DH
810 /*
811 * mac80211 HT index is always zero-indexed; we need to move
812 * HT OFDM rates after CCK rates in 2.4 GHz band
813 */
814 if (priv->band == IEEE80211_BAND_2GHZ)
815 mac_index += IWL_FIRST_OFDM_RATE;
31513be8 816 }
95407aa4 817 /* Here we actually compare this rate to the latest LQ command */
5027309b
DH
818 if ((mac_index < 0) ||
819 (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
820 (tbl_type.is_ht40 != !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) ||
821 (tbl_type.is_dup != !!(mac_flags & IEEE80211_TX_RC_DUP_DATA)) ||
e6a9854b 822 (tbl_type.ant_type != info->antenna_sel_tx) ||
5027309b
DH
823 (!!(tx_rate & RATE_MCS_HT_MSK) != !!(mac_flags & IEEE80211_TX_RC_MCS)) ||
824 (!!(tx_rate & RATE_MCS_GF_MSK) != !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
31513be8
DH
825 (rs_index != mac_index)) {
826 IWL_DEBUG_RATE(priv, "initial rate %d does not match %d (0x%x)\n", mac_index, rs_index, tx_rate);
95407aa4
DH
827 /*
828 * Since rates mis-match, the last LQ command may have failed.
829 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
830 * ... driver.
d5e49036 831 */
7d049e5a
AM
832 lq_sta->missed_rate_counter++;
833 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
834 lq_sta->missed_rate_counter = 0;
835 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
836 }
95407aa4
DH
837 /* Regardless, ignore this status info for outdated rate */
838 return;
839 } else
840 /* Rate did match, so reset the missed_rate_counter */
841 lq_sta->missed_rate_counter = 0;
842
843 /* Figure out if rate scale algorithm is in active or search table */
844 if (table_type_matches(&tbl_type,
845 &(lq_sta->lq_info[lq_sta->active_tbl]))) {
846 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
847 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
848 } else if (table_type_matches(&tbl_type,
849 &lq_sta->lq_info[1 - lq_sta->active_tbl])) {
850 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
851 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
852 } else {
853 IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
854 return;
b481de9c 855 }
95407aa4 856 window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
b481de9c 857
95407aa4
DH
858 /*
859 * Updating the frame history depends on whether packets were
860 * aggregated.
861 *
862 * For aggregation, all packets were transmitted at the same rate, the
863 * first index into rate scale table.
864 */
865 if (info->flags & IEEE80211_TX_STAT_AMPDU) {
866 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
867 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
868 &rs_index);
869 tpt = get_expected_tpt(curr_tbl, rs_index);
870 rs_collect_tx_data(window, rs_index, tpt,
871 info->status.ampdu_ack_len,
872 info->status.ampdu_ack_map);
873
874 /* Update success/fail counts if not searching for new mode */
875 if (lq_sta->stay_in_tbl) {
876 lq_sta->total_success += info->status.ampdu_ack_map;
877 lq_sta->total_failed += (info->status.ampdu_ack_len -
878 info->status.ampdu_ack_map);
b481de9c 879 }
95407aa4 880 } else {
77626355 881 /*
95407aa4 882 * For legacy, update frame history with for each Tx retry.
77626355 883 */
95407aa4
DH
884 retries = info->status.rates[0].count - 1;
885 /* HW doesn't send more than 15 retries */
886 retries = min(retries, 15);
887
888 /* The last transmission may have been successful */
889 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
890 /* Collect data for each rate used during failed TX attempts */
891 for (i = 0; i <= retries; ++i) {
892 tx_rate = le32_to_cpu(table->rs_table[i].rate_n_flags);
893 rs_get_tbl_info_from_mcs(tx_rate, priv->band,
894 &tbl_type, &rs_index);
895 /*
896 * Only collect stats if retried rate is in the same RS
897 * table as active/search.
898 */
899 if (table_type_matches(&tbl_type, curr_tbl))
900 tpt = get_expected_tpt(curr_tbl, rs_index);
901 else if (table_type_matches(&tbl_type, other_tbl))
902 tpt = get_expected_tpt(other_tbl, rs_index);
903 else
904 continue;
b481de9c 905
95407aa4
DH
906 /* Constants mean 1 transmission, 0 successes */
907 if (i < retries)
908 rs_collect_tx_data(window, rs_index, tpt, 1,
909 0);
99556438 910 else
95407aa4
DH
911 rs_collect_tx_data(window, rs_index, tpt, 1,
912 legacy_success);
913 }
914
915 /* Update success/fail counts if not searching for new mode */
916 if (lq_sta->stay_in_tbl) {
917 lq_sta->total_success += legacy_success;
918 lq_sta->total_failed += retries + (1 - legacy_success);
99556438 919 }
b481de9c 920 }
95407aa4
DH
921 /* The last TX rate is cached in lq_sta; it's set in if/else above */
922 lq_sta->last_rate_n_flags = tx_rate;
b481de9c 923
77626355 924 /* See if there's a better rate or modulation mode to try. */
c338ba3c 925 if (sta && sta->supp_rates[sband->band])
514d65c1 926 rs_rate_scale_perform(priv, skb, sta, lq_sta);
b481de9c
ZY
927}
928
77626355
BC
929/*
930 * Begin a period of staying with a selected modulation mode.
931 * Set "stay_in_tbl" flag to prevent any mode switches.
932 * Set frame tx success limits according to legacy vs. high-throughput,
933 * and reset overall (spanning all rates) tx success history statistics.
934 * These control how long we stay using same modulation mode before
935 * searching for a new mode.
936 */
bf403db8 937static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
e227ceac 938 struct iwl_lq_sta *lq_sta)
b481de9c 939{
e1623446 940 IWL_DEBUG_RATE(priv, "we are staying in the same table\n");
c33104f0 941 lq_sta->stay_in_tbl = 1; /* only place this gets set */
b481de9c 942 if (is_legacy) {
c33104f0
TW
943 lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT;
944 lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT;
945 lq_sta->max_success_limit = IWL_LEGACY_SUCCESS_LIMIT;
b481de9c 946 } else {
c33104f0
TW
947 lq_sta->table_count_limit = IWL_NONE_LEGACY_TABLE_COUNT;
948 lq_sta->max_failure_limit = IWL_NONE_LEGACY_FAILURE_LIMIT;
949 lq_sta->max_success_limit = IWL_NONE_LEGACY_SUCCESS_LIMIT;
b481de9c 950 }
c33104f0
TW
951 lq_sta->table_count = 0;
952 lq_sta->total_failed = 0;
953 lq_sta->total_success = 0;
447fee70 954 lq_sta->flush_timer = jiffies;
d6e93399 955 lq_sta->action_counter = 0;
b481de9c
ZY
956}
957
77626355
BC
958/*
959 * Find correct throughput table for given mode of modulation
960 */
e227ceac
TW
961static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
962 struct iwl_scale_tbl_info *tbl)
b481de9c 963{
e3949d62
DH
964 /* Used to choose among HT tables */
965 s32 (*ht_tbl_pointer)[IWL_RATE_COUNT];
966
967 /* Check for invalid LQ type */
968 if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_Ht(tbl->lq_type))) {
969 tbl->expected_tpt = expected_tpt_legacy;
970 return;
971 }
972
973 /* Legacy rates have only one table */
b481de9c 974 if (is_legacy(tbl->lq_type)) {
e3949d62
DH
975 tbl->expected_tpt = expected_tpt_legacy;
976 return;
977 }
978
979 /* Choose among many HT tables depending on number of streams
980 * (SISO/MIMO2/MIMO3), channel width (20/40), SGI, and aggregation
981 * status */
982 if (is_siso(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup))
983 ht_tbl_pointer = expected_tpt_siso20MHz;
984 else if (is_siso(tbl->lq_type))
985 ht_tbl_pointer = expected_tpt_siso40MHz;
986 else if (is_mimo2(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup))
987 ht_tbl_pointer = expected_tpt_mimo2_20MHz;
988 else if (is_mimo2(tbl->lq_type))
989 ht_tbl_pointer = expected_tpt_mimo2_40MHz;
990 else if (is_mimo3(tbl->lq_type) && (!tbl->is_ht40 || lq_sta->is_dup))
991 ht_tbl_pointer = expected_tpt_mimo3_20MHz;
992 else /* if (is_mimo3(tbl->lq_type)) <-- must be true */
993 ht_tbl_pointer = expected_tpt_mimo3_40MHz;
994
995 if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */
996 tbl->expected_tpt = ht_tbl_pointer[0];
997 else if (tbl->is_SGI && !lq_sta->is_agg) /* SGI */
998 tbl->expected_tpt = ht_tbl_pointer[1];
999 else if (!tbl->is_SGI && lq_sta->is_agg) /* AGG */
1000 tbl->expected_tpt = ht_tbl_pointer[2];
1001 else /* AGG+SGI */
1002 tbl->expected_tpt = ht_tbl_pointer[3];
b481de9c
ZY
1003}
1004
77626355
BC
1005/*
1006 * Find starting rate for new "search" high-throughput mode of modulation.
1007 * Goal is to find lowest expected rate (under perfect conditions) that is
1008 * above the current measured throughput of "active" mode, to give new mode
1009 * a fair chance to prove itself without too many challenges.
1010 *
1011 * This gets called when transitioning to more aggressive modulation
1012 * (i.e. legacy to SISO or MIMO, or SISO to MIMO), as well as less aggressive
1013 * (i.e. MIMO to SISO). When moving to MIMO, bit rate will typically need
1014 * to decrease to match "active" throughput. When moving from MIMO to SISO,
1015 * bit rate will typically need to increase, but not if performance was bad.
1016 */
c79dd5b5 1017static s32 rs_get_best_rate(struct iwl_priv *priv,
e227ceac
TW
1018 struct iwl_lq_sta *lq_sta,
1019 struct iwl_scale_tbl_info *tbl, /* "search" */
f935a6da 1020 u16 rate_mask, s8 index)
b481de9c 1021{
77626355 1022 /* "active" values */
e227ceac 1023 struct iwl_scale_tbl_info *active_tbl =
c33104f0 1024 &(lq_sta->lq_info[lq_sta->active_tbl]);
b481de9c 1025 s32 active_sr = active_tbl->win[index].success_ratio;
b481de9c 1026 s32 active_tpt = active_tbl->expected_tpt[index];
77626355
BC
1027
1028 /* expected "search" throughput */
1029 s32 *tpt_tbl = tbl->expected_tpt;
1030
1031 s32 new_rate, high, low, start_hi;
b481de9c 1032 u16 high_low;
f935a6da 1033 s8 rate = index;
b481de9c
ZY
1034
1035 new_rate = high = low = start_hi = IWL_RATE_INVALID;
1036
1037 for (; ;) {
bf403db8
EK
1038 high_low = rs_get_adjacent_rate(priv, rate, rate_mask,
1039 tbl->lq_type);
b481de9c
ZY
1040
1041 low = high_low & 0xff;
1042 high = (high_low >> 8) & 0xff;
1043
77626355
BC
1044 /*
1045 * Lower the "search" bit rate, to give new "search" mode
1046 * approximately the same throughput as "active" if:
1047 *
1048 * 1) "Active" mode has been working modestly well (but not
1049 * great), and expected "search" throughput (under perfect
1050 * conditions) at candidate rate is above the actual
1051 * measured "active" throughput (but less than expected
1052 * "active" throughput under perfect conditions).
1053 * OR
1054 * 2) "Active" mode has been working perfectly or very well
1055 * and expected "search" throughput (under perfect
1056 * conditions) at candidate rate is above expected
1057 * "active" throughput (under perfect conditions).
1058 */
c33104f0 1059 if ((((100 * tpt_tbl[rate]) > lq_sta->last_tpt) &&
b481de9c
ZY
1060 ((active_sr > IWL_RATE_DECREASE_TH) &&
1061 (active_sr <= IWL_RATE_HIGH_TH) &&
1062 (tpt_tbl[rate] <= active_tpt))) ||
1063 ((active_sr >= IWL_RATE_SCALE_SWITCH) &&
1064 (tpt_tbl[rate] > active_tpt))) {
1065
77626355
BC
1066 /* (2nd or later pass)
1067 * If we've already tried to raise the rate, and are
1068 * now trying to lower it, use the higher rate. */
b481de9c
ZY
1069 if (start_hi != IWL_RATE_INVALID) {
1070 new_rate = start_hi;
1071 break;
1072 }
77626355 1073
b481de9c 1074 new_rate = rate;
77626355
BC
1075
1076 /* Loop again with lower rate */
b481de9c
ZY
1077 if (low != IWL_RATE_INVALID)
1078 rate = low;
77626355
BC
1079
1080 /* Lower rate not available, use the original */
b481de9c
ZY
1081 else
1082 break;
77626355
BC
1083
1084 /* Else try to raise the "search" rate to match "active" */
b481de9c 1085 } else {
77626355
BC
1086 /* (2nd or later pass)
1087 * If we've already tried to lower the rate, and are
1088 * now trying to raise it, use the lower rate. */
b481de9c
ZY
1089 if (new_rate != IWL_RATE_INVALID)
1090 break;
77626355
BC
1091
1092 /* Loop again with higher rate */
b481de9c
ZY
1093 else if (high != IWL_RATE_INVALID) {
1094 start_hi = high;
1095 rate = high;
77626355
BC
1096
1097 /* Higher rate not available, use the original */
b481de9c 1098 } else {
90d7795e 1099 new_rate = rate;
b481de9c
ZY
1100 break;
1101 }
1102 }
1103 }
1104
1105 return new_rate;
1106}
b481de9c 1107
77626355 1108/*
584a0f00 1109 * Set up search table for MIMO2
77626355 1110 */
fde0db31 1111static int rs_switch_to_mimo2(struct iwl_priv *priv,
e227ceac 1112 struct iwl_lq_sta *lq_sta,
270243a5 1113 struct ieee80211_conf *conf,
4b7679a5 1114 struct ieee80211_sta *sta,
e227ceac 1115 struct iwl_scale_tbl_info *tbl, int index)
b481de9c 1116{
b481de9c
ZY
1117 u16 rate_mask;
1118 s32 rate;
c33104f0 1119 s8 is_green = lq_sta->is_green;
b481de9c 1120
de27e64e 1121 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
b481de9c
ZY
1122 return -1;
1123
d9fe60de 1124 if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
00c5ae2f 1125 == WLAN_HT_CAP_SM_PS_STATIC)
b481de9c
ZY
1126 return -1;
1127
77626355 1128 /* Need both Tx chains/antennas to support MIMO */
aade00ce 1129 if (priv->hw_params.tx_chains_num < 2)
b481de9c
ZY
1130 return -1;
1131
e1623446 1132 IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO2\n");
39e88504
GC
1133
1134 tbl->lq_type = LQ_MIMO2;
c33104f0 1135 tbl->is_dup = lq_sta->is_dup;
b481de9c 1136 tbl->action = 0;
d6e93399 1137 tbl->max_search = IWL_MAX_SEARCH;
39e88504
GC
1138 rate_mask = lq_sta->active_mimo2_rate;
1139
7aafef1c
WYG
1140 if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap))
1141 tbl->is_ht40 = 1;
b481de9c 1142 else
7aafef1c 1143 tbl->is_ht40 = 0;
b481de9c 1144
eecd6e57 1145 rs_set_expected_tpt_table(lq_sta, tbl);
b481de9c 1146
f935a6da 1147 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
b481de9c 1148
e1623446 1149 IWL_DEBUG_RATE(priv, "LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask);
584a0f00
WYG
1150 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
1151 IWL_DEBUG_RATE(priv, "Can't switch with index %d rate mask %x\n",
1152 rate, rate_mask);
1153 return -1;
1154 }
1155 tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
1156
1157 IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n",
1158 tbl->current_rate, is_green);
1159 return 0;
1160}
1161
1162/*
1163 * Set up search table for MIMO3
1164 */
1165static int rs_switch_to_mimo3(struct iwl_priv *priv,
1166 struct iwl_lq_sta *lq_sta,
1167 struct ieee80211_conf *conf,
1168 struct ieee80211_sta *sta,
1169 struct iwl_scale_tbl_info *tbl, int index)
1170{
1171 u16 rate_mask;
1172 s32 rate;
1173 s8 is_green = lq_sta->is_green;
1174
1175 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
1176 return -1;
1177
1178 if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
1179 == WLAN_HT_CAP_SM_PS_STATIC)
1180 return -1;
1181
1182 /* Need both Tx chains/antennas to support MIMO */
1183 if (priv->hw_params.tx_chains_num < 3)
1184 return -1;
1185
1186 IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO3\n");
1187
1188 tbl->lq_type = LQ_MIMO3;
1189 tbl->is_dup = lq_sta->is_dup;
1190 tbl->action = 0;
d6e93399 1191 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
584a0f00
WYG
1192 rate_mask = lq_sta->active_mimo3_rate;
1193
7aafef1c
WYG
1194 if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap))
1195 tbl->is_ht40 = 1;
584a0f00 1196 else
7aafef1c 1197 tbl->is_ht40 = 0;
39e88504 1198
584a0f00
WYG
1199 rs_set_expected_tpt_table(lq_sta, tbl);
1200
1201 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
1202
1203 IWL_DEBUG_RATE(priv, "LQ: MIMO3 best rate %d mask %X\n",
1204 rate, rate_mask);
39e88504 1205 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
e1623446 1206 IWL_DEBUG_RATE(priv, "Can't switch with index %d rate mask %x\n",
39e88504 1207 rate, rate_mask);
b481de9c 1208 return -1;
39e88504 1209 }
978785a3 1210 tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
b481de9c 1211
e1623446 1212 IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n",
39e88504 1213 tbl->current_rate, is_green);
dc2453ae 1214 return 0;
fde0db31 1215}
b481de9c 1216
77626355
BC
1217/*
1218 * Set up search table for SISO
1219 */
c79dd5b5 1220static int rs_switch_to_siso(struct iwl_priv *priv,
e227ceac 1221 struct iwl_lq_sta *lq_sta,
270243a5 1222 struct ieee80211_conf *conf,
4b7679a5 1223 struct ieee80211_sta *sta,
e227ceac 1224 struct iwl_scale_tbl_info *tbl, int index)
b481de9c 1225{
b481de9c 1226 u16 rate_mask;
c33104f0 1227 u8 is_green = lq_sta->is_green;
b481de9c
ZY
1228 s32 rate;
1229
de27e64e 1230 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
b481de9c
ZY
1231 return -1;
1232
e1623446 1233 IWL_DEBUG_RATE(priv, "LQ: try to switch to SISO\n");
39e88504 1234
c33104f0 1235 tbl->is_dup = lq_sta->is_dup;
b481de9c
ZY
1236 tbl->lq_type = LQ_SISO;
1237 tbl->action = 0;
d6e93399 1238 tbl->max_search = IWL_MAX_SEARCH;
39e88504 1239 rate_mask = lq_sta->active_siso_rate;
b481de9c 1240
7aafef1c
WYG
1241 if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap))
1242 tbl->is_ht40 = 1;
b481de9c 1243 else
7aafef1c 1244 tbl->is_ht40 = 0;
b481de9c 1245
b481de9c 1246 if (is_green)
39e88504 1247 tbl->is_SGI = 0; /*11n spec: no SGI in SISO+Greenfield*/
b481de9c 1248
eecd6e57 1249 rs_set_expected_tpt_table(lq_sta, tbl);
f935a6da 1250 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
b481de9c 1251
e1623446 1252 IWL_DEBUG_RATE(priv, "LQ: get best rate %d mask %X\n", rate, rate_mask);
b481de9c 1253 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
e1623446 1254 IWL_DEBUG_RATE(priv, "can not switch with index %d rate mask %x\n",
b481de9c
ZY
1255 rate, rate_mask);
1256 return -1;
1257 }
978785a3 1258 tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
e1623446 1259 IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n",
39e88504 1260 tbl->current_rate, is_green);
403ab56b 1261 return 0;
b481de9c
ZY
1262}
1263
77626355
BC
1264/*
1265 * Try to switch to new modulation mode from legacy
1266 */
c79dd5b5 1267static int rs_move_legacy_other(struct iwl_priv *priv,
e227ceac 1268 struct iwl_lq_sta *lq_sta,
270243a5 1269 struct ieee80211_conf *conf,
4b7679a5 1270 struct ieee80211_sta *sta,
b481de9c
ZY
1271 int index)
1272{
e227ceac
TW
1273 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1274 struct iwl_scale_tbl_info *search_tbl =
1275 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1276 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1277 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1278 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
b481de9c 1279 u8 start_action = tbl->action;
fde0db31 1280 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
3110bef7 1281 u8 tx_chains_num = priv->hw_params.tx_chains_num;
fde0db31 1282 int ret = 0;
d6e93399 1283 u8 update_search_tbl_counter = 0;
b481de9c 1284
46f9381a
WYG
1285 if (!iwl_ht_enabled(priv))
1286 /* stay in Legacy */
1287 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
3ad3b92a 1288 else if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE &&
46f9381a
WYG
1289 tbl->action > IWL_LEGACY_SWITCH_SISO)
1290 tbl->action = IWL_LEGACY_SWITCH_SISO;
b481de9c 1291 for (; ;) {
d6e93399 1292 lq_sta->action_counter++;
b481de9c 1293 switch (tbl->action) {
3110bef7
GC
1294 case IWL_LEGACY_SWITCH_ANTENNA1:
1295 case IWL_LEGACY_SWITCH_ANTENNA2:
e1623446 1296 IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n");
b481de9c 1297
3110bef7
GC
1298 if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 &&
1299 tx_chains_num <= 1) ||
1300 (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 &&
1301 tx_chains_num <= 2))
1302 break;
1303
77626355 1304 /* Don't change antenna if success has been great */
b481de9c
ZY
1305 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1306 break;
77626355 1307
77626355 1308 /* Set up search table to try other antenna */
b481de9c
ZY
1309 memcpy(search_tbl, tbl, sz);
1310
aade00ce
GC
1311 if (rs_toggle_antenna(valid_tx_ant,
1312 &search_tbl->current_rate, search_tbl)) {
d6e93399 1313 update_search_tbl_counter = 1;
3110bef7 1314 rs_set_expected_tpt_table(lq_sta, search_tbl);
aade00ce
GC
1315 goto out;
1316 }
a5e8b505 1317 break;
b481de9c 1318 case IWL_LEGACY_SWITCH_SISO:
e1623446 1319 IWL_DEBUG_RATE(priv, "LQ: Legacy switch to SISO\n");
77626355
BC
1320
1321 /* Set up search table to try SISO */
b481de9c 1322 memcpy(search_tbl, tbl, sz);
b481de9c 1323 search_tbl->is_SGI = 0;
c33104f0 1324 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
270243a5 1325 search_tbl, index);
dc2453ae 1326 if (!ret) {
c33104f0 1327 lq_sta->action_counter = 0;
b481de9c 1328 goto out;
dc2453ae 1329 }
b481de9c
ZY
1330
1331 break;
3110bef7
GC
1332 case IWL_LEGACY_SWITCH_MIMO2_AB:
1333 case IWL_LEGACY_SWITCH_MIMO2_AC:
1334 case IWL_LEGACY_SWITCH_MIMO2_BC:
e1623446 1335 IWL_DEBUG_RATE(priv, "LQ: Legacy switch to MIMO2\n");
77626355
BC
1336
1337 /* Set up search table to try MIMO */
b481de9c 1338 memcpy(search_tbl, tbl, sz);
b481de9c 1339 search_tbl->is_SGI = 0;
3110bef7
GC
1340
1341 if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AB)
1342 search_tbl->ant_type = ANT_AB;
1343 else if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AC)
1344 search_tbl->ant_type = ANT_AC;
1345 else
1346 search_tbl->ant_type = ANT_BC;
1347
1348 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
1349 break;
1350
fde0db31 1351 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
270243a5 1352 search_tbl, index);
dc2453ae 1353 if (!ret) {
c33104f0 1354 lq_sta->action_counter = 0;
b481de9c 1355 goto out;
dc2453ae 1356 }
b481de9c 1357 break;
584a0f00
WYG
1358
1359 case IWL_LEGACY_SWITCH_MIMO3_ABC:
1360 IWL_DEBUG_RATE(priv, "LQ: Legacy switch to MIMO3\n");
1361
1362 /* Set up search table to try MIMO3 */
1363 memcpy(search_tbl, tbl, sz);
1364 search_tbl->is_SGI = 0;
1365
1366 search_tbl->ant_type = ANT_ABC;
1367
1368 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
1369 break;
1370
1371 ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
1372 search_tbl, index);
1373 if (!ret) {
1374 lq_sta->action_counter = 0;
1375 goto out;
1376 }
1377 break;
b481de9c
ZY
1378 }
1379 tbl->action++;
584a0f00 1380 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
3110bef7 1381 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
b481de9c
ZY
1382
1383 if (tbl->action == start_action)
1384 break;
1385
1386 }
3110bef7 1387 search_tbl->lq_type = LQ_NONE;
b481de9c
ZY
1388 return 0;
1389
3110bef7
GC
1390out:
1391 lq_sta->search_better_tbl = 1;
b481de9c 1392 tbl->action++;
584a0f00 1393 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
3110bef7 1394 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
d6e93399
MA
1395 if (update_search_tbl_counter)
1396 search_tbl->action = tbl->action;
b481de9c
ZY
1397 return 0;
1398
1399}
1400
77626355
BC
1401/*
1402 * Try to switch to new modulation mode from SISO
1403 */
c79dd5b5 1404static int rs_move_siso_to_other(struct iwl_priv *priv,
e227ceac 1405 struct iwl_lq_sta *lq_sta,
270243a5 1406 struct ieee80211_conf *conf,
4b7679a5 1407 struct ieee80211_sta *sta, int index)
b481de9c 1408{
c33104f0 1409 u8 is_green = lq_sta->is_green;
e227ceac
TW
1410 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1411 struct iwl_scale_tbl_info *search_tbl =
1412 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1413 struct iwl_rate_scale_data *window = &(tbl->win[index]);
28e6f489 1414 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
e227ceac
TW
1415 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1416 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
b481de9c 1417 u8 start_action = tbl->action;
fde0db31 1418 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
3110bef7 1419 u8 tx_chains_num = priv->hw_params.tx_chains_num;
d6e93399 1420 u8 update_search_tbl_counter = 0;
fde0db31 1421 int ret;
b481de9c 1422
3ad3b92a 1423 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE &&
46f9381a
WYG
1424 tbl->action > IWL_SISO_SWITCH_ANTENNA2) {
1425 /* stay in SISO */
1426 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1427 }
b481de9c 1428 for (;;) {
c33104f0 1429 lq_sta->action_counter++;
b481de9c 1430 switch (tbl->action) {
3110bef7
GC
1431 case IWL_SISO_SWITCH_ANTENNA1:
1432 case IWL_SISO_SWITCH_ANTENNA2:
e1623446 1433 IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n");
3110bef7
GC
1434
1435 if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
1436 tx_chains_num <= 1) ||
1437 (tbl->action == IWL_SISO_SWITCH_ANTENNA2 &&
1438 tx_chains_num <= 2))
1439 break;
1440
b481de9c
ZY
1441 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1442 break;
b481de9c
ZY
1443
1444 memcpy(search_tbl, tbl, sz);
aade00ce 1445 if (rs_toggle_antenna(valid_tx_ant,
d6e93399
MA
1446 &search_tbl->current_rate, search_tbl)) {
1447 update_search_tbl_counter = 1;
aade00ce 1448 goto out;
d6e93399 1449 }
a5e8b505 1450 break;
3110bef7
GC
1451 case IWL_SISO_SWITCH_MIMO2_AB:
1452 case IWL_SISO_SWITCH_MIMO2_AC:
1453 case IWL_SISO_SWITCH_MIMO2_BC:
e1623446 1454 IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO2\n");
b481de9c 1455 memcpy(search_tbl, tbl, sz);
b481de9c 1456 search_tbl->is_SGI = 0;
3110bef7
GC
1457
1458 if (tbl->action == IWL_SISO_SWITCH_MIMO2_AB)
1459 search_tbl->ant_type = ANT_AB;
1460 else if (tbl->action == IWL_SISO_SWITCH_MIMO2_AC)
1461 search_tbl->ant_type = ANT_AC;
1462 else
1463 search_tbl->ant_type = ANT_BC;
1464
1465 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
1466 break;
1467
fde0db31 1468 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
270243a5 1469 search_tbl, index);
3110bef7 1470 if (!ret)
b481de9c
ZY
1471 goto out;
1472 break;
1473 case IWL_SISO_SWITCH_GI:
28e6f489
DH
1474 if (!tbl->is_ht40 && !(ht_cap->cap &
1475 IEEE80211_HT_CAP_SGI_20))
a9841013 1476 break;
28e6f489
DH
1477 if (tbl->is_ht40 && !(ht_cap->cap &
1478 IEEE80211_HT_CAP_SGI_40))
a9841013
EG
1479 break;
1480
e1623446 1481 IWL_DEBUG_RATE(priv, "LQ: SISO toggle SGI/NGI\n");
0c11b4de 1482
b481de9c 1483 memcpy(search_tbl, tbl, sz);
39e88504
GC
1484 if (is_green) {
1485 if (!tbl->is_SGI)
1486 break;
1487 else
15b1687c
WT
1488 IWL_ERR(priv,
1489 "SGI was set in GF+SISO\n");
b481de9c 1490 }
39e88504 1491 search_tbl->is_SGI = !tbl->is_SGI;
eecd6e57 1492 rs_set_expected_tpt_table(lq_sta, search_tbl);
39e88504
GC
1493 if (tbl->is_SGI) {
1494 s32 tpt = lq_sta->last_tpt / 100;
1495 if (tpt >= search_tbl->expected_tpt[index])
1496 break;
1497 }
978785a3
TW
1498 search_tbl->current_rate =
1499 rate_n_flags_from_tbl(priv, search_tbl,
1500 index, is_green);
d6e93399 1501 update_search_tbl_counter = 1;
b481de9c 1502 goto out;
584a0f00
WYG
1503 case IWL_SISO_SWITCH_MIMO3_ABC:
1504 IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO3\n");
1505 memcpy(search_tbl, tbl, sz);
1506 search_tbl->is_SGI = 0;
1507 search_tbl->ant_type = ANT_ABC;
1508
1509 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
1510 break;
1511
1512 ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
1513 search_tbl, index);
1514 if (!ret)
1515 goto out;
1516 break;
b481de9c
ZY
1517 }
1518 tbl->action++;
584a0f00 1519 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
3110bef7 1520 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
b481de9c
ZY
1521
1522 if (tbl->action == start_action)
1523 break;
1524 }
3110bef7 1525 search_tbl->lq_type = LQ_NONE;
b481de9c
ZY
1526 return 0;
1527
1528 out:
3110bef7 1529 lq_sta->search_better_tbl = 1;
b481de9c 1530 tbl->action++;
584a0f00 1531 if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC)
3110bef7 1532 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
d6e93399
MA
1533 if (update_search_tbl_counter)
1534 search_tbl->action = tbl->action;
1535
b481de9c
ZY
1536 return 0;
1537}
1538
77626355 1539/*
584a0f00 1540 * Try to switch to new modulation mode from MIMO2
77626355 1541 */
584a0f00 1542static int rs_move_mimo2_to_other(struct iwl_priv *priv,
e227ceac 1543 struct iwl_lq_sta *lq_sta,
270243a5 1544 struct ieee80211_conf *conf,
4b7679a5 1545 struct ieee80211_sta *sta, int index)
b481de9c 1546{
c33104f0 1547 s8 is_green = lq_sta->is_green;
e227ceac
TW
1548 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1549 struct iwl_scale_tbl_info *search_tbl =
1550 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
3110bef7 1551 struct iwl_rate_scale_data *window = &(tbl->win[index]);
28e6f489 1552 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
e227ceac
TW
1553 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1554 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
b481de9c 1555 u8 start_action = tbl->action;
3110bef7
GC
1556 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1557 u8 tx_chains_num = priv->hw_params.tx_chains_num;
d6e93399 1558 u8 update_search_tbl_counter = 0;
aade00ce 1559 int ret;
b481de9c 1560
3ad3b92a 1561 if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) &&
46f9381a
WYG
1562 (tbl->action < IWL_MIMO2_SWITCH_SISO_A ||
1563 tbl->action > IWL_MIMO2_SWITCH_SISO_C)) {
1564 /* switch in SISO */
1565 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1566 }
b481de9c 1567 for (;;) {
c33104f0 1568 lq_sta->action_counter++;
b481de9c 1569 switch (tbl->action) {
3110bef7
GC
1570 case IWL_MIMO2_SWITCH_ANTENNA1:
1571 case IWL_MIMO2_SWITCH_ANTENNA2:
584a0f00 1572 IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle Antennas\n");
3110bef7
GC
1573
1574 if (tx_chains_num <= 2)
1575 break;
1576
1577 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1578 break;
1579
1580 memcpy(search_tbl, tbl, sz);
1581 if (rs_toggle_antenna(valid_tx_ant,
d6e93399
MA
1582 &search_tbl->current_rate, search_tbl)) {
1583 update_search_tbl_counter = 1;
3110bef7 1584 goto out;
d6e93399 1585 }
3110bef7
GC
1586 break;
1587 case IWL_MIMO2_SWITCH_SISO_A:
1588 case IWL_MIMO2_SWITCH_SISO_B:
1589 case IWL_MIMO2_SWITCH_SISO_C:
e1623446 1590 IWL_DEBUG_RATE(priv, "LQ: MIMO2 switch to SISO\n");
0c11b4de 1591
77626355 1592 /* Set up new search table for SISO */
b481de9c 1593 memcpy(search_tbl, tbl, sz);
39e88504 1594
3110bef7 1595 if (tbl->action == IWL_MIMO2_SWITCH_SISO_A)
fde0db31 1596 search_tbl->ant_type = ANT_A;
3110bef7 1597 else if (tbl->action == IWL_MIMO2_SWITCH_SISO_B)
fde0db31 1598 search_tbl->ant_type = ANT_B;
3110bef7
GC
1599 else
1600 search_tbl->ant_type = ANT_C;
1601
1602 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
1603 break;
b481de9c 1604
c33104f0 1605 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
270243a5 1606 search_tbl, index);
3110bef7 1607 if (!ret)
b481de9c 1608 goto out;
3110bef7 1609
b481de9c
ZY
1610 break;
1611
3110bef7 1612 case IWL_MIMO2_SWITCH_GI:
28e6f489
DH
1613 if (!tbl->is_ht40 && !(ht_cap->cap &
1614 IEEE80211_HT_CAP_SGI_20))
a9841013 1615 break;
28e6f489
DH
1616 if (tbl->is_ht40 && !(ht_cap->cap &
1617 IEEE80211_HT_CAP_SGI_40))
a9841013
EG
1618 break;
1619
584a0f00 1620 IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle SGI/NGI\n");
77626355 1621
584a0f00 1622 /* Set up new search table for MIMO2 */
b481de9c 1623 memcpy(search_tbl, tbl, sz);
39e88504 1624 search_tbl->is_SGI = !tbl->is_SGI;
eecd6e57 1625 rs_set_expected_tpt_table(lq_sta, search_tbl);
77626355
BC
1626 /*
1627 * If active table already uses the fastest possible
1628 * modulation (dual stream with short guard interval),
1629 * and it's working well, there's no need to look
1630 * for a better type of modulation!
1631 */
39e88504 1632 if (tbl->is_SGI) {
c33104f0 1633 s32 tpt = lq_sta->last_tpt / 100;
39e88504
GC
1634 if (tpt >= search_tbl->expected_tpt[index])
1635 break;
b481de9c 1636 }
978785a3
TW
1637 search_tbl->current_rate =
1638 rate_n_flags_from_tbl(priv, search_tbl,
1639 index, is_green);
d6e93399 1640 update_search_tbl_counter = 1;
b481de9c
ZY
1641 goto out;
1642
584a0f00
WYG
1643 case IWL_MIMO2_SWITCH_MIMO3_ABC:
1644 IWL_DEBUG_RATE(priv, "LQ: MIMO2 switch to MIMO3\n");
1645 memcpy(search_tbl, tbl, sz);
1646 search_tbl->is_SGI = 0;
1647 search_tbl->ant_type = ANT_ABC;
1648
1649 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
1650 break;
1651
1652 ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
1653 search_tbl, index);
1654 if (!ret)
1655 goto out;
1656
1657 break;
b481de9c
ZY
1658 }
1659 tbl->action++;
584a0f00 1660 if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)
3110bef7 1661 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
b481de9c
ZY
1662
1663 if (tbl->action == start_action)
1664 break;
1665 }
3110bef7 1666 search_tbl->lq_type = LQ_NONE;
b481de9c
ZY
1667 return 0;
1668 out:
3110bef7 1669 lq_sta->search_better_tbl = 1;
b481de9c 1670 tbl->action++;
584a0f00 1671 if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)
3110bef7 1672 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
d6e93399
MA
1673 if (update_search_tbl_counter)
1674 search_tbl->action = tbl->action;
1675
b481de9c
ZY
1676 return 0;
1677
1678}
1679
584a0f00
WYG
1680/*
1681 * Try to switch to new modulation mode from MIMO3
1682 */
1683static int rs_move_mimo3_to_other(struct iwl_priv *priv,
1684 struct iwl_lq_sta *lq_sta,
1685 struct ieee80211_conf *conf,
1686 struct ieee80211_sta *sta, int index)
1687{
1688 s8 is_green = lq_sta->is_green;
1689 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1690 struct iwl_scale_tbl_info *search_tbl =
1691 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1692 struct iwl_rate_scale_data *window = &(tbl->win[index]);
28e6f489 1693 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
584a0f00
WYG
1694 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1695 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1696 u8 start_action = tbl->action;
1697 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1698 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1699 int ret;
d6e93399 1700 u8 update_search_tbl_counter = 0;
584a0f00 1701
3ad3b92a 1702 if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) &&
46f9381a
WYG
1703 (tbl->action < IWL_MIMO3_SWITCH_SISO_A ||
1704 tbl->action > IWL_MIMO3_SWITCH_SISO_C)) {
1705 /* switch in SISO */
1706 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1707 }
584a0f00
WYG
1708 for (;;) {
1709 lq_sta->action_counter++;
1710 switch (tbl->action) {
1711 case IWL_MIMO3_SWITCH_ANTENNA1:
1712 case IWL_MIMO3_SWITCH_ANTENNA2:
1713 IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle Antennas\n");
1714
1715 if (tx_chains_num <= 3)
1716 break;
1717
1718 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1719 break;
1720
1721 memcpy(search_tbl, tbl, sz);
1722 if (rs_toggle_antenna(valid_tx_ant,
1723 &search_tbl->current_rate, search_tbl))
1724 goto out;
1725 break;
1726 case IWL_MIMO3_SWITCH_SISO_A:
1727 case IWL_MIMO3_SWITCH_SISO_B:
1728 case IWL_MIMO3_SWITCH_SISO_C:
1729 IWL_DEBUG_RATE(priv, "LQ: MIMO3 switch to SISO\n");
1730
1731 /* Set up new search table for SISO */
1732 memcpy(search_tbl, tbl, sz);
1733
1734 if (tbl->action == IWL_MIMO3_SWITCH_SISO_A)
1735 search_tbl->ant_type = ANT_A;
1736 else if (tbl->action == IWL_MIMO3_SWITCH_SISO_B)
1737 search_tbl->ant_type = ANT_B;
1738 else
1739 search_tbl->ant_type = ANT_C;
1740
1741 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
1742 break;
1743
1744 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
1745 search_tbl, index);
1746 if (!ret)
1747 goto out;
1748
1749 break;
1750
1751 case IWL_MIMO3_SWITCH_MIMO2_AB:
1752 case IWL_MIMO3_SWITCH_MIMO2_AC:
1753 case IWL_MIMO3_SWITCH_MIMO2_BC:
1754 IWL_DEBUG_RATE(priv, "LQ: MIMO3 switch to MIMO2\n");
1755
1756 memcpy(search_tbl, tbl, sz);
1757 search_tbl->is_SGI = 0;
1758 if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AB)
1759 search_tbl->ant_type = ANT_AB;
1760 else if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AC)
1761 search_tbl->ant_type = ANT_AC;
1762 else
1763 search_tbl->ant_type = ANT_BC;
1764
1765 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
1766 break;
1767
1768 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
1769 search_tbl, index);
1770 if (!ret)
1771 goto out;
1772
1773 break;
1774
1775 case IWL_MIMO3_SWITCH_GI:
28e6f489
DH
1776 if (!tbl->is_ht40 && !(ht_cap->cap &
1777 IEEE80211_HT_CAP_SGI_20))
584a0f00 1778 break;
28e6f489
DH
1779 if (tbl->is_ht40 && !(ht_cap->cap &
1780 IEEE80211_HT_CAP_SGI_40))
584a0f00
WYG
1781 break;
1782
1783 IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle SGI/NGI\n");
1784
1785 /* Set up new search table for MIMO */
1786 memcpy(search_tbl, tbl, sz);
1787 search_tbl->is_SGI = !tbl->is_SGI;
1788 rs_set_expected_tpt_table(lq_sta, search_tbl);
1789 /*
1790 * If active table already uses the fastest possible
1791 * modulation (dual stream with short guard interval),
1792 * and it's working well, there's no need to look
1793 * for a better type of modulation!
1794 */
1795 if (tbl->is_SGI) {
1796 s32 tpt = lq_sta->last_tpt / 100;
1797 if (tpt >= search_tbl->expected_tpt[index])
1798 break;
1799 }
1800 search_tbl->current_rate =
1801 rate_n_flags_from_tbl(priv, search_tbl,
1802 index, is_green);
d6e93399 1803 update_search_tbl_counter = 1;
584a0f00
WYG
1804 goto out;
1805 }
1806 tbl->action++;
1807 if (tbl->action > IWL_MIMO3_SWITCH_GI)
1808 tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
1809
1810 if (tbl->action == start_action)
1811 break;
1812 }
1813 search_tbl->lq_type = LQ_NONE;
1814 return 0;
1815 out:
1816 lq_sta->search_better_tbl = 1;
1817 tbl->action++;
1818 if (tbl->action > IWL_MIMO3_SWITCH_GI)
1819 tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
d6e93399
MA
1820 if (update_search_tbl_counter)
1821 search_tbl->action = tbl->action;
1822
584a0f00
WYG
1823 return 0;
1824
1825}
1826
77626355
BC
1827/*
1828 * Check whether we should continue using same modulation mode, or
1829 * begin search for a new mode, based on:
1830 * 1) # tx successes or failures while using this mode
1831 * 2) # times calling this function
1832 * 3) elapsed time in this mode (not used, for now)
1833 */
e227ceac 1834static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
b481de9c 1835{
e227ceac 1836 struct iwl_scale_tbl_info *tbl;
b481de9c
ZY
1837 int i;
1838 int active_tbl;
1839 int flush_interval_passed = 0;
bf403db8 1840 struct iwl_priv *priv;
b481de9c 1841
bf403db8 1842 priv = lq_sta->drv;
c33104f0 1843 active_tbl = lq_sta->active_tbl;
b481de9c 1844
c33104f0 1845 tbl = &(lq_sta->lq_info[active_tbl]);
b481de9c 1846
77626355 1847 /* If we've been disallowing search, see if we should now allow it */
c33104f0 1848 if (lq_sta->stay_in_tbl) {
b481de9c 1849
77626355 1850 /* Elapsed time using current modulation mode */
c33104f0 1851 if (lq_sta->flush_timer)
b481de9c 1852 flush_interval_passed =
447fee70
MA
1853 time_after(jiffies,
1854 (unsigned long)(lq_sta->flush_timer +
b481de9c
ZY
1855 IWL_RATE_SCALE_FLUSH_INTVL));
1856
77626355
BC
1857 /*
1858 * Check if we should allow search for new modulation mode.
1859 * If many frames have failed or succeeded, or we've used
1860 * this same modulation for a long time, allow search, and
1861 * reset history stats that keep track of whether we should
1862 * allow a new search. Also (below) reset all bitmaps and
1863 * stats in active history.
1864 */
c33104f0
TW
1865 if ((lq_sta->total_failed > lq_sta->max_failure_limit) ||
1866 (lq_sta->total_success > lq_sta->max_success_limit) ||
1867 ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer)
b481de9c 1868 && (flush_interval_passed))) {
e1623446 1869 IWL_DEBUG_RATE(priv, "LQ: stay is expired %d %d %d\n:",
c33104f0
TW
1870 lq_sta->total_failed,
1871 lq_sta->total_success,
b481de9c 1872 flush_interval_passed);
77626355
BC
1873
1874 /* Allow search for new mode */
c33104f0
TW
1875 lq_sta->stay_in_tbl = 0; /* only place reset */
1876 lq_sta->total_failed = 0;
1877 lq_sta->total_success = 0;
1878 lq_sta->flush_timer = 0;
77626355
BC
1879
1880 /*
1881 * Else if we've used this modulation mode enough repetitions
1882 * (regardless of elapsed time or success/failure), reset
1883 * history bitmaps and rate-specific stats for all rates in
1884 * active table.
1885 */
403ab56b 1886 } else {
c33104f0
TW
1887 lq_sta->table_count++;
1888 if (lq_sta->table_count >=
1889 lq_sta->table_count_limit) {
1890 lq_sta->table_count = 0;
b481de9c 1891
e1623446 1892 IWL_DEBUG_RATE(priv, "LQ: stay in table clear win\n");
b481de9c
ZY
1893 for (i = 0; i < IWL_RATE_COUNT; i++)
1894 rs_rate_scale_clear_window(
1895 &(tbl->win[i]));
1896 }
1897 }
1898
77626355
BC
1899 /* If transitioning to allow "search", reset all history
1900 * bitmaps and stats in active table (this will become the new
1901 * "search" table). */
c33104f0 1902 if (!lq_sta->stay_in_tbl) {
b481de9c
ZY
1903 for (i = 0; i < IWL_RATE_COUNT; i++)
1904 rs_rate_scale_clear_window(&(tbl->win[i]));
1905 }
1906 }
1907}
1908
e3139fe7
WYG
1909/*
1910 * setup rate table in uCode
1911 * return rate_n_flags as used in the table
1912 */
1913static u32 rs_update_rate_tbl(struct iwl_priv *priv,
1914 struct iwl_lq_sta *lq_sta,
1915 struct iwl_scale_tbl_info *tbl,
1916 int index, u8 is_green)
1917{
1918 u32 rate;
1919
1920 /* Update uCode's rate table. */
1921 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
1922 rs_fill_link_cmd(priv, lq_sta, rate);
1923 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
1924
1925 return rate;
1926}
1927
77626355
BC
1928/*
1929 * Do rate scaling and search for new modulation mode.
1930 */
c79dd5b5 1931static void rs_rate_scale_perform(struct iwl_priv *priv,
514d65c1 1932 struct sk_buff *skb,
4b7679a5
JB
1933 struct ieee80211_sta *sta,
1934 struct iwl_lq_sta *lq_sta)
b481de9c 1935{
4b7679a5 1936 struct ieee80211_hw *hw = priv->hw;
270243a5 1937 struct ieee80211_conf *conf = &hw->conf;
514d65c1
GS
1938 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1939 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
b481de9c
ZY
1940 int low = IWL_RATE_INVALID;
1941 int high = IWL_RATE_INVALID;
1942 int index;
1943 int i;
e227ceac 1944 struct iwl_rate_scale_data *window = NULL;
b481de9c
ZY
1945 int current_tpt = IWL_INVALID_VALUE;
1946 int low_tpt = IWL_INVALID_VALUE;
1947 int high_tpt = IWL_INVALID_VALUE;
1948 u32 fail_count;
1949 s8 scale_action = 0;
fd7c8a40 1950 u16 rate_mask;
b481de9c 1951 u8 update_lq = 0;
e227ceac 1952 struct iwl_scale_tbl_info *tbl, *tbl1;
b481de9c 1953 u16 rate_scale_index_msk = 0;
39e88504 1954 u32 rate;
b481de9c
ZY
1955 u8 is_green = 0;
1956 u8 active_tbl = 0;
1957 u8 done_search = 0;
1958 u16 high_low;
a5e8b505 1959 s32 sr;
0c11b4de 1960 u8 tid = MAX_TID_COUNT;
86b4766b 1961 struct iwl_tid_data *tid_data;
b481de9c 1962
e1623446 1963 IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
b481de9c 1964
514d65c1 1965 /* Send management frames and NO_ACK data using lowest rate. */
417f114b
TW
1966 /* TODO: this could probably be improved.. */
1967 if (!ieee80211_is_data(hdr->frame_control) ||
514d65c1 1968 info->flags & IEEE80211_TX_CTL_NO_ACK)
b481de9c 1969 return;
b481de9c 1970
4b7679a5 1971 if (!sta || !lq_sta)
b481de9c
ZY
1972 return;
1973
4b7679a5 1974 lq_sta->supp_rates = sta->supp_rates[lq_sta->band];
b481de9c 1975
faa29718 1976 tid = rs_tl_add_packet(lq_sta, hdr);
e3949d62
DH
1977 if ((tid != MAX_TID_COUNT) && (lq_sta->tx_agg_tid_en & (1 << tid))) {
1978 tid_data = &priv->stations[lq_sta->lq.sta_id].tid[tid];
1979 if (tid_data->agg.state == IWL_AGG_OFF)
1980 lq_sta->is_agg = 0;
1981 else
1982 lq_sta->is_agg = 1;
1983 } else
1984 lq_sta->is_agg = 0;
faa29718 1985
77626355
BC
1986 /*
1987 * Select rate-scale / modulation-mode table to work with in
1988 * the rest of this function: "search" if searching for better
1989 * modulation mode, or "active" if doing rate scaling within a mode.
1990 */
c33104f0
TW
1991 if (!lq_sta->search_better_tbl)
1992 active_tbl = lq_sta->active_tbl;
b481de9c 1993 else
c33104f0 1994 active_tbl = 1 - lq_sta->active_tbl;
b481de9c 1995
c33104f0 1996 tbl = &(lq_sta->lq_info[active_tbl]);
2681b20b
WYG
1997 if (is_legacy(tbl->lq_type))
1998 lq_sta->is_green = 0;
1999 else
b261793d 2000 lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config);
c33104f0 2001 is_green = lq_sta->is_green;
b481de9c 2002
77626355 2003 /* current tx rate */
b7e35008 2004 index = lq_sta->last_txrate_idx;
b481de9c 2005
e1623446 2006 IWL_DEBUG_RATE(priv, "Rate scale index %d for type %d\n", index,
b481de9c
ZY
2007 tbl->lq_type);
2008
77626355 2009 /* rates available for this association, and for modulation mode */
eecd6e57 2010 rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type);
b481de9c 2011
e1623446 2012 IWL_DEBUG_RATE(priv, "mask 0x%04X \n", rate_mask);
b481de9c
ZY
2013
2014 /* mask with station rate restriction */
2015 if (is_legacy(tbl->lq_type)) {
8318d78a 2016 if (lq_sta->band == IEEE80211_BAND_5GHZ)
77626355 2017 /* supp_rates has no CCK bits in A mode */
b481de9c 2018 rate_scale_index_msk = (u16) (rate_mask &
c33104f0 2019 (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
b481de9c
ZY
2020 else
2021 rate_scale_index_msk = (u16) (rate_mask &
c33104f0 2022 lq_sta->supp_rates);
b481de9c
ZY
2023
2024 } else
2025 rate_scale_index_msk = rate_mask;
2026
2027 if (!rate_scale_index_msk)
2028 rate_scale_index_msk = rate_mask;
2029
07bc28ed 2030 if (!((1 << index) & rate_scale_index_msk)) {
15b1687c 2031 IWL_ERR(priv, "Current Rate is not valid\n");
e3139fe7
WYG
2032 if (lq_sta->search_better_tbl) {
2033 /* revert to active table if search table is not valid*/
2034 tbl->lq_type = LQ_NONE;
2035 lq_sta->search_better_tbl = 0;
2036 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2037 /* get "active" rate info */
2038 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
2039 rate = rs_update_rate_tbl(priv, lq_sta,
2040 tbl, index, is_green);
2041 }
07bc28ed 2042 return;
b481de9c
ZY
2043 }
2044
77626355 2045 /* Get expected throughput table and history window for current rate */
07bc28ed 2046 if (!tbl->expected_tpt) {
15b1687c 2047 IWL_ERR(priv, "tbl->expected_tpt is NULL\n");
07bc28ed
GC
2048 return;
2049 }
b481de9c 2050
c6ec7a9b
AM
2051 /* force user max rate if set by user */
2052 if ((lq_sta->max_rate_idx != -1) &&
2053 (lq_sta->max_rate_idx < index)) {
2054 index = lq_sta->max_rate_idx;
2055 update_lq = 1;
2056 window = &(tbl->win[index]);
2057 goto lq_update;
2058 }
2059
b481de9c
ZY
2060 window = &(tbl->win[index]);
2061
77626355
BC
2062 /*
2063 * If there is not enough history to calculate actual average
2064 * throughput, keep analyzing results of more tx frames, without
2065 * changing rate or mode (bypass most of the rest of this function).
2066 * Set up new rate table in uCode only if old rate is not supported
2067 * in current association (use new rate found above).
2068 */
b481de9c 2069 fail_count = window->counter - window->success_counter;
07bc28ed
GC
2070 if ((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
2071 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) {
e1623446 2072 IWL_DEBUG_RATE(priv, "LQ: still below TH. succ=%d total=%d "
b481de9c
ZY
2073 "for index %d\n",
2074 window->success_counter, window->counter, index);
77626355
BC
2075
2076 /* Can't calculate this yet; not enough history */
b481de9c 2077 window->average_tpt = IWL_INVALID_VALUE;
77626355
BC
2078
2079 /* Should we stay with this modulation mode,
2080 * or search for a new one? */
c33104f0 2081 rs_stay_in_table(lq_sta);
77626355 2082
b481de9c 2083 goto out;
3110bef7 2084 }
77626355
BC
2085 /* Else we have enough samples; calculate estimate of
2086 * actual average throughput */
3110bef7 2087
e3949d62 2088 /* Sanity-check TPT calculations */
3110bef7
GC
2089 BUG_ON(window->average_tpt != ((window->success_ratio *
2090 tbl->expected_tpt[index] + 64) / 128));
b481de9c 2091
77626355 2092 /* If we are searching for better modulation mode, check success. */
46f9381a 2093 if (lq_sta->search_better_tbl &&
3ad3b92a 2094 (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI)) {
77626355
BC
2095 /* If good success, continue using the "search" mode;
2096 * no need to send new link quality command, since we're
2097 * continuing to use the setup that we've been trying. */
07bc28ed
GC
2098 if (window->average_tpt > lq_sta->last_tpt) {
2099
e1623446 2100 IWL_DEBUG_RATE(priv, "LQ: SWITCHING TO NEW TABLE "
07bc28ed
GC
2101 "suc=%d cur-tpt=%d old-tpt=%d\n",
2102 window->success_ratio,
2103 window->average_tpt,
2104 lq_sta->last_tpt);
2105
2106 if (!is_legacy(tbl->lq_type))
c33104f0 2107 lq_sta->enable_counter = 1;
07bc28ed 2108
77626355 2109 /* Swap tables; "search" becomes "active" */
c33104f0 2110 lq_sta->active_tbl = active_tbl;
b481de9c 2111 current_tpt = window->average_tpt;
77626355
BC
2112
2113 /* Else poor success; go back to mode in "active" table */
b481de9c 2114 } else {
07bc28ed 2115
e1623446 2116 IWL_DEBUG_RATE(priv, "LQ: GOING BACK TO THE OLD TABLE "
07bc28ed
GC
2117 "suc=%d cur-tpt=%d old-tpt=%d\n",
2118 window->success_ratio,
2119 window->average_tpt,
2120 lq_sta->last_tpt);
2121
77626355 2122 /* Nullify "search" table */
b481de9c 2123 tbl->lq_type = LQ_NONE;
77626355
BC
2124
2125 /* Revert to "active" table */
c33104f0
TW
2126 active_tbl = lq_sta->active_tbl;
2127 tbl = &(lq_sta->lq_info[active_tbl]);
b481de9c 2128
77626355 2129 /* Revert to "active" rate and throughput info */
e7d326ac 2130 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
c33104f0 2131 current_tpt = lq_sta->last_tpt;
b481de9c 2132
77626355 2133 /* Need to set up a new rate table in uCode */
b481de9c 2134 update_lq = 1;
b481de9c 2135 }
77626355
BC
2136
2137 /* Either way, we've made a decision; modulation mode
2138 * search is done, allow rate adjustment next time. */
c33104f0 2139 lq_sta->search_better_tbl = 0;
77626355 2140 done_search = 1; /* Don't switch modes below! */
b481de9c
ZY
2141 goto lq_update;
2142 }
2143
77626355
BC
2144 /* (Else) not in search of better modulation mode, try for better
2145 * starting rate, while staying in this mode. */
bf403db8 2146 high_low = rs_get_adjacent_rate(priv, index, rate_scale_index_msk,
b481de9c
ZY
2147 tbl->lq_type);
2148 low = high_low & 0xff;
2149 high = (high_low >> 8) & 0xff;
2150
c6ec7a9b
AM
2151 /* If user set max rate, dont allow higher than user constrain */
2152 if ((lq_sta->max_rate_idx != -1) &&
2153 (lq_sta->max_rate_idx < high))
2154 high = IWL_RATE_INVALID;
2155
a5e8b505
GC
2156 sr = window->success_ratio;
2157
77626355 2158 /* Collect measured throughputs for current and adjacent rates */
b481de9c 2159 current_tpt = window->average_tpt;
b481de9c
ZY
2160 if (low != IWL_RATE_INVALID)
2161 low_tpt = tbl->win[low].average_tpt;
b481de9c
ZY
2162 if (high != IWL_RATE_INVALID)
2163 high_tpt = tbl->win[high].average_tpt;
2164
a5e8b505 2165 scale_action = 0;
b481de9c 2166
77626355 2167 /* Too many failures, decrease rate */
a5e8b505 2168 if ((sr <= IWL_RATE_DECREASE_TH) || (current_tpt == 0)) {
e1623446 2169 IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n");
b481de9c 2170 scale_action = -1;
77626355
BC
2171
2172 /* No throughput measured yet for adjacent rates; try increase. */
b481de9c 2173 } else if ((low_tpt == IWL_INVALID_VALUE) &&
a5e8b505
GC
2174 (high_tpt == IWL_INVALID_VALUE)) {
2175
2176 if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH)
2177 scale_action = 1;
2178 else if (low != IWL_RATE_INVALID)
8fe72311 2179 scale_action = 0;
a5e8b505 2180 }
77626355
BC
2181
2182 /* Both adjacent throughputs are measured, but neither one has better
2183 * throughput; we're using the best rate, don't change it! */
b481de9c
ZY
2184 else if ((low_tpt != IWL_INVALID_VALUE) &&
2185 (high_tpt != IWL_INVALID_VALUE) &&
2186 (low_tpt < current_tpt) &&
2187 (high_tpt < current_tpt))
2188 scale_action = 0;
77626355
BC
2189
2190 /* At least one adjacent rate's throughput is measured,
2191 * and may have better performance. */
b481de9c 2192 else {
77626355 2193 /* Higher adjacent rate's throughput is measured */
b481de9c 2194 if (high_tpt != IWL_INVALID_VALUE) {
77626355 2195 /* Higher rate has better throughput */
a5e8b505
GC
2196 if (high_tpt > current_tpt &&
2197 sr >= IWL_RATE_INCREASE_TH) {
b481de9c 2198 scale_action = 1;
a5e8b505 2199 } else {
8fe72311 2200 scale_action = 0;
b481de9c 2201 }
77626355
BC
2202
2203 /* Lower adjacent rate's throughput is measured */
b481de9c 2204 } else if (low_tpt != IWL_INVALID_VALUE) {
77626355 2205 /* Lower rate has better throughput */
b481de9c 2206 if (low_tpt > current_tpt) {
e1623446
TW
2207 IWL_DEBUG_RATE(priv,
2208 "decrease rate because of low tpt\n");
b481de9c 2209 scale_action = -1;
a5e8b505 2210 } else if (sr >= IWL_RATE_INCREASE_TH) {
b481de9c 2211 scale_action = 1;
a5e8b505 2212 }
b481de9c
ZY
2213 }
2214 }
2215
77626355
BC
2216 /* Sanity check; asked for decrease, but success rate or throughput
2217 * has been good at old rate. Don't change it. */
a5e8b505
GC
2218 if ((scale_action == -1) && (low != IWL_RATE_INVALID) &&
2219 ((sr > IWL_RATE_HIGH_TH) ||
b481de9c 2220 (current_tpt > (100 * tbl->expected_tpt[low]))))
b481de9c 2221 scale_action = 0;
46f9381a
WYG
2222 if (!iwl_ht_enabled(priv) && !is_legacy(tbl->lq_type))
2223 scale_action = -1;
3ad3b92a 2224 if (iwl_tx_ant_restriction(priv) != IWL_ANT_OK_MULTI &&
46f9381a
WYG
2225 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type)))
2226 scale_action = -1;
b481de9c
ZY
2227 switch (scale_action) {
2228 case -1:
77626355 2229 /* Decrease starting rate, update uCode's rate table */
b481de9c
ZY
2230 if (low != IWL_RATE_INVALID) {
2231 update_lq = 1;
2232 index = low;
2233 }
447fee70 2234
b481de9c
ZY
2235 break;
2236 case 1:
77626355 2237 /* Increase starting rate, update uCode's rate table */
b481de9c
ZY
2238 if (high != IWL_RATE_INVALID) {
2239 update_lq = 1;
2240 index = high;
2241 }
2242
2243 break;
2244 case 0:
77626355 2245 /* No change */
b481de9c
ZY
2246 default:
2247 break;
2248 }
2249
e1623446 2250 IWL_DEBUG_RATE(priv, "choose rate scale index %d action %d low %d "
b481de9c
ZY
2251 "high %d type %d\n",
2252 index, scale_action, low, high, tbl->lq_type);
2253
a5e8b505 2254lq_update:
77626355 2255 /* Replace uCode's rate table for the destination station. */
e3139fe7
WYG
2256 if (update_lq)
2257 rate = rs_update_rate_tbl(priv, lq_sta,
2258 tbl, index, is_green);
77626355 2259
3ad3b92a 2260 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) {
46f9381a
WYG
2261 /* Should we stay with this modulation mode,
2262 * or search for a new one? */
2263 rs_stay_in_table(lq_sta);
2264 }
77626355
BC
2265 /*
2266 * Search for new modulation mode if we're:
2267 * 1) Not changing rates right now
2268 * 2) Not just finishing up a search
2269 * 3) Allowing a new search
2270 */
47cfd463 2271 if (!update_lq && !done_search && !lq_sta->stay_in_tbl && window->counter) {
77626355 2272 /* Save current throughput to compare with "search" throughput*/
c33104f0 2273 lq_sta->last_tpt = current_tpt;
b481de9c 2274
77626355
BC
2275 /* Select a new "search" modulation mode to try.
2276 * If one is found, set up the new "search" table. */
b481de9c 2277 if (is_legacy(tbl->lq_type))
c33104f0 2278 rs_move_legacy_other(priv, lq_sta, conf, sta, index);
b481de9c 2279 else if (is_siso(tbl->lq_type))
c33104f0 2280 rs_move_siso_to_other(priv, lq_sta, conf, sta, index);
584a0f00
WYG
2281 else if (is_mimo2(tbl->lq_type))
2282 rs_move_mimo2_to_other(priv, lq_sta, conf, sta, index);
b481de9c 2283 else
584a0f00 2284 rs_move_mimo3_to_other(priv, lq_sta, conf, sta, index);
b481de9c 2285
77626355 2286 /* If new "search" mode was selected, set up in uCode table */
c33104f0 2287 if (lq_sta->search_better_tbl) {
77626355 2288 /* Access the "search" table, clear its history. */
c33104f0 2289 tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
b481de9c
ZY
2290 for (i = 0; i < IWL_RATE_COUNT; i++)
2291 rs_rate_scale_clear_window(&(tbl->win[i]));
2292
77626355 2293 /* Use new "search" start rate */
e7d326ac 2294 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
b481de9c 2295
e1623446 2296 IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n",
39e88504 2297 tbl->current_rate, index);
07bc28ed 2298 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
66c73db7 2299 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
447fee70
MA
2300 } else
2301 done_search = 1;
2302 }
b481de9c 2303
447fee70 2304 if (done_search && !lq_sta->stay_in_tbl) {
77626355
BC
2305 /* If the "active" (non-search) mode was legacy,
2306 * and we've tried switching antennas,
2307 * but we haven't been able to try HT modes (not available),
2308 * stay with best antenna legacy modulation for a while
2309 * before next round of mode comparisons. */
c33104f0 2310 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
de27e64e 2311 if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) &&
d6e93399 2312 lq_sta->action_counter > tbl1->max_search) {
e1623446 2313 IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n");
bf403db8 2314 rs_set_stay_in_table(priv, 1, lq_sta);
b481de9c
ZY
2315 }
2316
77626355
BC
2317 /* If we're in an HT mode, and all 3 mode switch actions
2318 * have been tried and compared, stay in this best modulation
2319 * mode for a while before next round of mode comparisons. */
c33104f0 2320 if (lq_sta->enable_counter &&
46f9381a
WYG
2321 (lq_sta->action_counter >= tbl1->max_search) &&
2322 iwl_ht_enabled(priv)) {
0c11b4de
RR
2323 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
2324 (lq_sta->tx_agg_tid_en & (1 << tid)) &&
2325 (tid != MAX_TID_COUNT)) {
86b4766b
WYG
2326 tid_data =
2327 &priv->stations[lq_sta->lq.sta_id].tid[tid];
2328 if (tid_data->agg.state == IWL_AGG_OFF) {
2329 IWL_DEBUG_RATE(priv,
2330 "try to aggregate tid %d\n",
2331 tid);
2332 rs_tl_turn_on_agg(priv, tid,
2333 lq_sta, sta);
2334 }
b481de9c 2335 }
bf403db8 2336 rs_set_stay_in_table(priv, 0, lq_sta);
b481de9c 2337 }
b481de9c
ZY
2338 }
2339
2340out:
978785a3 2341 tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
b481de9c 2342 i = index;
b7e35008 2343 lq_sta->last_txrate_idx = i;
b481de9c 2344
b481de9c
ZY
2345 return;
2346}
2347
2348
c79dd5b5 2349static void rs_initialize_lq(struct iwl_priv *priv,
270243a5 2350 struct ieee80211_conf *conf,
4b7679a5
JB
2351 struct ieee80211_sta *sta,
2352 struct iwl_lq_sta *lq_sta)
b481de9c 2353{
e227ceac 2354 struct iwl_scale_tbl_info *tbl;
b481de9c 2355 int rate_idx;
aade00ce 2356 int i;
39e88504 2357 u32 rate;
b261793d 2358 u8 use_green = rs_use_green(sta, &priv->current_ht_config);
aade00ce
GC
2359 u8 active_tbl = 0;
2360 u8 valid_tx_ant;
b481de9c 2361
4b7679a5 2362 if (!sta || !lq_sta)
b481de9c
ZY
2363 goto out;
2364
b7e35008 2365 i = lq_sta->last_txrate_idx;
b481de9c 2366
c33104f0 2367 if ((lq_sta->lq.sta_id == 0xff) &&
05c914fe 2368 (priv->iw_mode == NL80211_IFTYPE_ADHOC))
b481de9c
ZY
2369 goto out;
2370
aade00ce
GC
2371 valid_tx_ant = priv->hw_params.valid_tx_ant;
2372
c33104f0
TW
2373 if (!lq_sta->search_better_tbl)
2374 active_tbl = lq_sta->active_tbl;
b481de9c 2375 else
c33104f0 2376 active_tbl = 1 - lq_sta->active_tbl;
b481de9c 2377
c33104f0 2378 tbl = &(lq_sta->lq_info[active_tbl]);
b481de9c
ZY
2379
2380 if ((i < 0) || (i >= IWL_RATE_COUNT))
2381 i = 0;
2382
1826dcc0 2383 rate = iwl_rates[i].plcp;
eb48dcaf
WT
2384 tbl->ant_type = first_antenna(valid_tx_ant);
2385 rate |= tbl->ant_type << RATE_MCS_ANT_POS;
b481de9c
ZY
2386
2387 if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE)
39e88504 2388 rate |= RATE_MCS_CCK_MSK;
b481de9c 2389
39e88504 2390 rs_get_tbl_info_from_mcs(rate, priv->band, tbl, &rate_idx);
aade00ce
GC
2391 if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type))
2392 rs_toggle_antenna(valid_tx_ant, &rate, tbl);
b481de9c 2393
978785a3 2394 rate = rate_n_flags_from_tbl(priv, tbl, rate_idx, use_green);
39e88504 2395 tbl->current_rate = rate;
eecd6e57 2396 rs_set_expected_tpt_table(lq_sta, tbl);
07bc28ed 2397 rs_fill_link_cmd(NULL, lq_sta, rate);
66c73db7 2398 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
b481de9c
ZY
2399 out:
2400 return;
2401}
2402
e6a9854b
JB
2403static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2404 struct ieee80211_tx_rate_control *txrc)
b481de9c
ZY
2405{
2406
e6a9854b
JB
2407 struct sk_buff *skb = txrc->skb;
2408 struct ieee80211_supported_band *sband = txrc->sband;
4b7679a5
JB
2409 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
2410 struct ieee80211_conf *conf = &priv->hw->conf;
7869b0ea 2411 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
b481de9c 2412 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
e6a9854b 2413 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
417f114b
TW
2414 struct iwl_lq_sta *lq_sta = priv_sta;
2415 int rate_idx;
b481de9c 2416
e1623446 2417 IWL_DEBUG_RATE_LIMIT(priv, "rate scale calculate new rate for skb\n");
b481de9c 2418
c6ec7a9b
AM
2419 /* Get max rate if user set max rate */
2420 if (lq_sta) {
2421 lq_sta->max_rate_idx = txrc->max_rate_idx;
2422 if ((sband->band == IEEE80211_BAND_5GHZ) &&
2423 (lq_sta->max_rate_idx != -1))
2424 lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE;
2425 if ((lq_sta->max_rate_idx < 0) ||
2426 (lq_sta->max_rate_idx >= IWL_RATE_COUNT))
2427 lq_sta->max_rate_idx = -1;
2428 }
2429
514d65c1 2430 /* Send management frames and NO_ACK data using lowest rate. */
4c6d4f5c 2431 if (rate_control_send_low(sta, priv_sta, txrc))
4b7679a5 2432 return;
b481de9c 2433
417f114b 2434 rate_idx = lq_sta->last_txrate_idx;
b481de9c 2435
05c914fe 2436 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
c33104f0 2437 !lq_sta->ibss_sta_added) {
c587de0b 2438 u8 sta_id = iwl_find_station(priv, hdr->addr1);
b481de9c
ZY
2439
2440 if (sta_id == IWL_INVALID_STATION) {
e1623446 2441 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
e174961c 2442 hdr->addr1);
c587de0b 2443 sta_id = iwl_add_station(priv, hdr->addr1,
7869b0ea 2444 false, CMD_ASYNC, ht_cap);
b481de9c
ZY
2445 }
2446 if ((sta_id != IWL_INVALID_STATION)) {
c33104f0
TW
2447 lq_sta->lq.sta_id = sta_id;
2448 lq_sta->lq.rs_table[0].rate_n_flags = 0;
2449 lq_sta->ibss_sta_added = 1;
4b7679a5 2450 rs_initialize_lq(priv, conf, sta, lq_sta);
b481de9c 2451 }
b481de9c
ZY
2452 }
2453
a9c146b3 2454 if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) {
417f114b 2455 rate_idx -= IWL_FIRST_OFDM_RATE;
a9c146b3
WYG
2456 /* 6M and 9M shared same MCS index */
2457 rate_idx = (rate_idx > 0) ? (rate_idx - 1) : 0;
2458 if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
2459 IWL_RATE_MIMO3_6M_PLCP)
2460 rate_idx = rate_idx + (2 * MCS_INDEX_PER_STREAM);
2461 else if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
2462 IWL_RATE_MIMO2_6M_PLCP)
2463 rate_idx = rate_idx + MCS_INDEX_PER_STREAM;
2464 info->control.rates[0].flags = IEEE80211_TX_RC_MCS;
2465 if (lq_sta->last_rate_n_flags & RATE_MCS_SGI_MSK)
2466 info->control.rates[0].flags |= IEEE80211_TX_RC_SHORT_GI;
2467 if (lq_sta->last_rate_n_flags & RATE_MCS_DUP_MSK)
2468 info->control.rates[0].flags |= IEEE80211_TX_RC_DUP_DATA;
7aafef1c 2469 if (lq_sta->last_rate_n_flags & RATE_MCS_HT40_MSK)
a9c146b3
WYG
2470 info->control.rates[0].flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
2471 if (lq_sta->last_rate_n_flags & RATE_MCS_GF_MSK)
2472 info->control.rates[0].flags |= IEEE80211_TX_RC_GREEN_FIELD;
2473 } else {
5027309b
DH
2474 /* Check for invalid rates */
2475 if ((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT_LEGACY) ||
2476 ((sband->band == IEEE80211_BAND_5GHZ) &&
2477 (rate_idx < IWL_FIRST_OFDM_RATE)))
a9c146b3 2478 rate_idx = rate_lowest_index(sband, sta);
5027309b 2479 /* On valid 5 GHz rate, adjust index */
a9c146b3
WYG
2480 else if (sband->band == IEEE80211_BAND_5GHZ)
2481 rate_idx -= IWL_FIRST_OFDM_RATE;
7ebaeff8 2482 info->control.rates[0].flags = 0;
a9c146b3 2483 }
417f114b 2484 info->control.rates[0].idx = rate_idx;
a9c146b3 2485
b481de9c
ZY
2486}
2487
4b7679a5
JB
2488static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
2489 gfp_t gfp)
b481de9c 2490{
e227ceac 2491 struct iwl_lq_sta *lq_sta;
8d9698b3 2492 struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv;
bf403db8 2493 struct iwl_priv *priv;
b481de9c 2494
bf403db8 2495 priv = (struct iwl_priv *)priv_rate;
e1623446 2496 IWL_DEBUG_RATE(priv, "create station rate scale window\n");
b481de9c 2497
8d9698b3 2498 lq_sta = &sta_priv->lq_sta;
b481de9c 2499
c33104f0 2500 return lq_sta;
b481de9c
ZY
2501}
2502
4b7679a5
JB
2503static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2504 struct ieee80211_sta *sta, void *priv_sta)
b481de9c
ZY
2505{
2506 int i, j;
4b7679a5
JB
2507 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
2508 struct ieee80211_conf *conf = &priv->hw->conf;
7869b0ea 2509 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
e227ceac 2510 struct iwl_lq_sta *lq_sta = priv_sta;
b481de9c 2511
5ad13f8c
RC
2512 lq_sta->lq.sta_id = 0xff;
2513
2514 for (j = 0; j < LQ_SIZE; j++)
2515 for (i = 0; i < IWL_RATE_COUNT; i++)
2516 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2517
c33104f0 2518 lq_sta->flush_timer = 0;
4b7679a5 2519 lq_sta->supp_rates = sta->supp_rates[sband->band];
b481de9c
ZY
2520 for (j = 0; j < LQ_SIZE; j++)
2521 for (i = 0; i < IWL_RATE_COUNT; i++)
3ac7f146 2522 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
b481de9c 2523
e1623446 2524 IWL_DEBUG_RATE(priv, "LQ: *** rate scale station global init ***\n");
b481de9c
ZY
2525 /* TODO: what is a good starting rate for STA? About middle? Maybe not
2526 * the lowest or the highest rate.. Could consider using RSSI from
2527 * previous packets? Need to have IEEE 802.1X auth succeed immediately
2528 * after assoc.. */
2529
c33104f0 2530 lq_sta->ibss_sta_added = 0;
05c914fe 2531 if (priv->iw_mode == NL80211_IFTYPE_AP) {
c587de0b 2532 u8 sta_id = iwl_find_station(priv,
e11bc028 2533 sta->addr);
0795af57 2534
b481de9c 2535 /* for IBSS the call are from tasklet */
e1623446 2536 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
b481de9c
ZY
2537
2538 if (sta_id == IWL_INVALID_STATION) {
e1623446 2539 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
c587de0b 2540 sta_id = iwl_add_station(priv, sta->addr, false,
7869b0ea 2541 CMD_ASYNC, ht_cap);
b481de9c
ZY
2542 }
2543 if ((sta_id != IWL_INVALID_STATION)) {
c33104f0
TW
2544 lq_sta->lq.sta_id = sta_id;
2545 lq_sta->lq.rs_table[0].rate_n_flags = 0;
b481de9c
ZY
2546 }
2547 /* FIXME: this is w/a remove it later */
2548 priv->assoc_station_added = 1;
2549 }
2550
c33104f0 2551 lq_sta->is_dup = 0;
c6ec7a9b 2552 lq_sta->max_rate_idx = -1;
7d049e5a 2553 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
b261793d 2554 lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config);
39e88504 2555 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
c33104f0 2556 lq_sta->active_rate_basic = priv->active_rate_basic;
8318d78a 2557 lq_sta->band = priv->band;
77626355
BC
2558 /*
2559 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
2560 * supp_rates[] does not; shift to convert format, force 9 MBits off.
2561 */
7869b0ea
DH
2562 lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1;
2563 lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1;
c33104f0 2564 lq_sta->active_siso_rate &= ~((u16)0x2);
fde0db31 2565 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
b481de9c 2566
77626355 2567 /* Same here */
7869b0ea
DH
2568 lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1;
2569 lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1;
fde0db31
GC
2570 lq_sta->active_mimo2_rate &= ~((u16)0x2);
2571 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
2572
7869b0ea
DH
2573 lq_sta->active_mimo3_rate = ht_cap->mcs.rx_mask[2] << 1;
2574 lq_sta->active_mimo3_rate |= ht_cap->mcs.rx_mask[2] & 0x1;
fde0db31
GC
2575 lq_sta->active_mimo3_rate &= ~((u16)0x2);
2576 lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;
2577
e1623446 2578 IWL_DEBUG_RATE(priv, "SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n",
c33104f0 2579 lq_sta->active_siso_rate,
fde0db31
GC
2580 lq_sta->active_mimo2_rate,
2581 lq_sta->active_mimo3_rate);
2582
a96a27f9 2583 /* These values will be overridden later */
07bc28ed
GC
2584 lq_sta->lq.general_params.single_stream_ant_msk = ANT_A;
2585 lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB;
2586
0c11b4de
RR
2587 /* as default allow aggregation for all tids */
2588 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
c33104f0 2589 lq_sta->drv = priv;
b481de9c 2590
5027309b
DH
2591 /* Set last_txrate_idx to lowest rate */
2592 lq_sta->last_txrate_idx = rate_lowest_index(sband, sta);
2593 if (sband->band == IEEE80211_BAND_5GHZ)
2594 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
e3949d62 2595 lq_sta->is_agg = 0;
d5e49036 2596
4b7679a5 2597 rs_initialize_lq(priv, conf, sta, lq_sta);
b481de9c
ZY
2598}
2599
46f9381a 2600static void rs_fill_link_cmd(struct iwl_priv *priv,
e227ceac 2601 struct iwl_lq_sta *lq_sta, u32 new_rate)
b481de9c 2602{
e227ceac 2603 struct iwl_scale_tbl_info tbl_type;
b481de9c 2604 int index = 0;
b481de9c 2605 int rate_idx;
1b696de2 2606 int repeat_rate = 0;
aade00ce 2607 u8 ant_toggle_cnt = 0;
b481de9c 2608 u8 use_ht_possible = 1;
aade00ce 2609 u8 valid_tx_ant = 0;
07bc28ed 2610 struct iwl_link_quality_cmd *lq_cmd = &lq_sta->lq;
b481de9c 2611
77626355 2612 /* Override starting rate (index 0) if needed for debug purposes */
39e88504 2613 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
98d7e09a 2614
39e88504 2615 /* Interpret new_rate (rate_n_flags) */
aade00ce 2616 memset(&tbl_type, 0, sizeof(tbl_type));
39e88504 2617 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
b481de9c
ZY
2618 &tbl_type, &rate_idx);
2619
77626355 2620 /* How many times should we repeat the initial rate? */
b481de9c 2621 if (is_legacy(tbl_type.lq_type)) {
aade00ce 2622 ant_toggle_cnt = 1;
1b696de2 2623 repeat_rate = IWL_NUMBER_TRY;
aade00ce 2624 } else {
1b696de2 2625 repeat_rate = IWL_HT_NUMBER_TRY;
aade00ce 2626 }
b481de9c
ZY
2627
2628 lq_cmd->general_params.mimo_delimiter =
2629 is_mimo(tbl_type.lq_type) ? 1 : 0;
77626355
BC
2630
2631 /* Fill 1st table entry (index 0) */
39e88504 2632 lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate);
b481de9c 2633
07bc28ed
GC
2634 if (num_of_ant(tbl_type.ant_type) == 1) {
2635 lq_cmd->general_params.single_stream_ant_msk =
2636 tbl_type.ant_type;
2637 } else if (num_of_ant(tbl_type.ant_type) == 2) {
2638 lq_cmd->general_params.dual_stream_ant_msk =
2639 tbl_type.ant_type;
2640 } /* otherwise we don't modify the existing value */
b481de9c
ZY
2641
2642 index++;
1b696de2 2643 repeat_rate--;
b481de9c 2644
aade00ce
GC
2645 if (priv)
2646 valid_tx_ant = priv->hw_params.valid_tx_ant;
2647
77626355 2648 /* Fill rest of rate table */
b481de9c 2649 while (index < LINK_QUAL_MAX_RETRY_NUM) {
77626355
BC
2650 /* Repeat initial/next rate.
2651 * For legacy IWL_NUMBER_TRY == 1, this loop will not execute.
2652 * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */
1b696de2 2653 while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {
b481de9c 2654 if (is_legacy(tbl_type.lq_type)) {
aade00ce
GC
2655 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
2656 ant_toggle_cnt++;
2657 else if (priv &&
2658 rs_toggle_antenna(valid_tx_ant,
2659 &new_rate, &tbl_type))
2660 ant_toggle_cnt = 1;
2661}
98d7e09a 2662
77626355 2663 /* Override next rate if needed for debug purposes */
c33104f0 2664 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
77626355
BC
2665
2666 /* Fill next table entry */
b481de9c 2667 lq_cmd->rs_table[index].rate_n_flags =
39e88504 2668 cpu_to_le32(new_rate);
1b696de2 2669 repeat_rate--;
b481de9c
ZY
2670 index++;
2671 }
2672
39e88504 2673 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type,
b481de9c
ZY
2674 &rate_idx);
2675
77626355
BC
2676 /* Indicate to uCode which entries might be MIMO.
2677 * If initial rate was MIMO, this will finally end up
2678 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
b481de9c
ZY
2679 if (is_mimo(tbl_type.lq_type))
2680 lq_cmd->general_params.mimo_delimiter = index;
2681
77626355 2682 /* Get next rate */
39e88504
GC
2683 new_rate = rs_get_lower_rate(lq_sta, &tbl_type, rate_idx,
2684 use_ht_possible);
b481de9c 2685
77626355 2686 /* How many times should we repeat the next rate? */
b481de9c 2687 if (is_legacy(tbl_type.lq_type)) {
aade00ce
GC
2688 if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
2689 ant_toggle_cnt++;
2690 else if (priv &&
2691 rs_toggle_antenna(valid_tx_ant,
2692 &new_rate, &tbl_type))
2693 ant_toggle_cnt = 1;
2694
1b696de2 2695 repeat_rate = IWL_NUMBER_TRY;
aade00ce 2696 } else {
1b696de2 2697 repeat_rate = IWL_HT_NUMBER_TRY;
aade00ce 2698 }
b481de9c 2699
77626355
BC
2700 /* Don't allow HT rates after next pass.
2701 * rs_get_lower_rate() will change type to LQ_A or LQ_G. */
b481de9c
ZY
2702 use_ht_possible = 0;
2703
77626355 2704 /* Override next rate if needed for debug purposes */
c33104f0 2705 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
77626355
BC
2706
2707 /* Fill next table entry */
39e88504 2708 lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate);
b481de9c
ZY
2709
2710 index++;
1b696de2 2711 repeat_rate--;
b481de9c
ZY
2712 }
2713
4d80d721 2714 lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
13c33a09
WYG
2715 lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
2716 lq_cmd->agg_params.agg_time_limit =
2717 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
b481de9c
ZY
2718}
2719
4b7679a5 2720static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
b481de9c 2721{
4b7679a5 2722 return hw->priv;
b481de9c
ZY
2723}
2724/* rate scale requires free function to be implemented */
2725static void rs_free(void *priv_rate)
2726{
2727 return;
2728}
2729
4b7679a5
JB
2730static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
2731 void *priv_sta)
b481de9c 2732{
45527c2c 2733 struct iwl_priv *priv __maybe_unused = priv_r;
b481de9c 2734
e1623446 2735 IWL_DEBUG_RATE(priv, "enter\n");
e1623446 2736 IWL_DEBUG_RATE(priv, "leave\n");
b481de9c
ZY
2737}
2738
2739
93dc646a 2740#ifdef CONFIG_MAC80211_DEBUGFS
5ae212c9
ZY
2741static int open_file_generic(struct inode *inode, struct file *file)
2742{
2743 file->private_data = inode->i_private;
2744 return 0;
2745}
e227ceac
TW
2746static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
2747 u32 *rate_n_flags, int index)
98d7e09a 2748{
bf403db8 2749 struct iwl_priv *priv;
3c4955f8
WYG
2750 u8 valid_tx_ant;
2751 u8 ant_sel_tx;
bf403db8
EK
2752
2753 priv = lq_sta->drv;
3c4955f8 2754 valid_tx_ant = priv->hw_params.valid_tx_ant;
39e88504 2755 if (lq_sta->dbg_fixed_rate) {
3c4955f8
WYG
2756 ant_sel_tx =
2757 ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK)
2758 >> RATE_MCS_ANT_POS);
2759 if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) {
39e88504 2760 *rate_n_flags = lq_sta->dbg_fixed_rate;
3c4955f8 2761 IWL_DEBUG_RATE(priv, "Fixed rate ON\n");
39e88504 2762 } else {
3c4955f8
WYG
2763 lq_sta->dbg_fixed_rate = 0;
2764 IWL_ERR(priv,
2765 "Invalid antenna selection 0x%X, Valid is 0x%X\n",
2766 ant_sel_tx, valid_tx_ant);
2767 IWL_DEBUG_RATE(priv, "Fixed rate OFF\n");
39e88504 2768 }
39e88504 2769 } else {
e1623446 2770 IWL_DEBUG_RATE(priv, "Fixed rate OFF\n");
98d7e09a 2771 }
98d7e09a 2772}
5ae212c9 2773
98d7e09a
ZY
2774static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2775 const char __user *user_buf, size_t count, loff_t *ppos)
2776{
e227ceac 2777 struct iwl_lq_sta *lq_sta = file->private_data;
bf403db8 2778 struct iwl_priv *priv;
98d7e09a
ZY
2779 char buf[64];
2780 int buf_size;
2781 u32 parsed_rate;
2782
bf403db8 2783 priv = lq_sta->drv;
98d7e09a
ZY
2784 memset(buf, 0, sizeof(buf));
2785 buf_size = min(count, sizeof(buf) - 1);
2786 if (copy_from_user(buf, user_buf, buf_size))
2787 return -EFAULT;
2788
2789 if (sscanf(buf, "%x", &parsed_rate) == 1)
39e88504 2790 lq_sta->dbg_fixed_rate = parsed_rate;
98d7e09a 2791 else
39e88504 2792 lq_sta->dbg_fixed_rate = 0;
98d7e09a 2793
39e88504
GC
2794 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
2795 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2796 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2797 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
98d7e09a 2798
e1623446 2799 IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
39e88504 2800 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
98d7e09a 2801
39e88504 2802 if (lq_sta->dbg_fixed_rate) {
07bc28ed 2803 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
66c73db7 2804 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC);
98d7e09a
ZY
2805 }
2806
2807 return count;
2808}
0209dc11 2809
5ae212c9
ZY
2810static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2811 char __user *user_buf, size_t count, loff_t *ppos)
2812{
a412c804 2813 char *buff;
5ae212c9
ZY
2814 int desc = 0;
2815 int i = 0;
12b96817 2816 int index = 0;
a412c804 2817 ssize_t ret;
5ae212c9 2818
e227ceac 2819 struct iwl_lq_sta *lq_sta = file->private_data;
d8ae4f52 2820 struct iwl_priv *priv;
adb7b5e6 2821 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
5ae212c9 2822
d8ae4f52 2823 priv = lq_sta->drv;
a412c804
FS
2824 buff = kmalloc(1024, GFP_KERNEL);
2825 if (!buff)
2826 return -ENOMEM;
2827
c33104f0 2828 desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
98d7e09a 2829 desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
c33104f0 2830 lq_sta->total_failed, lq_sta->total_success,
39e88504 2831 lq_sta->active_legacy_rate);
98d7e09a 2832 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
39e88504 2833 lq_sta->dbg_fixed_rate);
d8ae4f52
WYG
2834 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
2835 (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "",
2836 (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "",
2837 (priv->hw_params.valid_tx_ant & ANT_C) ? "ANT_C" : "");
adb7b5e6
WYG
2838 desc += sprintf(buff+desc, "lq type %s\n",
2839 (is_legacy(tbl->lq_type)) ? "legacy" : "HT");
2840 if (is_Ht(tbl->lq_type)) {
2841 desc += sprintf(buff+desc, " %s",
2842 (is_siso(tbl->lq_type)) ? "SISO" :
2843 ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3"));
2844 desc += sprintf(buff+desc, " %s",
7aafef1c 2845 (tbl->is_ht40) ? "40MHz" : "20MHz");
e3949d62
DH
2846 desc += sprintf(buff+desc, " %s %s %s\n", (tbl->is_SGI) ? "SGI" : "",
2847 (lq_sta->is_green) ? "GF enabled" : "",
2848 (lq_sta->is_agg) ? "AGG on" : "");
adb7b5e6 2849 }
12b96817
WYG
2850 desc += sprintf(buff+desc, "last tx rate=0x%X\n",
2851 lq_sta->last_rate_n_flags);
5ae212c9
ZY
2852 desc += sprintf(buff+desc, "general:"
2853 "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
c33104f0
TW
2854 lq_sta->lq.general_params.flags,
2855 lq_sta->lq.general_params.mimo_delimiter,
2856 lq_sta->lq.general_params.single_stream_ant_msk,
2857 lq_sta->lq.general_params.dual_stream_ant_msk);
5ae212c9
ZY
2858
2859 desc += sprintf(buff+desc, "agg:"
2860 "time_limit=%d dist_start_th=%d frame_cnt_limit=%d\n",
c33104f0
TW
2861 le16_to_cpu(lq_sta->lq.agg_params.agg_time_limit),
2862 lq_sta->lq.agg_params.agg_dis_start_th,
2863 lq_sta->lq.agg_params.agg_frame_cnt_limit);
5ae212c9
ZY
2864
2865 desc += sprintf(buff+desc,
2866 "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",
c33104f0
TW
2867 lq_sta->lq.general_params.start_rate_index[0],
2868 lq_sta->lq.general_params.start_rate_index[1],
2869 lq_sta->lq.general_params.start_rate_index[2],
2870 lq_sta->lq.general_params.start_rate_index[3]);
5ae212c9 2871
12b96817
WYG
2872 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
2873 index = iwl_hwrate_to_plcp_idx(
2874 le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
2875 if (is_legacy(tbl->lq_type)) {
2876 desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n",
2877 i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags),
2878 iwl_rate_mcs[index].mbps);
2879 } else {
2880 desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps (%s)\n",
2881 i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags),
2882 iwl_rate_mcs[index].mbps, iwl_rate_mcs[index].mcs);
2883 }
2884 }
5ae212c9 2885
a412c804
FS
2886 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
2887 kfree(buff);
2888 return ret;
5ae212c9
ZY
2889}
2890
2891static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
98d7e09a 2892 .write = rs_sta_dbgfs_scale_table_write,
5ae212c9
ZY
2893 .read = rs_sta_dbgfs_scale_table_read,
2894 .open = open_file_generic,
2895};
0209dc11
ZY
2896static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2897 char __user *user_buf, size_t count, loff_t *ppos)
2898{
a412c804 2899 char *buff;
0209dc11
ZY
2900 int desc = 0;
2901 int i, j;
a412c804 2902 ssize_t ret;
0209dc11 2903
e227ceac 2904 struct iwl_lq_sta *lq_sta = file->private_data;
a412c804
FS
2905
2906 buff = kmalloc(1024, GFP_KERNEL);
2907 if (!buff)
2908 return -ENOMEM;
2909
0209dc11 2910 for (i = 0; i < LQ_SIZE; i++) {
7aafef1c
WYG
2911 desc += sprintf(buff+desc,
2912 "%s type=%d SGI=%d HT40=%d DUP=%d GF=%d\n"
0209dc11 2913 "rate=0x%X\n",
c3056065 2914 lq_sta->active_tbl == i ? "*" : "x",
c33104f0
TW
2915 lq_sta->lq_info[i].lq_type,
2916 lq_sta->lq_info[i].is_SGI,
7aafef1c 2917 lq_sta->lq_info[i].is_ht40,
c33104f0 2918 lq_sta->lq_info[i].is_dup,
2681b20b 2919 lq_sta->is_green,
39e88504 2920 lq_sta->lq_info[i].current_rate);
0209dc11
ZY
2921 for (j = 0; j < IWL_RATE_COUNT; j++) {
2922 desc += sprintf(buff+desc,
c33104f0
TW
2923 "counter=%d success=%d %%=%d\n",
2924 lq_sta->lq_info[i].win[j].counter,
2925 lq_sta->lq_info[i].win[j].success_counter,
2926 lq_sta->lq_info[i].win[j].success_ratio);
0209dc11
ZY
2927 }
2928 }
a412c804
FS
2929 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
2930 kfree(buff);
2931 return ret;
0209dc11
ZY
2932}
2933
2934static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
2935 .read = rs_sta_dbgfs_stats_table_read,
2936 .open = open_file_generic,
2937};
5ae212c9 2938
38167459
WYG
2939static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
2940 char __user *user_buf, size_t count, loff_t *ppos)
2941{
2942 char buff[120];
2943 int desc = 0;
2944 ssize_t ret;
2945
2946 struct iwl_lq_sta *lq_sta = file->private_data;
2947 struct iwl_priv *priv;
2948 struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl];
2949
2950 priv = lq_sta->drv;
2951
2952 if (is_Ht(tbl->lq_type))
2953 desc += sprintf(buff+desc,
2954 "Bit Rate= %d Mb/s\n",
2955 tbl->expected_tpt[lq_sta->last_txrate_idx]);
2956 else
2957 desc += sprintf(buff+desc,
2958 "Bit Rate= %d Mb/s\n",
2959 iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
2960 desc += sprintf(buff+desc,
2961 "Signal Level= %d dBm\tNoise Level= %d dBm\n",
2962 priv->last_rx_rssi, priv->last_rx_noise);
2963 desc += sprintf(buff+desc,
2964 "Tsf= 0x%llx\tBeacon time= 0x%08X\n",
2965 priv->last_tsf, priv->last_beacon_time);
2966
2967 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
2968 return ret;
2969}
2970
2971static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
2972 .read = rs_sta_dbgfs_rate_scale_data_read,
2973 .open = open_file_generic,
2974};
2975
93dc646a
ZY
2976static void rs_add_debugfs(void *priv, void *priv_sta,
2977 struct dentry *dir)
2978{
e227ceac 2979 struct iwl_lq_sta *lq_sta = priv_sta;
c33104f0 2980 lq_sta->rs_sta_dbgfs_scale_table_file =
43e85115 2981 debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir,
c33104f0
TW
2982 lq_sta, &rs_sta_dbgfs_scale_table_ops);
2983 lq_sta->rs_sta_dbgfs_stats_table_file =
43e85115 2984 debugfs_create_file("rate_stats_table", S_IRUSR, dir,
c33104f0 2985 lq_sta, &rs_sta_dbgfs_stats_table_ops);
38167459 2986 lq_sta->rs_sta_dbgfs_rate_scale_data_file =
43e85115 2987 debugfs_create_file("rate_scale_data", S_IRUSR, dir,
38167459 2988 lq_sta, &rs_sta_dbgfs_rate_scale_data_ops);
0c11b4de 2989 lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
43e85115 2990 debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir,
0c11b4de 2991 &lq_sta->tx_agg_tid_en);
0c11b4de 2992
93dc646a
ZY
2993}
2994
2995static void rs_remove_debugfs(void *priv, void *priv_sta)
2996{
e227ceac 2997 struct iwl_lq_sta *lq_sta = priv_sta;
c33104f0
TW
2998 debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
2999 debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
38167459 3000 debugfs_remove(lq_sta->rs_sta_dbgfs_rate_scale_data_file);
0c11b4de 3001 debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
93dc646a
ZY
3002}
3003#endif
3004
b481de9c
ZY
3005static struct rate_control_ops rs_ops = {
3006 .module = NULL,
3007 .name = RS_NAME,
3008 .tx_status = rs_tx_status,
3009 .get_rate = rs_get_rate,
3010 .rate_init = rs_rate_init,
b481de9c
ZY
3011 .alloc = rs_alloc,
3012 .free = rs_free,
3013 .alloc_sta = rs_alloc_sta,
3014 .free_sta = rs_free_sta,
93dc646a
ZY
3015#ifdef CONFIG_MAC80211_DEBUGFS
3016 .add_sta_debugfs = rs_add_debugfs,
3017 .remove_sta_debugfs = rs_remove_debugfs,
3018#endif
b481de9c
ZY
3019};
3020
e227ceac 3021int iwlagn_rate_control_register(void)
b481de9c 3022{
897e1cf2 3023 return ieee80211_rate_control_register(&rs_ops);
b481de9c
ZY
3024}
3025
e227ceac 3026void iwlagn_rate_control_unregister(void)
b481de9c
ZY
3027{
3028 ieee80211_rate_control_unregister(&rs_ops);
3029}
3030