aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-rs.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c539
1 files changed, 440 insertions, 99 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 23e5c42e7d7e..592b0cfcf717 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. 3 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 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 6 * under the terms of version 2 of the GNU General Public License as
@@ -39,6 +39,7 @@
39#include "iwl-dev.h" 39#include "iwl-dev.h"
40#include "iwl-sta.h" 40#include "iwl-sta.h"
41#include "iwl-core.h" 41#include "iwl-core.h"
42#include "iwl-agn.h"
42 43
43#define RS_NAME "iwl-agn-rs" 44#define RS_NAME "iwl-agn-rs"
44 45
@@ -76,12 +77,87 @@ static const u8 ant_toggle_lookup[] = {
76 /*ANT_ABC -> */ ANT_ABC, 77 /*ANT_ABC -> */ ANT_ABC,
77}; 78};
78 79
80#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
81 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
82 IWL_RATE_SISO_##s##M_PLCP, \
83 IWL_RATE_MIMO2_##s##M_PLCP,\
84 IWL_RATE_MIMO3_##s##M_PLCP,\
85 IWL_RATE_##r##M_IEEE, \
86 IWL_RATE_##ip##M_INDEX, \
87 IWL_RATE_##in##M_INDEX, \
88 IWL_RATE_##rp##M_INDEX, \
89 IWL_RATE_##rn##M_INDEX, \
90 IWL_RATE_##pp##M_INDEX, \
91 IWL_RATE_##np##M_INDEX }
92
93/*
94 * Parameter order:
95 * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
96 *
97 * If there isn't a valid next or previous rate then INV is used which
98 * maps to IWL_RATE_INVALID
99 *
100 */
101const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
102 IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */
103 IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */
104 IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */
105 IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */
106 IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */
107 IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */
108 IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */
109 IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */
110 IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */
111 IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */
112 IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */
113 IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */
114 IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */
115 /* FIXME:RS: ^^ should be INV (legacy) */
116};
117
118static inline u8 rs_extract_rate(u32 rate_n_flags)
119{
120 return (u8)(rate_n_flags & RATE_MCS_RATE_MSK);
121}
122
123static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
124{
125 int idx = 0;
126
127 /* HT rate format */
128 if (rate_n_flags & RATE_MCS_HT_MSK) {
129 idx = rs_extract_rate(rate_n_flags);
130
131 if (idx >= IWL_RATE_MIMO3_6M_PLCP)
132 idx = idx - IWL_RATE_MIMO3_6M_PLCP;
133 else if (idx >= IWL_RATE_MIMO2_6M_PLCP)
134 idx = idx - IWL_RATE_MIMO2_6M_PLCP;
135
136 idx += IWL_FIRST_OFDM_RATE;
137 /* skip 9M not supported in ht*/
138 if (idx >= IWL_RATE_9M_INDEX)
139 idx += 1;
140 if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
141 return idx;
142
143 /* legacy rate format, search for match in table */
144 } else {
145 for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
146 if (iwl_rates[idx].plcp ==
147 rs_extract_rate(rate_n_flags))
148 return idx;
149 }
150
151 return -1;
152}
153
79static void rs_rate_scale_perform(struct iwl_priv *priv, 154static void rs_rate_scale_perform(struct iwl_priv *priv,
80 struct sk_buff *skb, 155 struct sk_buff *skb,
81 struct ieee80211_sta *sta, 156 struct ieee80211_sta *sta,
82 struct iwl_lq_sta *lq_sta); 157 struct iwl_lq_sta *lq_sta);
83static void rs_fill_link_cmd(struct iwl_priv *priv, 158static void rs_fill_link_cmd(struct iwl_priv *priv,
84 struct iwl_lq_sta *lq_sta, u32 rate_n_flags); 159 struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
160static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);
85 161
86 162
87#ifdef CONFIG_MAC80211_DEBUGFS 163#ifdef CONFIG_MAC80211_DEBUGFS
@@ -109,31 +185,31 @@ static s32 expected_tpt_legacy[IWL_RATE_COUNT] = {
109}; 185};
110 186
111static s32 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = { 187static s32 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = {
112 {0, 0, 0, 0, 42, 0, 76, 102, 124, 158, 183, 193, 202}, /* Norm */ 188 {0, 0, 0, 0, 42, 0, 76, 102, 124, 159, 183, 193, 202}, /* Norm */
113 {0, 0, 0, 0, 46, 0, 82, 110, 132, 167, 192, 202, 210}, /* SGI */ 189 {0, 0, 0, 0, 46, 0, 82, 110, 132, 168, 192, 202, 210}, /* SGI */
114 {0, 0, 0, 0, 48, 0, 93, 135, 176, 251, 319, 351, 381}, /* AGG */ 190 {0, 0, 0, 0, 47, 0, 91, 133, 171, 242, 305, 334, 362}, /* AGG */
115 {0, 0, 0, 0, 53, 0, 102, 149, 193, 275, 348, 381, 413}, /* AGG+SGI */ 191 {0, 0, 0, 0, 52, 0, 101, 145, 187, 264, 330, 361, 390}, /* AGG+SGI */
116}; 192};
117 193
118static s32 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = { 194static s32 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = {
119 {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257}, /* Norm */ 195 {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 */ 196 {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 */ 197 {0, 0, 0, 0, 94, 0, 177, 249, 313, 423, 512, 550, 586}, /* AGG */
122 {0, 0, 0, 0, 106, 0, 199, 282, 357, 487, 593, 640, 683}, /* AGG+SGI */ 198 {0, 0, 0, 0, 104, 0, 193, 270, 338, 454, 545, 584, 620}, /* AGG+SGI */
123}; 199};
124 200
125static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = { 201static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = {
126 {0, 0, 0, 0, 74, 0, 123, 155, 179, 213, 235, 243, 250}, /* Norm */ 202 {0, 0, 0, 0, 74, 0, 123, 155, 179, 214, 236, 244, 251}, /* Norm */
127 {0, 0, 0, 0, 81, 0, 131, 164, 187, 221, 242, 250, 256}, /* SGI */ 203 {0, 0, 0, 0, 81, 0, 131, 164, 188, 223, 243, 251, 257}, /* SGI */
128 {0, 0, 0, 0, 92, 0, 175, 250, 317, 436, 534, 578, 619}, /* AGG */ 204 {0, 0, 0, 0, 89, 0, 167, 235, 296, 402, 488, 526, 560}, /* AGG */
129 {0, 0, 0, 0, 102, 0, 192, 273, 344, 470, 573, 619, 660}, /* AGG+SGI*/ 205 {0, 0, 0, 0, 97, 0, 182, 255, 320, 431, 520, 558, 593}, /* AGG+SGI*/
130}; 206};
131 207
132static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = { 208static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = {
133 {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289}, /* Norm */ 209 {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 */ 210 {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 */ 211 {0, 0, 0, 0, 171, 0, 305, 410, 496, 634, 731, 771, 805}, /* AGG */
136 {0, 0, 0, 0, 197, 0, 355, 481, 584, 752, 872, 922, 966}, /* AGG+SGI */ 212 {0, 0, 0, 0, 186, 0, 329, 439, 527, 667, 764, 803, 838}, /* AGG+SGI */
137}; 213};
138 214
139static s32 expected_tpt_mimo3_20MHz[4][IWL_RATE_COUNT] = { 215static s32 expected_tpt_mimo3_20MHz[4][IWL_RATE_COUNT] = {
@@ -169,11 +245,6 @@ static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
169 245
170#define MCS_INDEX_PER_STREAM (8) 246#define MCS_INDEX_PER_STREAM (8)
171 247
172static inline u8 rs_extract_rate(u32 rate_n_flags)
173{
174 return (u8)(rate_n_flags & 0xFF);
175}
176
177static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) 248static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
178{ 249{
179 window->data = 0; 250 window->data = 0;
@@ -264,6 +335,32 @@ static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
264 return tid; 335 return tid;
265} 336}
266 337
338#ifdef CONFIG_MAC80211_DEBUGFS
339static void rs_program_fix_rate(struct iwl_priv *priv,
340 struct iwl_lq_sta *lq_sta)
341{
342 struct iwl_station_priv *sta_priv =
343 container_of(lq_sta, struct iwl_station_priv, lq_sta);
344 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
345
346 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
347 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
348 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
349 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
350
351 lq_sta->dbg_fixed_rate = priv->dbg_fixed_rate;
352
353 IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
354 lq_sta->lq.sta_id, priv->dbg_fixed_rate);
355
356 if (priv->dbg_fixed_rate) {
357 rs_fill_link_cmd(NULL, lq_sta, priv->dbg_fixed_rate);
358 iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC,
359 false);
360 }
361}
362#endif
363
267/* 364/*
268 get the traffic load value for tid 365 get the traffic load value for tid
269*/ 366*/
@@ -300,12 +397,24 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
300 struct ieee80211_sta *sta) 397 struct ieee80211_sta *sta)
301{ 398{
302 int ret = -EAGAIN; 399 int ret = -EAGAIN;
303 u32 load = rs_tl_get_load(lq_data, tid); 400 u32 load;
401
402 /*
403 * Don't create TX aggregation sessions when in high
404 * BT traffic, as they would just be disrupted by BT.
405 */
406 if (priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) {
407 IWL_ERR(priv, "BT traffic (%d), no aggregation allowed\n",
408 priv->bt_traffic_load);
409 return ret;
410 }
411
412 load = rs_tl_get_load(lq_data, tid);
304 413
305 if (load > IWL_AGG_LOAD_THRESHOLD) { 414 if (load > IWL_AGG_LOAD_THRESHOLD) {
306 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", 415 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
307 sta->addr, tid); 416 sta->addr, tid);
308 ret = ieee80211_start_tx_ba_session(sta, tid); 417 ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
309 if (ret == -EAGAIN) { 418 if (ret == -EAGAIN) {
310 /* 419 /*
311 * driver and mac80211 is out of sync 420 * driver and mac80211 is out of sync
@@ -502,6 +611,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
502 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags); 611 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);
503 u8 mcs; 612 u8 mcs;
504 613
614 memset(tbl, 0, sizeof(struct iwl_scale_tbl_info));
505 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); 615 *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
506 616
507 if (*rate_idx == IWL_RATE_INVALID) { 617 if (*rate_idx == IWL_RATE_INVALID) {
@@ -588,11 +698,13 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
588 * Green-field mode is valid if the station supports it and 698 * Green-field mode is valid if the station supports it and
589 * there are no non-GF stations present in the BSS. 699 * there are no non-GF stations present in the BSS.
590 */ 700 */
591static inline u8 rs_use_green(struct ieee80211_sta *sta, 701static bool rs_use_green(struct ieee80211_sta *sta)
592 struct iwl_ht_config *ht_conf)
593{ 702{
703 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
704 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
705
594 return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && 706 return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
595 !(ht_conf->non_GF_STA_present); 707 !(ctx->ht.non_gf_sta_present);
596} 708}
597 709
598/** 710/**
@@ -744,6 +856,38 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a,
744 (a->is_SGI == b->is_SGI); 856 (a->is_SGI == b->is_SGI);
745} 857}
746 858
859static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
860 struct iwl_lq_sta *lq_sta)
861{
862 struct iwl_scale_tbl_info *tbl;
863 bool full_concurrent = priv->bt_full_concurrent;
864 unsigned long flags;
865
866 if (priv->bt_ant_couple_ok) {
867 /*
868 * Is there a need to switch between
869 * full concurrency and 3-wire?
870 */
871 spin_lock_irqsave(&priv->lock, flags);
872 if (priv->bt_ci_compliance && priv->bt_ant_couple_ok)
873 full_concurrent = true;
874 else
875 full_concurrent = false;
876 spin_unlock_irqrestore(&priv->lock, flags);
877 }
878 if ((priv->bt_traffic_load != priv->last_bt_traffic_load) ||
879 (priv->bt_full_concurrent != full_concurrent)) {
880 priv->bt_full_concurrent = full_concurrent;
881
882 /* Update uCode's rate table. */
883 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
884 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
885 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
886
887 queue_work(priv->workqueue, &priv->bt_full_concurrency);
888 }
889}
890
747/* 891/*
748 * mac80211 sends us Tx status 892 * mac80211 sends us Tx status
749 */ 893 */
@@ -763,6 +907,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
763 u32 tx_rate; 907 u32 tx_rate;
764 struct iwl_scale_tbl_info tbl_type; 908 struct iwl_scale_tbl_info tbl_type;
765 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; 909 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
910 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
911 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
766 912
767 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); 913 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
768 914
@@ -829,7 +975,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
829 lq_sta->missed_rate_counter++; 975 lq_sta->missed_rate_counter++;
830 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { 976 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
831 lq_sta->missed_rate_counter = 0; 977 lq_sta->missed_rate_counter = 0;
832 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false); 978 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
833 } 979 }
834 /* Regardless, ignore this status info for outdated rate */ 980 /* Regardless, ignore this status info for outdated rate */
835 return; 981 return;
@@ -848,7 +994,20 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
848 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 994 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
849 } else { 995 } else {
850 IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n"); 996 IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
851 return; 997 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
998 IWL_DEBUG_RATE(priv, "active- lq:%x, ant:%x, SGI:%d\n",
999 tmp_tbl->lq_type, tmp_tbl->ant_type, tmp_tbl->is_SGI);
1000 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
1001 IWL_DEBUG_RATE(priv, "search- lq:%x, ant:%x, SGI:%d\n",
1002 tmp_tbl->lq_type, tmp_tbl->ant_type, tmp_tbl->is_SGI);
1003 IWL_DEBUG_RATE(priv, "actual- lq:%x, ant:%x, SGI:%d\n",
1004 tbl_type.lq_type, tbl_type.ant_type, tbl_type.is_SGI);
1005 /*
1006 * no matching table found, let's by-pass the data collection
1007 * and continue to perform rate scale to find the rate table
1008 */
1009 rs_stay_in_table(lq_sta, true);
1010 goto done;
852 } 1011 }
853 1012
854 /* 1013 /*
@@ -909,10 +1068,16 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
909 } 1068 }
910 /* The last TX rate is cached in lq_sta; it's set in if/else above */ 1069 /* The last TX rate is cached in lq_sta; it's set in if/else above */
911 lq_sta->last_rate_n_flags = tx_rate; 1070 lq_sta->last_rate_n_flags = tx_rate;
912 1071done:
913 /* See if there's a better rate or modulation mode to try. */ 1072 /* See if there's a better rate or modulation mode to try. */
914 if (sta && sta->supp_rates[sband->band]) 1073 if (sta && sta->supp_rates[sband->band])
915 rs_rate_scale_perform(priv, skb, sta, lq_sta); 1074 rs_rate_scale_perform(priv, skb, sta, lq_sta);
1075#ifdef CONFIG_MAC80211_DEBUGFS
1076 if (priv->dbg_fixed_rate != lq_sta->dbg_fixed_rate)
1077 rs_program_fix_rate(priv, lq_sta);
1078#endif
1079 if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
1080 rs_bt_update_lq(priv, ctx, lq_sta);
916} 1081}
917 1082
918/* 1083/*
@@ -1106,6 +1271,8 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
1106 u16 rate_mask; 1271 u16 rate_mask;
1107 s32 rate; 1272 s32 rate;
1108 s8 is_green = lq_sta->is_green; 1273 s8 is_green = lq_sta->is_green;
1274 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
1275 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
1109 1276
1110 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) 1277 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
1111 return -1; 1278 return -1;
@@ -1126,7 +1293,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
1126 tbl->max_search = IWL_MAX_SEARCH; 1293 tbl->max_search = IWL_MAX_SEARCH;
1127 rate_mask = lq_sta->active_mimo2_rate; 1294 rate_mask = lq_sta->active_mimo2_rate;
1128 1295
1129 if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap)) 1296 if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
1130 tbl->is_ht40 = 1; 1297 tbl->is_ht40 = 1;
1131 else 1298 else
1132 tbl->is_ht40 = 0; 1299 tbl->is_ht40 = 0;
@@ -1160,6 +1327,8 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
1160 u16 rate_mask; 1327 u16 rate_mask;
1161 s32 rate; 1328 s32 rate;
1162 s8 is_green = lq_sta->is_green; 1329 s8 is_green = lq_sta->is_green;
1330 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
1331 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
1163 1332
1164 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) 1333 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
1165 return -1; 1334 return -1;
@@ -1180,7 +1349,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
1180 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH; 1349 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
1181 rate_mask = lq_sta->active_mimo3_rate; 1350 rate_mask = lq_sta->active_mimo3_rate;
1182 1351
1183 if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap)) 1352 if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
1184 tbl->is_ht40 = 1; 1353 tbl->is_ht40 = 1;
1185 else 1354 else
1186 tbl->is_ht40 = 0; 1355 tbl->is_ht40 = 0;
@@ -1215,6 +1384,8 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
1215 u16 rate_mask; 1384 u16 rate_mask;
1216 u8 is_green = lq_sta->is_green; 1385 u8 is_green = lq_sta->is_green;
1217 s32 rate; 1386 s32 rate;
1387 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
1388 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
1218 1389
1219 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) 1390 if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
1220 return -1; 1391 return -1;
@@ -1227,7 +1398,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
1227 tbl->max_search = IWL_MAX_SEARCH; 1398 tbl->max_search = IWL_MAX_SEARCH;
1228 rate_mask = lq_sta->active_siso_rate; 1399 rate_mask = lq_sta->active_siso_rate;
1229 1400
1230 if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap)) 1401 if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
1231 tbl->is_ht40 = 1; 1402 tbl->is_ht40 = 1;
1232 else 1403 else
1233 tbl->is_ht40 = 0; 1404 tbl->is_ht40 = 0;
@@ -1265,18 +1436,52 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1265 struct iwl_rate_scale_data *window = &(tbl->win[index]); 1436 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1266 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1437 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1267 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1438 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1268 u8 start_action = tbl->action; 1439 u8 start_action;
1269 u8 valid_tx_ant = priv->hw_params.valid_tx_ant; 1440 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1270 u8 tx_chains_num = priv->hw_params.tx_chains_num; 1441 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1271 int ret = 0; 1442 int ret = 0;
1272 u8 update_search_tbl_counter = 0; 1443 u8 update_search_tbl_counter = 0;
1273 1444
1445 switch (priv->bt_traffic_load) {
1446 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1447 /* nothing */
1448 break;
1449 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1450 /* avoid antenna B unless MIMO */
1451 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1452 if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2)
1453 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1454 break;
1455 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1456 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1457 /* avoid antenna B and MIMO */
1458 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1459 if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 &&
1460 tbl->action != IWL_LEGACY_SWITCH_SISO)
1461 tbl->action = IWL_LEGACY_SWITCH_SISO;
1462 break;
1463 default:
1464 IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
1465 break;
1466 }
1467
1274 if (!iwl_ht_enabled(priv)) 1468 if (!iwl_ht_enabled(priv))
1275 /* stay in Legacy */ 1469 /* stay in Legacy */
1276 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; 1470 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1277 else if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE && 1471 else if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE &&
1278 tbl->action > IWL_LEGACY_SWITCH_SISO) 1472 tbl->action > IWL_LEGACY_SWITCH_SISO)
1279 tbl->action = IWL_LEGACY_SWITCH_SISO; 1473 tbl->action = IWL_LEGACY_SWITCH_SISO;
1474
1475 /* configure as 1x1 if bt full concurrency */
1476 if (priv->bt_full_concurrent) {
1477 if (!iwl_ht_enabled(priv))
1478 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1479 else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)
1480 tbl->action = IWL_LEGACY_SWITCH_SISO;
1481 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1482 }
1483
1484 start_action = tbl->action;
1280 for (; ;) { 1485 for (; ;) {
1281 lq_sta->action_counter++; 1486 lq_sta->action_counter++;
1282 switch (tbl->action) { 1487 switch (tbl->action) {
@@ -1291,7 +1496,10 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1291 break; 1496 break;
1292 1497
1293 /* Don't change antenna if success has been great */ 1498 /* Don't change antenna if success has been great */
1294 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1499 if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
1500 !priv->bt_full_concurrent &&
1501 priv->bt_traffic_load ==
1502 IWL_BT_COEX_TRAFFIC_LOAD_NONE)
1295 break; 1503 break;
1296 1504
1297 /* Set up search table to try other antenna */ 1505 /* Set up search table to try other antenna */
@@ -1403,31 +1611,64 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1403 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 1611 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1404 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1612 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1405 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1613 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1406 u8 start_action = tbl->action; 1614 u8 start_action;
1407 u8 valid_tx_ant = priv->hw_params.valid_tx_ant; 1615 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1408 u8 tx_chains_num = priv->hw_params.tx_chains_num; 1616 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1409 u8 update_search_tbl_counter = 0; 1617 u8 update_search_tbl_counter = 0;
1410 int ret; 1618 int ret;
1411 1619
1620 switch (priv->bt_traffic_load) {
1621 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1622 /* nothing */
1623 break;
1624 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1625 /* avoid antenna B unless MIMO */
1626 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1627 if (tbl->action == IWL_SISO_SWITCH_ANTENNA2)
1628 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1629 break;
1630 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1631 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1632 /* avoid antenna B and MIMO */
1633 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1634 if (tbl->action != IWL_SISO_SWITCH_ANTENNA1)
1635 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1636 break;
1637 default:
1638 IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
1639 break;
1640 }
1641
1412 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE && 1642 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE &&
1413 tbl->action > IWL_SISO_SWITCH_ANTENNA2) { 1643 tbl->action > IWL_SISO_SWITCH_ANTENNA2) {
1414 /* stay in SISO */ 1644 /* stay in SISO */
1415 tbl->action = IWL_SISO_SWITCH_ANTENNA1; 1645 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1416 } 1646 }
1647
1648 /* configure as 1x1 if bt full concurrency */
1649 if (priv->bt_full_concurrent) {
1650 valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant);
1651 if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2)
1652 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1653 }
1654
1655 start_action = tbl->action;
1417 for (;;) { 1656 for (;;) {
1418 lq_sta->action_counter++; 1657 lq_sta->action_counter++;
1419 switch (tbl->action) { 1658 switch (tbl->action) {
1420 case IWL_SISO_SWITCH_ANTENNA1: 1659 case IWL_SISO_SWITCH_ANTENNA1:
1421 case IWL_SISO_SWITCH_ANTENNA2: 1660 case IWL_SISO_SWITCH_ANTENNA2:
1422 IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n"); 1661 IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n");
1423
1424 if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 && 1662 if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
1425 tx_chains_num <= 1) || 1663 tx_chains_num <= 1) ||
1426 (tbl->action == IWL_SISO_SWITCH_ANTENNA2 && 1664 (tbl->action == IWL_SISO_SWITCH_ANTENNA2 &&
1427 tx_chains_num <= 2)) 1665 tx_chains_num <= 2))
1428 break; 1666 break;
1429 1667
1430 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1668 if (window->success_ratio >= IWL_RS_GOOD_RATIO &&
1669 !priv->bt_full_concurrent &&
1670 priv->bt_traffic_load ==
1671 IWL_BT_COEX_TRAFFIC_LOAD_NONE)
1431 break; 1672 break;
1432 1673
1433 memcpy(search_tbl, tbl, sz); 1674 memcpy(search_tbl, tbl, sz);
@@ -1541,18 +1782,47 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
1541 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 1782 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1542 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1783 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1543 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1784 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1544 u8 start_action = tbl->action; 1785 u8 start_action;
1545 u8 valid_tx_ant = priv->hw_params.valid_tx_ant; 1786 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1546 u8 tx_chains_num = priv->hw_params.tx_chains_num; 1787 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1547 u8 update_search_tbl_counter = 0; 1788 u8 update_search_tbl_counter = 0;
1548 int ret; 1789 int ret;
1549 1790
1791 switch (priv->bt_traffic_load) {
1792 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1793 /* nothing */
1794 break;
1795 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1796 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1797 /* avoid antenna B and MIMO */
1798 if (tbl->action != IWL_MIMO2_SWITCH_SISO_A)
1799 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1800 break;
1801 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1802 /* avoid antenna B unless MIMO */
1803 if (tbl->action == IWL_MIMO2_SWITCH_SISO_B ||
1804 tbl->action == IWL_MIMO2_SWITCH_SISO_C)
1805 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1806 break;
1807 default:
1808 IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
1809 break;
1810 }
1811
1550 if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) && 1812 if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) &&
1551 (tbl->action < IWL_MIMO2_SWITCH_SISO_A || 1813 (tbl->action < IWL_MIMO2_SWITCH_SISO_A ||
1552 tbl->action > IWL_MIMO2_SWITCH_SISO_C)) { 1814 tbl->action > IWL_MIMO2_SWITCH_SISO_C)) {
1553 /* switch in SISO */ 1815 /* switch in SISO */
1554 tbl->action = IWL_MIMO2_SWITCH_SISO_A; 1816 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1555 } 1817 }
1818
1819 /* configure as 1x1 if bt full concurrency */
1820 if (priv->bt_full_concurrent &&
1821 (tbl->action < IWL_MIMO2_SWITCH_SISO_A ||
1822 tbl->action > IWL_MIMO2_SWITCH_SISO_C))
1823 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1824
1825 start_action = tbl->action;
1556 for (;;) { 1826 for (;;) {
1557 lq_sta->action_counter++; 1827 lq_sta->action_counter++;
1558 switch (tbl->action) { 1828 switch (tbl->action) {
@@ -1682,18 +1952,47 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
1682 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 1952 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1683 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1953 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1684 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1954 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1685 u8 start_action = tbl->action; 1955 u8 start_action;
1686 u8 valid_tx_ant = priv->hw_params.valid_tx_ant; 1956 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1687 u8 tx_chains_num = priv->hw_params.tx_chains_num; 1957 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1688 int ret; 1958 int ret;
1689 u8 update_search_tbl_counter = 0; 1959 u8 update_search_tbl_counter = 0;
1690 1960
1961 switch (priv->bt_traffic_load) {
1962 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
1963 /* nothing */
1964 break;
1965 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1966 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1967 /* avoid antenna B and MIMO */
1968 if (tbl->action != IWL_MIMO3_SWITCH_SISO_A)
1969 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1970 break;
1971 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1972 /* avoid antenna B unless MIMO */
1973 if (tbl->action == IWL_MIMO3_SWITCH_SISO_B ||
1974 tbl->action == IWL_MIMO3_SWITCH_SISO_C)
1975 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1976 break;
1977 default:
1978 IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load);
1979 break;
1980 }
1981
1691 if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) && 1982 if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) &&
1692 (tbl->action < IWL_MIMO3_SWITCH_SISO_A || 1983 (tbl->action < IWL_MIMO3_SWITCH_SISO_A ||
1693 tbl->action > IWL_MIMO3_SWITCH_SISO_C)) { 1984 tbl->action > IWL_MIMO3_SWITCH_SISO_C)) {
1694 /* switch in SISO */ 1985 /* switch in SISO */
1695 tbl->action = IWL_MIMO3_SWITCH_SISO_A; 1986 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1696 } 1987 }
1988
1989 /* configure as 1x1 if bt full concurrency */
1990 if (priv->bt_full_concurrent &&
1991 (tbl->action < IWL_MIMO3_SWITCH_SISO_A ||
1992 tbl->action > IWL_MIMO3_SWITCH_SISO_C))
1993 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1994
1995 start_action = tbl->action;
1697 for (;;) { 1996 for (;;) {
1698 lq_sta->action_counter++; 1997 lq_sta->action_counter++;
1699 switch (tbl->action) { 1998 switch (tbl->action) {
@@ -1820,7 +2119,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
1820 * 2) # times calling this function 2119 * 2) # times calling this function
1821 * 3) elapsed time in this mode (not used, for now) 2120 * 3) elapsed time in this mode (not used, for now)
1822 */ 2121 */
1823static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) 2122static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1824{ 2123{
1825 struct iwl_scale_tbl_info *tbl; 2124 struct iwl_scale_tbl_info *tbl;
1826 int i; 2125 int i;
@@ -1851,7 +2150,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
1851 * allow a new search. Also (below) reset all bitmaps and 2150 * allow a new search. Also (below) reset all bitmaps and
1852 * stats in active history. 2151 * stats in active history.
1853 */ 2152 */
1854 if ((lq_sta->total_failed > lq_sta->max_failure_limit) || 2153 if (force_search ||
2154 (lq_sta->total_failed > lq_sta->max_failure_limit) ||
1855 (lq_sta->total_success > lq_sta->max_success_limit) || 2155 (lq_sta->total_success > lq_sta->max_success_limit) ||
1856 ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer) 2156 ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer)
1857 && (flush_interval_passed))) { 2157 && (flush_interval_passed))) {
@@ -1899,19 +2199,18 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
1899 * setup rate table in uCode 2199 * setup rate table in uCode
1900 * return rate_n_flags as used in the table 2200 * return rate_n_flags as used in the table
1901 */ 2201 */
1902static u32 rs_update_rate_tbl(struct iwl_priv *priv, 2202static void rs_update_rate_tbl(struct iwl_priv *priv,
1903 struct iwl_lq_sta *lq_sta, 2203 struct iwl_rxon_context *ctx,
1904 struct iwl_scale_tbl_info *tbl, 2204 struct iwl_lq_sta *lq_sta,
1905 int index, u8 is_green) 2205 struct iwl_scale_tbl_info *tbl,
2206 int index, u8 is_green)
1906{ 2207{
1907 u32 rate; 2208 u32 rate;
1908 2209
1909 /* Update uCode's rate table. */ 2210 /* Update uCode's rate table. */
1910 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); 2211 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
1911 rs_fill_link_cmd(priv, lq_sta, rate); 2212 rs_fill_link_cmd(priv, lq_sta, rate);
1912 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false); 2213 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
1913
1914 return rate;
1915} 2214}
1916 2215
1917/* 2216/*
@@ -1940,7 +2239,6 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1940 u8 update_lq = 0; 2239 u8 update_lq = 0;
1941 struct iwl_scale_tbl_info *tbl, *tbl1; 2240 struct iwl_scale_tbl_info *tbl, *tbl1;
1942 u16 rate_scale_index_msk = 0; 2241 u16 rate_scale_index_msk = 0;
1943 u32 rate;
1944 u8 is_green = 0; 2242 u8 is_green = 0;
1945 u8 active_tbl = 0; 2243 u8 active_tbl = 0;
1946 u8 done_search = 0; 2244 u8 done_search = 0;
@@ -1948,6 +2246,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1948 s32 sr; 2246 s32 sr;
1949 u8 tid = MAX_TID_COUNT; 2247 u8 tid = MAX_TID_COUNT;
1950 struct iwl_tid_data *tid_data; 2248 struct iwl_tid_data *tid_data;
2249 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
2250 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
1951 2251
1952 IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n"); 2252 IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
1953 2253
@@ -1986,7 +2286,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1986 if (is_legacy(tbl->lq_type)) 2286 if (is_legacy(tbl->lq_type))
1987 lq_sta->is_green = 0; 2287 lq_sta->is_green = 0;
1988 else 2288 else
1989 lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config); 2289 lq_sta->is_green = rs_use_green(sta);
1990 is_green = lq_sta->is_green; 2290 is_green = lq_sta->is_green;
1991 2291
1992 /* current tx rate */ 2292 /* current tx rate */
@@ -2025,8 +2325,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2025 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 2325 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2026 /* get "active" rate info */ 2326 /* get "active" rate info */
2027 index = iwl_hwrate_to_plcp_idx(tbl->current_rate); 2327 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
2028 rate = rs_update_rate_tbl(priv, lq_sta, 2328 rs_update_rate_tbl(priv, ctx, lq_sta, tbl,
2029 tbl, index, is_green); 2329 index, is_green);
2030 } 2330 }
2031 return; 2331 return;
2032 } 2332 }
@@ -2067,7 +2367,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2067 2367
2068 /* Should we stay with this modulation mode, 2368 /* Should we stay with this modulation mode,
2069 * or search for a new one? */ 2369 * or search for a new one? */
2070 rs_stay_in_table(lq_sta); 2370 rs_stay_in_table(lq_sta, false);
2071 2371
2072 goto out; 2372 goto out;
2073 } 2373 }
@@ -2215,6 +2515,28 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2215 if (iwl_tx_ant_restriction(priv) != IWL_ANT_OK_MULTI && 2515 if (iwl_tx_ant_restriction(priv) != IWL_ANT_OK_MULTI &&
2216 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) 2516 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type)))
2217 scale_action = -1; 2517 scale_action = -1;
2518
2519 if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
2520 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
2521 if (lq_sta->last_bt_traffic > priv->bt_traffic_load) {
2522 /*
2523 * don't set scale_action, don't want to scale up if
2524 * the rate scale doesn't otherwise think that is a
2525 * good idea.
2526 */
2527 } else if (lq_sta->last_bt_traffic <= priv->bt_traffic_load) {
2528 scale_action = -1;
2529 }
2530 }
2531 lq_sta->last_bt_traffic = priv->bt_traffic_load;
2532
2533 if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) &&
2534 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) {
2535 /* search for a new modulation */
2536 rs_stay_in_table(lq_sta, true);
2537 goto lq_update;
2538 }
2539
2218 switch (scale_action) { 2540 switch (scale_action) {
2219 case -1: 2541 case -1:
2220 /* Decrease starting rate, update uCode's rate table */ 2542 /* Decrease starting rate, update uCode's rate table */
@@ -2245,13 +2567,12 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2245lq_update: 2567lq_update:
2246 /* Replace uCode's rate table for the destination station. */ 2568 /* Replace uCode's rate table for the destination station. */
2247 if (update_lq) 2569 if (update_lq)
2248 rate = rs_update_rate_tbl(priv, lq_sta, 2570 rs_update_rate_tbl(priv, ctx, lq_sta, tbl, index, is_green);
2249 tbl, index, is_green);
2250 2571
2251 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) { 2572 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) {
2252 /* Should we stay with this modulation mode, 2573 /* Should we stay with this modulation mode,
2253 * or search for a new one? */ 2574 * or search for a new one? */
2254 rs_stay_in_table(lq_sta); 2575 rs_stay_in_table(lq_sta, false);
2255 } 2576 }
2256 /* 2577 /*
2257 * Search for new modulation mode if we're: 2578 * Search for new modulation mode if we're:
@@ -2287,7 +2608,7 @@ lq_update:
2287 IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n", 2608 IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n",
2288 tbl->current_rate, index); 2609 tbl->current_rate, index);
2289 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate); 2610 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
2290 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false); 2611 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
2291 } else 2612 } else
2292 done_search = 1; 2613 done_search = 1;
2293 } 2614 }
@@ -2357,12 +2678,17 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2357 int rate_idx; 2678 int rate_idx;
2358 int i; 2679 int i;
2359 u32 rate; 2680 u32 rate;
2360 u8 use_green = rs_use_green(sta, &priv->current_ht_config); 2681 u8 use_green = rs_use_green(sta);
2361 u8 active_tbl = 0; 2682 u8 active_tbl = 0;
2362 u8 valid_tx_ant; 2683 u8 valid_tx_ant;
2684 struct iwl_station_priv *sta_priv;
2685 struct iwl_rxon_context *ctx;
2363 2686
2364 if (!sta || !lq_sta) 2687 if (!sta || !lq_sta)
2365 goto out; 2688 return;
2689
2690 sta_priv = (void *)sta->drv_priv;
2691 ctx = sta_priv->common.ctx;
2366 2692
2367 i = lq_sta->last_txrate_idx; 2693 i = lq_sta->last_txrate_idx;
2368 2694
@@ -2394,9 +2720,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2394 rs_set_expected_tpt_table(lq_sta, tbl); 2720 rs_set_expected_tpt_table(lq_sta, tbl);
2395 rs_fill_link_cmd(NULL, lq_sta, rate); 2721 rs_fill_link_cmd(NULL, lq_sta, rate);
2396 priv->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq; 2722 priv->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq;
2397 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_SYNC, true); 2723 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_SYNC, true);
2398 out:
2399 return;
2400} 2724}
2401 2725
2402static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, 2726static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
@@ -2472,16 +2796,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2472static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, 2796static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
2473 gfp_t gfp) 2797 gfp_t gfp)
2474{ 2798{
2475 struct iwl_lq_sta *lq_sta;
2476 struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv; 2799 struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv;
2477 struct iwl_priv *priv; 2800 struct iwl_priv *priv;
2478 2801
2479 priv = (struct iwl_priv *)priv_rate; 2802 priv = (struct iwl_priv *)priv_rate;
2480 IWL_DEBUG_RATE(priv, "create station rate scale window\n"); 2803 IWL_DEBUG_RATE(priv, "create station rate scale window\n");
2481 2804
2482 lq_sta = &sta_priv->lq_sta; 2805 return &sta_priv->lq_sta;
2483
2484 return lq_sta;
2485} 2806}
2486 2807
2487/* 2808/*
@@ -2524,7 +2845,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
2524 lq_sta->is_dup = 0; 2845 lq_sta->is_dup = 0;
2525 lq_sta->max_rate_idx = -1; 2846 lq_sta->max_rate_idx = -1;
2526 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; 2847 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
2527 lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config); 2848 lq_sta->is_green = rs_use_green(sta);
2528 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); 2849 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
2529 lq_sta->band = priv->band; 2850 lq_sta->band = priv->band;
2530 /* 2851 /*
@@ -2575,6 +2896,11 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
2575 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; 2896 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
2576 lq_sta->is_agg = 0; 2897 lq_sta->is_agg = 0;
2577 2898
2899 priv->dbg_fixed_rate = 0;
2900#ifdef CONFIG_MAC80211_DEBUGFS
2901 lq_sta->dbg_fixed_rate = 0;
2902#endif
2903
2578 rs_initialize_lq(priv, conf, sta, lq_sta); 2904 rs_initialize_lq(priv, conf, sta, lq_sta);
2579} 2905}
2580 2906
@@ -2588,22 +2914,30 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2588 u8 ant_toggle_cnt = 0; 2914 u8 ant_toggle_cnt = 0;
2589 u8 use_ht_possible = 1; 2915 u8 use_ht_possible = 1;
2590 u8 valid_tx_ant = 0; 2916 u8 valid_tx_ant = 0;
2917 struct iwl_station_priv *sta_priv =
2918 container_of(lq_sta, struct iwl_station_priv, lq_sta);
2591 struct iwl_link_quality_cmd *lq_cmd = &lq_sta->lq; 2919 struct iwl_link_quality_cmd *lq_cmd = &lq_sta->lq;
2592 2920
2593 /* Override starting rate (index 0) if needed for debug purposes */ 2921 /* Override starting rate (index 0) if needed for debug purposes */
2594 rs_dbgfs_set_mcs(lq_sta, &new_rate, index); 2922 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
2595 2923
2596 /* Interpret new_rate (rate_n_flags) */ 2924 /* Interpret new_rate (rate_n_flags) */
2597 memset(&tbl_type, 0, sizeof(tbl_type));
2598 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, 2925 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
2599 &tbl_type, &rate_idx); 2926 &tbl_type, &rate_idx);
2600 2927
2928 if (priv && priv->bt_full_concurrent) {
2929 /* 1x1 only */
2930 tbl_type.ant_type =
2931 first_antenna(priv->hw_params.valid_tx_ant);
2932 }
2933
2601 /* How many times should we repeat the initial rate? */ 2934 /* How many times should we repeat the initial rate? */
2602 if (is_legacy(tbl_type.lq_type)) { 2935 if (is_legacy(tbl_type.lq_type)) {
2603 ant_toggle_cnt = 1; 2936 ant_toggle_cnt = 1;
2604 repeat_rate = IWL_NUMBER_TRY; 2937 repeat_rate = IWL_NUMBER_TRY;
2605 } else { 2938 } else {
2606 repeat_rate = IWL_HT_NUMBER_TRY; 2939 repeat_rate = min(IWL_HT_NUMBER_TRY,
2940 LINK_QUAL_AGG_DISABLE_START_DEF - 1);
2607 } 2941 }
2608 2942
2609 lq_cmd->general_params.mimo_delimiter = 2943 lq_cmd->general_params.mimo_delimiter =
@@ -2622,9 +2956,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2622 2956
2623 index++; 2957 index++;
2624 repeat_rate--; 2958 repeat_rate--;
2625 2959 if (priv) {
2626 if (priv) 2960 if (priv->bt_full_concurrent)
2627 valid_tx_ant = priv->hw_params.valid_tx_ant; 2961 valid_tx_ant = ANT_A;
2962 else
2963 valid_tx_ant = priv->hw_params.valid_tx_ant;
2964 }
2628 2965
2629 /* Fill rest of rate table */ 2966 /* Fill rest of rate table */
2630 while (index < LINK_QUAL_MAX_RETRY_NUM) { 2967 while (index < LINK_QUAL_MAX_RETRY_NUM) {
@@ -2639,7 +2976,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2639 rs_toggle_antenna(valid_tx_ant, 2976 rs_toggle_antenna(valid_tx_ant,
2640 &new_rate, &tbl_type)) 2977 &new_rate, &tbl_type))
2641 ant_toggle_cnt = 1; 2978 ant_toggle_cnt = 1;
2642} 2979 }
2643 2980
2644 /* Override next rate if needed for debug purposes */ 2981 /* Override next rate if needed for debug purposes */
2645 rs_dbgfs_set_mcs(lq_sta, &new_rate, index); 2982 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
@@ -2654,6 +2991,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2654 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, 2991 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type,
2655 &rate_idx); 2992 &rate_idx);
2656 2993
2994 if (priv && priv->bt_full_concurrent) {
2995 /* 1x1 only */
2996 tbl_type.ant_type =
2997 first_antenna(priv->hw_params.valid_tx_ant);
2998 }
2999
2657 /* Indicate to uCode which entries might be MIMO. 3000 /* Indicate to uCode which entries might be MIMO.
2658 * If initial rate was MIMO, this will finally end up 3001 * If initial rate was MIMO, this will finally end up
2659 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */ 3002 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
@@ -2692,10 +3035,21 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
2692 repeat_rate--; 3035 repeat_rate--;
2693 } 3036 }
2694 3037
2695 lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; 3038 lq_cmd->agg_params.agg_frame_cnt_limit =
3039 sta_priv->max_agg_bufsize ?: LINK_QUAL_AGG_FRAME_LIMIT_DEF;
2696 lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; 3040 lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
3041
2697 lq_cmd->agg_params.agg_time_limit = 3042 lq_cmd->agg_params.agg_time_limit =
2698 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); 3043 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
3044 /*
3045 * overwrite if needed, pass aggregation time limit
3046 * to uCode in uSec
3047 */
3048 if (priv && priv->cfg->bt_params &&
3049 priv->cfg->bt_params->agg_time_limit &&
3050 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
3051 lq_cmd->agg_params.agg_time_limit =
3052 cpu_to_le16(priv->cfg->bt_params->agg_time_limit);
2699} 3053}
2700 3054
2701static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 3055static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -2717,7 +3071,6 @@ static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
2717 IWL_DEBUG_RATE(priv, "leave\n"); 3071 IWL_DEBUG_RATE(priv, "leave\n");
2718} 3072}
2719 3073
2720
2721#ifdef CONFIG_MAC80211_DEBUGFS 3074#ifdef CONFIG_MAC80211_DEBUGFS
2722static int open_file_generic(struct inode *inode, struct file *file) 3075static int open_file_generic(struct inode *inode, struct file *file)
2723{ 3076{
@@ -2742,6 +3095,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
2742 IWL_DEBUG_RATE(priv, "Fixed rate ON\n"); 3095 IWL_DEBUG_RATE(priv, "Fixed rate ON\n");
2743 } else { 3096 } else {
2744 lq_sta->dbg_fixed_rate = 0; 3097 lq_sta->dbg_fixed_rate = 0;
3098 priv->dbg_fixed_rate = 0;
2745 IWL_ERR(priv, 3099 IWL_ERR(priv,
2746 "Invalid antenna selection 0x%X, Valid is 0x%X\n", 3100 "Invalid antenna selection 0x%X, Valid is 0x%X\n",
2747 ant_sel_tx, valid_tx_ant); 3101 ant_sel_tx, valid_tx_ant);
@@ -2758,9 +3112,10 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2758 struct iwl_lq_sta *lq_sta = file->private_data; 3112 struct iwl_lq_sta *lq_sta = file->private_data;
2759 struct iwl_priv *priv; 3113 struct iwl_priv *priv;
2760 char buf[64]; 3114 char buf[64];
2761 int buf_size; 3115 size_t buf_size;
2762 u32 parsed_rate; 3116 u32 parsed_rate;
2763 3117
3118
2764 priv = lq_sta->drv; 3119 priv = lq_sta->drv;
2765 memset(buf, 0, sizeof(buf)); 3120 memset(buf, 0, sizeof(buf));
2766 buf_size = min(count, sizeof(buf) - 1); 3121 buf_size = min(count, sizeof(buf) - 1);
@@ -2768,22 +3123,11 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2768 return -EFAULT; 3123 return -EFAULT;
2769 3124
2770 if (sscanf(buf, "%x", &parsed_rate) == 1) 3125 if (sscanf(buf, "%x", &parsed_rate) == 1)
2771 lq_sta->dbg_fixed_rate = parsed_rate; 3126 priv->dbg_fixed_rate = lq_sta->dbg_fixed_rate = parsed_rate;
2772 else 3127 else
2773 lq_sta->dbg_fixed_rate = 0; 3128 priv->dbg_fixed_rate = lq_sta->dbg_fixed_rate = 0;
2774 3129
2775 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ 3130 rs_program_fix_rate(priv, lq_sta);
2776 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2777 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2778 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2779
2780 IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
2781 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
2782
2783 if (lq_sta->dbg_fixed_rate) {
2784 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
2785 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
2786 }
2787 3131
2788 return count; 3132 return count;
2789} 3133}
@@ -2811,7 +3155,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2811 lq_sta->total_failed, lq_sta->total_success, 3155 lq_sta->total_failed, lq_sta->total_success,
2812 lq_sta->active_legacy_rate); 3156 lq_sta->active_legacy_rate);
2813 desc += sprintf(buff+desc, "fixed rate 0x%X\n", 3157 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
2814 lq_sta->dbg_fixed_rate); 3158 priv->dbg_fixed_rate);
2815 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", 3159 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
2816 (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "", 3160 (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "",
2817 (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "", 3161 (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "",
@@ -2873,6 +3217,7 @@ static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
2873 .write = rs_sta_dbgfs_scale_table_write, 3217 .write = rs_sta_dbgfs_scale_table_write,
2874 .read = rs_sta_dbgfs_scale_table_read, 3218 .read = rs_sta_dbgfs_scale_table_read,
2875 .open = open_file_generic, 3219 .open = open_file_generic,
3220 .llseek = default_llseek,
2876}; 3221};
2877static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file, 3222static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2878 char __user *user_buf, size_t count, loff_t *ppos) 3223 char __user *user_buf, size_t count, loff_t *ppos)
@@ -2915,20 +3260,16 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2915static const struct file_operations rs_sta_dbgfs_stats_table_ops = { 3260static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
2916 .read = rs_sta_dbgfs_stats_table_read, 3261 .read = rs_sta_dbgfs_stats_table_read,
2917 .open = open_file_generic, 3262 .open = open_file_generic,
3263 .llseek = default_llseek,
2918}; 3264};
2919 3265
2920static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file, 3266static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
2921 char __user *user_buf, size_t count, loff_t *ppos) 3267 char __user *user_buf, size_t count, loff_t *ppos)
2922{ 3268{
2923 char buff[120];
2924 int desc = 0;
2925 ssize_t ret;
2926
2927 struct iwl_lq_sta *lq_sta = file->private_data; 3269 struct iwl_lq_sta *lq_sta = file->private_data;
2928 struct iwl_priv *priv;
2929 struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl]; 3270 struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl];
2930 3271 char buff[120];
2931 priv = lq_sta->drv; 3272 int desc = 0;
2932 3273
2933 if (is_Ht(tbl->lq_type)) 3274 if (is_Ht(tbl->lq_type))
2934 desc += sprintf(buff+desc, 3275 desc += sprintf(buff+desc,
@@ -2939,13 +3280,13 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
2939 "Bit Rate= %d Mb/s\n", 3280 "Bit Rate= %d Mb/s\n",
2940 iwl_rates[lq_sta->last_txrate_idx].ieee >> 1); 3281 iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
2941 3282
2942 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); 3283 return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
2943 return ret;
2944} 3284}
2945 3285
2946static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = { 3286static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
2947 .read = rs_sta_dbgfs_rate_scale_data_read, 3287 .read = rs_sta_dbgfs_rate_scale_data_read,
2948 .open = open_file_generic, 3288 .open = open_file_generic,
3289 .llseek = default_llseek,
2949}; 3290};
2950 3291
2951static void rs_add_debugfs(void *priv, void *priv_sta, 3292static void rs_add_debugfs(void *priv, void *priv_sta,