diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-rs.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 539 |
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 | */ | ||
101 | const 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 | |||
118 | static inline u8 rs_extract_rate(u32 rate_n_flags) | ||
119 | { | ||
120 | return (u8)(rate_n_flags & RATE_MCS_RATE_MSK); | ||
121 | } | ||
122 | |||
123 | static 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 | |||
79 | static void rs_rate_scale_perform(struct iwl_priv *priv, | 154 | static 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); |
83 | static void rs_fill_link_cmd(struct iwl_priv *priv, | 158 | static 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); |
160 | static 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 | ||
111 | static s32 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = { | 187 | static 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 | ||
118 | static s32 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = { | 194 | static 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 | ||
125 | static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = { | 201 | static 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 | ||
132 | static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = { | 208 | static 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 | ||
139 | static s32 expected_tpt_mimo3_20MHz[4][IWL_RATE_COUNT] = { | 215 | static 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 | ||
172 | static inline u8 rs_extract_rate(u32 rate_n_flags) | ||
173 | { | ||
174 | return (u8)(rate_n_flags & 0xFF); | ||
175 | } | ||
176 | |||
177 | static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) | 248 | static 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 | ||
339 | static 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 | */ |
591 | static inline u8 rs_use_green(struct ieee80211_sta *sta, | 701 | static 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 | ||
859 | static 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 | 1071 | done: | |
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 | */ |
1823 | static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) | 2122 | static 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 | */ |
1902 | static u32 rs_update_rate_tbl(struct iwl_priv *priv, | 2202 | static 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, | |||
2245 | lq_update: | 2567 | lq_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 | ||
2402 | static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, | 2726 | static 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, | |||
2472 | static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, | 2796 | static 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 | ||
2701 | static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | 3055 | static 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 |
2722 | static int open_file_generic(struct inode *inode, struct file *file) | 3075 | static 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 | }; |
2877 | static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file, | 3222 | static 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, | |||
2915 | static const struct file_operations rs_sta_dbgfs_stats_table_ops = { | 3260 | static 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 | ||
2920 | static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file, | 3266 | static 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 | ||
2946 | static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = { | 3286 | static 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 | ||
2951 | static void rs_add_debugfs(void *priv, void *priv_sta, | 3292 | static void rs_add_debugfs(void *priv, void *priv_sta, |