aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex.c18
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c261
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h14
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sf.c3
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c2
7 files changed, 195 insertions, 109 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 003a546571d4..4c2d4ef28b22 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -67,8 +67,8 @@
67#include "iwl-agn-hw.h" 67#include "iwl-agn-hw.h"
68 68
69/* Highest firmware API version supported */ 69/* Highest firmware API version supported */
70#define IWL7260_UCODE_API_MAX 8 70#define IWL7260_UCODE_API_MAX 9
71#define IWL3160_UCODE_API_MAX 8 71#define IWL3160_UCODE_API_MAX 9
72 72
73/* Oldest version we won't warn about */ 73/* Oldest version we won't warn about */
74#define IWL7260_UCODE_API_OK 8 74#define IWL7260_UCODE_API_OK 8
@@ -244,3 +244,4 @@ const struct iwl_cfg iwl7265_n_cfg = {
244 244
245MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); 245MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
246MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); 246MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
247MODULE_FIRMWARE(IWL7265_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c
index 685f7e8e6943..fa858d548d13 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex.c
@@ -190,7 +190,7 @@ static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = {
190 cpu_to_le32(0xcc00aaaa), 190 cpu_to_le32(0xcc00aaaa),
191 cpu_to_le32(0x0000aaaa), 191 cpu_to_le32(0x0000aaaa),
192 cpu_to_le32(0xc0004000), 192 cpu_to_le32(0xc0004000),
193 cpu_to_le32(0x00000000), 193 cpu_to_le32(0x00004000),
194 cpu_to_le32(0xf0005000), 194 cpu_to_le32(0xf0005000),
195 cpu_to_le32(0xf0005000), 195 cpu_to_le32(0xf0005000),
196 }, 196 },
@@ -213,16 +213,16 @@ static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = {
213 /* Tx Tx disabled */ 213 /* Tx Tx disabled */
214 cpu_to_le32(0xaaaaaaaa), 214 cpu_to_le32(0xaaaaaaaa),
215 cpu_to_le32(0xaaaaaaaa), 215 cpu_to_le32(0xaaaaaaaa),
216 cpu_to_le32(0xaaaaaaaa), 216 cpu_to_le32(0xeeaaaaaa),
217 cpu_to_le32(0xaaaaaaaa), 217 cpu_to_le32(0xaaaaaaaa),
218 cpu_to_le32(0xcc00ff28), 218 cpu_to_le32(0xcc00ff28),
219 cpu_to_le32(0x0000aaaa), 219 cpu_to_le32(0x0000aaaa),
220 cpu_to_le32(0xcc00aaaa), 220 cpu_to_le32(0xcc00aaaa),
221 cpu_to_le32(0x0000aaaa), 221 cpu_to_le32(0x0000aaaa),
222 cpu_to_le32(0xC0004000), 222 cpu_to_le32(0xc0004000),
223 cpu_to_le32(0xC0004000), 223 cpu_to_le32(0xc0004000),
224 cpu_to_le32(0xF0005000), 224 cpu_to_le32(0xf0005000),
225 cpu_to_le32(0xF0005000), 225 cpu_to_le32(0xf0005000),
226 }, 226 },
227}; 227};
228 228
@@ -1262,6 +1262,7 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
1262 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1262 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1263 u32 ant_isolation = le32_to_cpup((void *)pkt->data); 1263 u32 ant_isolation = le32_to_cpup((void *)pkt->data);
1264 u8 __maybe_unused lower_bound, upper_bound; 1264 u8 __maybe_unused lower_bound, upper_bound;
1265 int ret;
1265 u8 lut; 1266 u8 lut;
1266 1267
1267 struct iwl_bt_coex_cmd *bt_cmd; 1268 struct iwl_bt_coex_cmd *bt_cmd;
@@ -1318,5 +1319,8 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
1318 memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[lut].lut20, 1319 memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[lut].lut20,
1319 sizeof(bt_cmd->bt4_corun_lut40)); 1320 sizeof(bt_cmd->bt4_corun_lut40));
1320 1321
1321 return 0; 1322 ret = iwl_mvm_send_cmd(mvm, &cmd);
1323
1324 kfree(bt_cmd);
1325 return ret;
1322} 1326}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 4dd9ff43b8b6..f0cebf12c7b8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -1332,6 +1332,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1332 */ 1332 */
1333 iwl_mvm_remove_time_event(mvm, mvmvif, 1333 iwl_mvm_remove_time_event(mvm, mvmvif,
1334 &mvmvif->time_event_data); 1334 &mvmvif->time_event_data);
1335 iwl_mvm_sf_update(mvm, vif, false);
1335 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, CMD_SYNC)); 1336 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, CMD_SYNC));
1336 } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS | 1337 } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS |
1337 BSS_CHANGED_QOS)) { 1338 BSS_CHANGED_QOS)) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 568abd61b14f..9f52c5b3f0ec 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -59,7 +59,7 @@
59/* max allowed rate miss before sync LQ cmd */ 59/* max allowed rate miss before sync LQ cmd */
60#define IWL_MISSED_RATE_MAX 15 60#define IWL_MISSED_RATE_MAX 15
61#define RS_STAY_IN_COLUMN_TIMEOUT (5*HZ) 61#define RS_STAY_IN_COLUMN_TIMEOUT (5*HZ)
62 62#define RS_IDLE_TIMEOUT (5*HZ)
63 63
64static u8 rs_ht_to_legacy[] = { 64static u8 rs_ht_to_legacy[] = {
65 [IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX, 65 [IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX,
@@ -142,7 +142,7 @@ enum rs_column_mode {
142 RS_MIMO2, 142 RS_MIMO2,
143}; 143};
144 144
145#define MAX_NEXT_COLUMNS 5 145#define MAX_NEXT_COLUMNS 7
146#define MAX_COLUMN_CHECKS 3 146#define MAX_COLUMN_CHECKS 3
147 147
148typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm, 148typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm,
@@ -212,8 +212,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
212 RS_COLUMN_LEGACY_ANT_B, 212 RS_COLUMN_LEGACY_ANT_B,
213 RS_COLUMN_SISO_ANT_A, 213 RS_COLUMN_SISO_ANT_A,
214 RS_COLUMN_SISO_ANT_B, 214 RS_COLUMN_SISO_ANT_B,
215 RS_COLUMN_MIMO2, 215 RS_COLUMN_INVALID,
216 RS_COLUMN_MIMO2_SGI, 216 RS_COLUMN_INVALID,
217 RS_COLUMN_INVALID,
218 RS_COLUMN_INVALID,
217 }, 219 },
218 }, 220 },
219 [RS_COLUMN_LEGACY_ANT_B] = { 221 [RS_COLUMN_LEGACY_ANT_B] = {
@@ -223,8 +225,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
223 RS_COLUMN_LEGACY_ANT_A, 225 RS_COLUMN_LEGACY_ANT_A,
224 RS_COLUMN_SISO_ANT_A, 226 RS_COLUMN_SISO_ANT_A,
225 RS_COLUMN_SISO_ANT_B, 227 RS_COLUMN_SISO_ANT_B,
226 RS_COLUMN_MIMO2, 228 RS_COLUMN_INVALID,
227 RS_COLUMN_MIMO2_SGI, 229 RS_COLUMN_INVALID,
230 RS_COLUMN_INVALID,
231 RS_COLUMN_INVALID,
228 }, 232 },
229 }, 233 },
230 [RS_COLUMN_SISO_ANT_A] = { 234 [RS_COLUMN_SISO_ANT_A] = {
@@ -235,7 +239,9 @@ static const struct rs_tx_column rs_tx_columns[] = {
235 RS_COLUMN_MIMO2, 239 RS_COLUMN_MIMO2,
236 RS_COLUMN_SISO_ANT_A_SGI, 240 RS_COLUMN_SISO_ANT_A_SGI,
237 RS_COLUMN_SISO_ANT_B_SGI, 241 RS_COLUMN_SISO_ANT_B_SGI,
238 RS_COLUMN_MIMO2_SGI, 242 RS_COLUMN_LEGACY_ANT_A,
243 RS_COLUMN_LEGACY_ANT_B,
244 RS_COLUMN_INVALID,
239 }, 245 },
240 .checks = { 246 .checks = {
241 rs_siso_allow, 247 rs_siso_allow,
@@ -249,7 +255,9 @@ static const struct rs_tx_column rs_tx_columns[] = {
249 RS_COLUMN_MIMO2, 255 RS_COLUMN_MIMO2,
250 RS_COLUMN_SISO_ANT_B_SGI, 256 RS_COLUMN_SISO_ANT_B_SGI,
251 RS_COLUMN_SISO_ANT_A_SGI, 257 RS_COLUMN_SISO_ANT_A_SGI,
252 RS_COLUMN_MIMO2_SGI, 258 RS_COLUMN_LEGACY_ANT_A,
259 RS_COLUMN_LEGACY_ANT_B,
260 RS_COLUMN_INVALID,
253 }, 261 },
254 .checks = { 262 .checks = {
255 rs_siso_allow, 263 rs_siso_allow,
@@ -265,6 +273,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
265 RS_COLUMN_SISO_ANT_A, 273 RS_COLUMN_SISO_ANT_A,
266 RS_COLUMN_SISO_ANT_B, 274 RS_COLUMN_SISO_ANT_B,
267 RS_COLUMN_MIMO2, 275 RS_COLUMN_MIMO2,
276 RS_COLUMN_LEGACY_ANT_A,
277 RS_COLUMN_LEGACY_ANT_B,
268 }, 278 },
269 .checks = { 279 .checks = {
270 rs_siso_allow, 280 rs_siso_allow,
@@ -281,6 +291,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
281 RS_COLUMN_SISO_ANT_B, 291 RS_COLUMN_SISO_ANT_B,
282 RS_COLUMN_SISO_ANT_A, 292 RS_COLUMN_SISO_ANT_A,
283 RS_COLUMN_MIMO2, 293 RS_COLUMN_MIMO2,
294 RS_COLUMN_LEGACY_ANT_A,
295 RS_COLUMN_LEGACY_ANT_B,
284 }, 296 },
285 .checks = { 297 .checks = {
286 rs_siso_allow, 298 rs_siso_allow,
@@ -296,6 +308,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
296 RS_COLUMN_SISO_ANT_A_SGI, 308 RS_COLUMN_SISO_ANT_A_SGI,
297 RS_COLUMN_SISO_ANT_B_SGI, 309 RS_COLUMN_SISO_ANT_B_SGI,
298 RS_COLUMN_MIMO2_SGI, 310 RS_COLUMN_MIMO2_SGI,
311 RS_COLUMN_LEGACY_ANT_A,
312 RS_COLUMN_LEGACY_ANT_B,
299 }, 313 },
300 .checks = { 314 .checks = {
301 rs_mimo_allow, 315 rs_mimo_allow,
@@ -311,6 +325,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
311 RS_COLUMN_SISO_ANT_A, 325 RS_COLUMN_SISO_ANT_A,
312 RS_COLUMN_SISO_ANT_B, 326 RS_COLUMN_SISO_ANT_B,
313 RS_COLUMN_MIMO2, 327 RS_COLUMN_MIMO2,
328 RS_COLUMN_LEGACY_ANT_A,
329 RS_COLUMN_LEGACY_ANT_B,
314 }, 330 },
315 .checks = { 331 .checks = {
316 rs_mimo_allow, 332 rs_mimo_allow,
@@ -503,10 +519,12 @@ static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
503 window->average_tpt = IWL_INVALID_VALUE; 519 window->average_tpt = IWL_INVALID_VALUE;
504} 520}
505 521
506static void rs_rate_scale_clear_tbl_windows(struct iwl_scale_tbl_info *tbl) 522static void rs_rate_scale_clear_tbl_windows(struct iwl_mvm *mvm,
523 struct iwl_scale_tbl_info *tbl)
507{ 524{
508 int i; 525 int i;
509 526
527 IWL_DEBUG_RATE(mvm, "Clearing up window stats\n");
510 for (i = 0; i < IWL_RATE_COUNT; i++) 528 for (i = 0; i < IWL_RATE_COUNT; i++)
511 rs_rate_scale_clear_window(&tbl->win[i]); 529 rs_rate_scale_clear_window(&tbl->win[i]);
512} 530}
@@ -992,6 +1010,13 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
992 return; 1010 return;
993 } 1011 }
994 1012
1013#ifdef CPTCFG_MAC80211_DEBUGFS
1014 /* Disable last tx check if we are debugging with fixed rate */
1015 if (lq_sta->dbg_fixed_rate) {
1016 IWL_DEBUG_RATE(mvm, "Fixed rate. avoid rate scaling\n");
1017 return;
1018 }
1019#endif
995 if (!ieee80211_is_data(hdr->frame_control) || 1020 if (!ieee80211_is_data(hdr->frame_control) ||
996 info->flags & IEEE80211_TX_CTL_NO_ACK) 1021 info->flags & IEEE80211_TX_CTL_NO_ACK)
997 return; 1022 return;
@@ -1034,6 +1059,18 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
1034 mac_index++; 1059 mac_index++;
1035 } 1060 }
1036 1061
1062 if (time_after(jiffies,
1063 (unsigned long)(lq_sta->last_tx + RS_IDLE_TIMEOUT))) {
1064 int tid;
1065 IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
1066 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
1067 ieee80211_stop_tx_ba_session(sta, tid);
1068
1069 iwl_mvm_rs_rate_init(mvm, sta, sband->band, false);
1070 return;
1071 }
1072 lq_sta->last_tx = jiffies;
1073
1037 /* Here we actually compare this rate to the latest LQ command */ 1074 /* Here we actually compare this rate to the latest LQ command */
1038 if ((mac_index < 0) || 1075 if ((mac_index < 0) ||
1039 (rate.sgi != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) || 1076 (rate.sgi != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
@@ -1186,9 +1223,26 @@ static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
1186 lq_sta->visited_columns = 0; 1223 lq_sta->visited_columns = 0;
1187} 1224}
1188 1225
1226static int rs_get_max_allowed_rate(struct iwl_lq_sta *lq_sta,
1227 const struct rs_tx_column *column)
1228{
1229 switch (column->mode) {
1230 case RS_LEGACY:
1231 return lq_sta->max_legacy_rate_idx;
1232 case RS_SISO:
1233 return lq_sta->max_siso_rate_idx;
1234 case RS_MIMO2:
1235 return lq_sta->max_mimo2_rate_idx;
1236 default:
1237 WARN_ON_ONCE(1);
1238 }
1239
1240 return lq_sta->max_legacy_rate_idx;
1241}
1242
1189static const u16 *rs_get_expected_tpt_table(struct iwl_lq_sta *lq_sta, 1243static const u16 *rs_get_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1190 const struct rs_tx_column *column, 1244 const struct rs_tx_column *column,
1191 u32 bw) 1245 u32 bw)
1192{ 1246{
1193 /* Used to choose among HT tables */ 1247 /* Used to choose among HT tables */
1194 const u16 (*ht_tbl_pointer)[IWL_RATE_COUNT]; 1248 const u16 (*ht_tbl_pointer)[IWL_RATE_COUNT];
@@ -1438,7 +1492,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1438 1492
1439 IWL_DEBUG_RATE(mvm, 1493 IWL_DEBUG_RATE(mvm,
1440 "LQ: stay in table clear win\n"); 1494 "LQ: stay in table clear win\n");
1441 rs_rate_scale_clear_tbl_windows(tbl); 1495 rs_rate_scale_clear_tbl_windows(mvm, tbl);
1442 } 1496 }
1443 } 1497 }
1444 1498
@@ -1446,8 +1500,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1446 * bitmaps and stats in active table (this will become the new 1500 * bitmaps and stats in active table (this will become the new
1447 * "search" table). */ 1501 * "search" table). */
1448 if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) { 1502 if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) {
1449 IWL_DEBUG_RATE(mvm, "Clearing up window stats\n"); 1503 rs_rate_scale_clear_tbl_windows(mvm, tbl);
1450 rs_rate_scale_clear_tbl_windows(tbl);
1451 } 1504 }
1452 } 1505 }
1453} 1506}
@@ -1485,14 +1538,14 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
1485 struct ieee80211_sta *sta, 1538 struct ieee80211_sta *sta,
1486 struct iwl_scale_tbl_info *tbl) 1539 struct iwl_scale_tbl_info *tbl)
1487{ 1540{
1488 int i, j, n; 1541 int i, j, max_rate;
1489 enum rs_column next_col_id; 1542 enum rs_column next_col_id;
1490 const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column]; 1543 const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column];
1491 const struct rs_tx_column *next_col; 1544 const struct rs_tx_column *next_col;
1492 allow_column_func_t allow_func; 1545 allow_column_func_t allow_func;
1493 u8 valid_ants = mvm->fw->valid_tx_ant; 1546 u8 valid_ants = mvm->fw->valid_tx_ant;
1494 const u16 *expected_tpt_tbl; 1547 const u16 *expected_tpt_tbl;
1495 s32 tpt, max_expected_tpt; 1548 u16 tpt, max_expected_tpt;
1496 1549
1497 for (i = 0; i < MAX_NEXT_COLUMNS; i++) { 1550 for (i = 0; i < MAX_NEXT_COLUMNS; i++) {
1498 next_col_id = curr_col->next_columns[i]; 1551 next_col_id = curr_col->next_columns[i];
@@ -1535,11 +1588,11 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
1535 if (WARN_ON_ONCE(!expected_tpt_tbl)) 1588 if (WARN_ON_ONCE(!expected_tpt_tbl))
1536 continue; 1589 continue;
1537 1590
1538 max_expected_tpt = 0; 1591 max_rate = rs_get_max_allowed_rate(lq_sta, next_col);
1539 for (n = 0; n < IWL_RATE_COUNT; n++) 1592 if (WARN_ON_ONCE(max_rate == IWL_RATE_INVALID))
1540 if (expected_tpt_tbl[n] > max_expected_tpt) 1593 continue;
1541 max_expected_tpt = expected_tpt_tbl[n];
1542 1594
1595 max_expected_tpt = expected_tpt_tbl[max_rate];
1543 if (tpt >= max_expected_tpt) { 1596 if (tpt >= max_expected_tpt) {
1544 IWL_DEBUG_RATE(mvm, 1597 IWL_DEBUG_RATE(mvm,
1545 "Skip column %d: can't beat current TPT. Max expected %d current %d\n", 1598 "Skip column %d: can't beat current TPT. Max expected %d current %d\n",
@@ -1547,14 +1600,15 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
1547 continue; 1600 continue;
1548 } 1601 }
1549 1602
1603 IWL_DEBUG_RATE(mvm,
1604 "Found potential column %d. Max expected %d current %d\n",
1605 next_col_id, max_expected_tpt, tpt);
1550 break; 1606 break;
1551 } 1607 }
1552 1608
1553 if (i == MAX_NEXT_COLUMNS) 1609 if (i == MAX_NEXT_COLUMNS)
1554 return RS_COLUMN_INVALID; 1610 return RS_COLUMN_INVALID;
1555 1611
1556 IWL_DEBUG_RATE(mvm, "Found potential column %d\n", next_col_id);
1557
1558 return next_col_id; 1612 return next_col_id;
1559} 1613}
1560 1614
@@ -1640,85 +1694,76 @@ static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm,
1640{ 1694{
1641 enum rs_action action = RS_ACTION_STAY; 1695 enum rs_action action = RS_ACTION_STAY;
1642 1696
1643 /* Too many failures, decrease rate */
1644 if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) { 1697 if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) {
1645 IWL_DEBUG_RATE(mvm, 1698 IWL_DEBUG_RATE(mvm,
1646 "decrease rate because of low SR\n"); 1699 "Decrease rate because of low SR\n");
1647 action = RS_ACTION_DOWNSCALE; 1700 return RS_ACTION_DOWNSCALE;
1648 /* No throughput measured yet for adjacent rates; try increase. */
1649 } else if ((low_tpt == IWL_INVALID_VALUE) &&
1650 (high_tpt == IWL_INVALID_VALUE)) {
1651 if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) {
1652 IWL_DEBUG_RATE(mvm,
1653 "Good SR and no high rate measurement. "
1654 "Increase rate\n");
1655 action = RS_ACTION_UPSCALE;
1656 } else if (low != IWL_RATE_INVALID) {
1657 IWL_DEBUG_RATE(mvm,
1658 "Remain in current rate\n");
1659 action = RS_ACTION_STAY;
1660 }
1661 } 1701 }
1662 1702
1663 /* Both adjacent throughputs are measured, but neither one has better 1703 if ((low_tpt == IWL_INVALID_VALUE) &&
1664 * throughput; we're using the best rate, don't change it! 1704 (high_tpt == IWL_INVALID_VALUE) &&
1665 */ 1705 (high != IWL_RATE_INVALID)) {
1666 else if ((low_tpt != IWL_INVALID_VALUE) &&
1667 (high_tpt != IWL_INVALID_VALUE) &&
1668 (low_tpt < current_tpt) &&
1669 (high_tpt < current_tpt)) {
1670 IWL_DEBUG_RATE(mvm, 1706 IWL_DEBUG_RATE(mvm,
1671 "Both high and low are worse. " 1707 "No data about high/low rates. Increase rate\n");
1672 "Maintain rate\n"); 1708 return RS_ACTION_UPSCALE;
1673 action = RS_ACTION_STAY;
1674 } 1709 }
1675 1710
1676 /* At least one adjacent rate's throughput is measured, 1711 if ((high_tpt == IWL_INVALID_VALUE) &&
1677 * and may have better performance. 1712 (high != IWL_RATE_INVALID) &&
1678 */ 1713 (low_tpt != IWL_INVALID_VALUE) &&
1679 else { 1714 (low_tpt < current_tpt)) {
1680 /* Higher adjacent rate's throughput is measured */ 1715 IWL_DEBUG_RATE(mvm,
1681 if (high_tpt != IWL_INVALID_VALUE) { 1716 "No data about high rate and low rate is worse. Increase rate\n");
1682 /* Higher rate has better throughput */ 1717 return RS_ACTION_UPSCALE;
1683 if (high_tpt > current_tpt && 1718 }
1684 sr >= IWL_RATE_INCREASE_TH) {
1685 IWL_DEBUG_RATE(mvm,
1686 "Higher rate is better and good "
1687 "SR. Increate rate\n");
1688 action = RS_ACTION_UPSCALE;
1689 } else {
1690 IWL_DEBUG_RATE(mvm,
1691 "Higher rate isn't better OR "
1692 "no good SR. Maintain rate\n");
1693 action = RS_ACTION_STAY;
1694 }
1695 1719
1696 /* Lower adjacent rate's throughput is measured */ 1720 if ((high_tpt != IWL_INVALID_VALUE) &&
1697 } else if (low_tpt != IWL_INVALID_VALUE) { 1721 (high_tpt > current_tpt)) {
1698 /* Lower rate has better throughput */ 1722 IWL_DEBUG_RATE(mvm,
1699 if (low_tpt > current_tpt) { 1723 "Higher rate is better. Increate rate\n");
1700 IWL_DEBUG_RATE(mvm, 1724 return RS_ACTION_UPSCALE;
1701 "Lower rate is better. "
1702 "Decrease rate\n");
1703 action = RS_ACTION_DOWNSCALE;
1704 } else if (sr >= IWL_RATE_INCREASE_TH) {
1705 IWL_DEBUG_RATE(mvm,
1706 "Lower rate isn't better and "
1707 "good SR. Increase rate\n");
1708 action = RS_ACTION_UPSCALE;
1709 }
1710 }
1711 } 1725 }
1712 1726
1713 /* Sanity check; asked for decrease, but success rate or throughput 1727 if ((low_tpt != IWL_INVALID_VALUE) &&
1714 * has been good at old rate. Don't change it. 1728 (high_tpt != IWL_INVALID_VALUE) &&
1715 */ 1729 (low_tpt < current_tpt) &&
1716 if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID) && 1730 (high_tpt < current_tpt)) {
1717 ((sr > IWL_RATE_HIGH_TH) || 1731 IWL_DEBUG_RATE(mvm,
1718 (current_tpt > (100 * tbl->expected_tpt[low])))) { 1732 "Both high and low are worse. Maintain rate\n");
1733 return RS_ACTION_STAY;
1734 }
1735
1736 if ((low_tpt != IWL_INVALID_VALUE) &&
1737 (low_tpt > current_tpt)) {
1738 IWL_DEBUG_RATE(mvm,
1739 "Lower rate is better\n");
1740 action = RS_ACTION_DOWNSCALE;
1741 goto out;
1742 }
1743
1744 if ((low_tpt == IWL_INVALID_VALUE) &&
1745 (low != IWL_RATE_INVALID)) {
1719 IWL_DEBUG_RATE(mvm, 1746 IWL_DEBUG_RATE(mvm,
1720 "Sanity check failed. Maintain rate\n"); 1747 "No data about lower rate\n");
1721 action = RS_ACTION_STAY; 1748 action = RS_ACTION_DOWNSCALE;
1749 goto out;
1750 }
1751
1752 IWL_DEBUG_RATE(mvm, "Maintain rate\n");
1753
1754out:
1755 if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID)) {
1756 if (sr >= RS_SR_NO_DECREASE) {
1757 IWL_DEBUG_RATE(mvm,
1758 "SR is above NO DECREASE. Avoid downscale\n");
1759 action = RS_ACTION_STAY;
1760 } else if (current_tpt > (100 * tbl->expected_tpt[low])) {
1761 IWL_DEBUG_RATE(mvm,
1762 "Current TPT is higher than max expected in low rate. Avoid downscale\n");
1763 action = RS_ACTION_STAY;
1764 } else {
1765 IWL_DEBUG_RATE(mvm, "Decrease rate\n");
1766 }
1722 } 1767 }
1723 1768
1724 return action; 1769 return action;
@@ -1792,6 +1837,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
1792 "Aggregation changed: prev %d current %d. Update expected TPT table\n", 1837 "Aggregation changed: prev %d current %d. Update expected TPT table\n",
1793 prev_agg, lq_sta->is_agg); 1838 prev_agg, lq_sta->is_agg);
1794 rs_set_expected_tpt_table(lq_sta, tbl); 1839 rs_set_expected_tpt_table(lq_sta, tbl);
1840 rs_rate_scale_clear_tbl_windows(mvm, tbl);
1795 } 1841 }
1796 1842
1797 /* current tx rate */ 1843 /* current tx rate */
@@ -2021,7 +2067,7 @@ lq_update:
2021 if (lq_sta->search_better_tbl) { 2067 if (lq_sta->search_better_tbl) {
2022 /* Access the "search" table, clear its history. */ 2068 /* Access the "search" table, clear its history. */
2023 tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); 2069 tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
2024 rs_rate_scale_clear_tbl_windows(tbl); 2070 rs_rate_scale_clear_tbl_windows(mvm, tbl);
2025 2071
2026 /* Use new "search" start rate */ 2072 /* Use new "search" start rate */
2027 index = tbl->rate.index; 2073 index = tbl->rate.index;
@@ -2042,8 +2088,18 @@ lq_update:
2042 * stay with best antenna legacy modulation for a while 2088 * stay with best antenna legacy modulation for a while
2043 * before next round of mode comparisons. */ 2089 * before next round of mode comparisons. */
2044 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); 2090 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
2045 if (is_legacy(&tbl1->rate) && !sta->ht_cap.ht_supported) { 2091 if (is_legacy(&tbl1->rate)) {
2046 IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n"); 2092 IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n");
2093
2094 if (tid != IWL_MAX_TID_COUNT) {
2095 tid_data = &sta_priv->tid_data[tid];
2096 if (tid_data->state != IWL_AGG_OFF) {
2097 IWL_DEBUG_RATE(mvm,
2098 "Stop aggregation on tid %d\n",
2099 tid);
2100 ieee80211_stop_tx_ba_session(sta, tid);
2101 }
2102 }
2047 rs_set_stay_in_table(mvm, 1, lq_sta); 2103 rs_set_stay_in_table(mvm, 1, lq_sta);
2048 } else { 2104 } else {
2049 /* If we're in an HT mode, and all 3 mode switch actions 2105 /* If we're in an HT mode, and all 3 mode switch actions
@@ -2342,9 +2398,10 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2342 lq_sta->lq.sta_id = sta_priv->sta_id; 2398 lq_sta->lq.sta_id = sta_priv->sta_id;
2343 2399
2344 for (j = 0; j < LQ_SIZE; j++) 2400 for (j = 0; j < LQ_SIZE; j++)
2345 rs_rate_scale_clear_tbl_windows(&lq_sta->lq_info[j]); 2401 rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]);
2346 2402
2347 lq_sta->flush_timer = 0; 2403 lq_sta->flush_timer = 0;
2404 lq_sta->last_tx = jiffies;
2348 2405
2349 IWL_DEBUG_RATE(mvm, 2406 IWL_DEBUG_RATE(mvm,
2350 "LQ: *** rate scale station global init for station %d ***\n", 2407 "LQ: *** rate scale station global init for station %d ***\n",
@@ -2388,11 +2445,22 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2388 lq_sta->is_vht = true; 2445 lq_sta->is_vht = true;
2389 } 2446 }
2390 2447
2391 IWL_DEBUG_RATE(mvm, 2448 lq_sta->max_legacy_rate_idx = find_last_bit(&lq_sta->active_legacy_rate,
2392 "SISO-RATE=%X MIMO2-RATE=%X VHT=%d\n", 2449 BITS_PER_LONG);
2450 lq_sta->max_siso_rate_idx = find_last_bit(&lq_sta->active_siso_rate,
2451 BITS_PER_LONG);
2452 lq_sta->max_mimo2_rate_idx = find_last_bit(&lq_sta->active_mimo2_rate,
2453 BITS_PER_LONG);
2454
2455 IWL_DEBUG_RATE(mvm, "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d\n",
2456 lq_sta->active_legacy_rate,
2393 lq_sta->active_siso_rate, 2457 lq_sta->active_siso_rate,
2394 lq_sta->active_mimo2_rate, 2458 lq_sta->active_mimo2_rate,
2395 lq_sta->is_vht); 2459 lq_sta->is_vht);
2460 IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n",
2461 lq_sta->max_legacy_rate_idx,
2462 lq_sta->max_siso_rate_idx,
2463 lq_sta->max_mimo2_rate_idx);
2396 2464
2397 /* These values will be overridden later */ 2465 /* These values will be overridden later */
2398 lq_sta->lq.single_stream_ant_msk = 2466 lq_sta->lq.single_stream_ant_msk =
@@ -2547,6 +2615,7 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
2547 if (is_siso(&rate)) { 2615 if (is_siso(&rate)) {
2548 num_rates = RS_SECONDARY_SISO_NUM_RATES; 2616 num_rates = RS_SECONDARY_SISO_NUM_RATES;
2549 num_retries = RS_SECONDARY_SISO_RETRIES; 2617 num_retries = RS_SECONDARY_SISO_RETRIES;
2618 lq_cmd->mimo_delim = index;
2550 } else if (is_legacy(&rate)) { 2619 } else if (is_legacy(&rate)) {
2551 num_rates = RS_SECONDARY_LEGACY_NUM_RATES; 2620 num_rates = RS_SECONDARY_LEGACY_NUM_RATES;
2552 num_retries = RS_LEGACY_RETRIES_PER_RATE; 2621 num_retries = RS_LEGACY_RETRIES_PER_RATE;
@@ -2749,7 +2818,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2749 return -ENOMEM; 2818 return -ENOMEM;
2750 2819
2751 desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id); 2820 desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
2752 desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n", 2821 desc += sprintf(buff+desc, "failed=%d success=%d rate=0%lX\n",
2753 lq_sta->total_failed, lq_sta->total_success, 2822 lq_sta->total_failed, lq_sta->total_success,
2754 lq_sta->active_legacy_rate); 2823 lq_sta->active_legacy_rate);
2755 desc += sprintf(buff+desc, "fixed rate 0x%X\n", 2824 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 3332b396011e..0acfac96a56c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -156,6 +156,7 @@ enum {
156#define IWL_RATE_HIGH_TH 10880 /* 85% */ 156#define IWL_RATE_HIGH_TH 10880 /* 85% */
157#define IWL_RATE_INCREASE_TH 6400 /* 50% */ 157#define IWL_RATE_INCREASE_TH 6400 /* 50% */
158#define RS_SR_FORCE_DECREASE 1920 /* 15% */ 158#define RS_SR_FORCE_DECREASE 1920 /* 15% */
159#define RS_SR_NO_DECREASE 10880 /* 85% */
159 160
160#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ 161#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
161#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000) 162#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000)
@@ -310,13 +311,20 @@ struct iwl_lq_sta {
310 u32 visited_columns; /* Bitmask marking which Tx columns were 311 u32 visited_columns; /* Bitmask marking which Tx columns were
311 * explored during a search cycle 312 * explored during a search cycle
312 */ 313 */
314 u64 last_tx;
313 bool is_vht; 315 bool is_vht;
314 enum ieee80211_band band; 316 enum ieee80211_band band;
315 317
316 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ 318 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
317 u16 active_legacy_rate; 319 unsigned long active_legacy_rate;
318 u16 active_siso_rate; 320 unsigned long active_siso_rate;
319 u16 active_mimo2_rate; 321 unsigned long active_mimo2_rate;
322
323 /* Highest rate per Tx mode */
324 u8 max_legacy_rate_idx;
325 u8 max_siso_rate_idx;
326 u8 max_mimo2_rate_idx;
327
320 s8 max_rate_idx; /* Max rate set by user */ 328 s8 max_rate_idx; /* Max rate set by user */
321 u8 missed_rate_counter; 329 u8 missed_rate_counter;
322 330
diff --git a/drivers/net/wireless/iwlwifi/mvm/sf.c b/drivers/net/wireless/iwlwifi/mvm/sf.c
index 8401627c0030..88809b2d1654 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sf.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sf.c
@@ -274,7 +274,8 @@ int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *changed_vif,
274 return -EINVAL; 274 return -EINVAL;
275 if (changed_vif->type != NL80211_IFTYPE_STATION) { 275 if (changed_vif->type != NL80211_IFTYPE_STATION) {
276 new_state = SF_UNINIT; 276 new_state = SF_UNINIT;
277 } else if (changed_vif->bss_conf.assoc) { 277 } else if (changed_vif->bss_conf.assoc &&
278 changed_vif->bss_conf.dtim_period) {
278 mvmvif = iwl_mvm_vif_from_mac80211(changed_vif); 279 mvmvif = iwl_mvm_vif_from_mac80211(changed_vif);
279 sta_id = mvmvif->ap_sta_id; 280 sta_id = mvmvif->ap_sta_id;
280 new_state = SF_FULL_ON; 281 new_state = SF_FULL_ON;
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index edb015c99049..3d1d57f9f5bc 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -373,12 +373,14 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
373 {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)}, 373 {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)},
374 {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)}, 374 {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)},
375 {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)}, 375 {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)},
376 {IWL_PCI_DEVICE(0x095A, 0x5102, iwl7265_n_cfg)},
376 {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)}, 377 {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)},
377 {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)}, 378 {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)},
378 {IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)}, 379 {IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)},
379 {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)}, 380 {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)},
380 {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)}, 381 {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)},
381 {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)}, 382 {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},
383 {IWL_PCI_DEVICE(0x095A, 0x9200, iwl7265_2ac_cfg)},
382 {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)}, 384 {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)},
383 {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)}, 385 {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)},
384 {IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)}, 386 {IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)},