aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/rs.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs.c539
1 files changed, 289 insertions, 250 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index 009e72abcd51..e4415e58fa78 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -1197,239 +1197,6 @@ static u8 rs_get_tid(struct ieee80211_hdr *hdr)
1197 return tid; 1197 return tid;
1198} 1198}
1199 1199
1200void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1201 int tid, struct ieee80211_tx_info *info, bool ndp)
1202{
1203 int legacy_success;
1204 int retries;
1205 int i;
1206 struct iwl_lq_cmd *table;
1207 u32 lq_hwrate;
1208 struct rs_rate lq_rate, tx_resp_rate;
1209 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
1210 u32 tlc_info = (uintptr_t)info->status.status_driver_data[0];
1211 u8 reduced_txp = tlc_info & RS_DRV_DATA_TXP_MSK;
1212 u8 lq_color = RS_DRV_DATA_LQ_COLOR_GET(tlc_info);
1213 u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1];
1214 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1215 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv;
1216
1217 /* Treat uninitialized rate scaling data same as non-existing. */
1218 if (!lq_sta) {
1219 IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n");
1220 return;
1221 } else if (!lq_sta->pers.drv) {
1222 IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
1223 return;
1224 }
1225
1226 /* This packet was aggregated but doesn't carry status info */
1227 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
1228 !(info->flags & IEEE80211_TX_STAT_AMPDU))
1229 return;
1230
1231 if (rs_rate_from_ucode_rate(tx_resp_hwrate, info->band,
1232 &tx_resp_rate)) {
1233 WARN_ON_ONCE(1);
1234 return;
1235 }
1236
1237#ifdef CONFIG_MAC80211_DEBUGFS
1238 /* Disable last tx check if we are debugging with fixed rate but
1239 * update tx stats */
1240 if (lq_sta->pers.dbg_fixed_rate) {
1241 int index = tx_resp_rate.index;
1242 enum rs_column column;
1243 int attempts, success;
1244
1245 column = rs_get_column_from_rate(&tx_resp_rate);
1246 if (WARN_ONCE(column == RS_COLUMN_INVALID,
1247 "Can't map rate 0x%x to column",
1248 tx_resp_hwrate))
1249 return;
1250
1251 if (info->flags & IEEE80211_TX_STAT_AMPDU) {
1252 attempts = info->status.ampdu_len;
1253 success = info->status.ampdu_ack_len;
1254 } else {
1255 attempts = info->status.rates[0].count;
1256 success = !!(info->flags & IEEE80211_TX_STAT_ACK);
1257 }
1258
1259 lq_sta->pers.tx_stats[column][index].total += attempts;
1260 lq_sta->pers.tx_stats[column][index].success += success;
1261
1262 IWL_DEBUG_RATE(mvm, "Fixed rate 0x%x success %d attempts %d\n",
1263 tx_resp_hwrate, success, attempts);
1264 return;
1265 }
1266#endif
1267
1268 if (time_after(jiffies,
1269 (unsigned long)(lq_sta->last_tx +
1270 (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
1271 IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
1272 iwl_mvm_rs_rate_init(mvm, sta, info->band, true);
1273 return;
1274 }
1275 lq_sta->last_tx = jiffies;
1276
1277 /* Ignore this Tx frame response if its initial rate doesn't match
1278 * that of latest Link Quality command. There may be stragglers
1279 * from a previous Link Quality command, but we're no longer interested
1280 * in those; they're either from the "active" mode while we're trying
1281 * to check "search" mode, or a prior "search" mode after we've moved
1282 * to a new "search" mode (which might become the new "active" mode).
1283 */
1284 table = &lq_sta->lq;
1285 lq_hwrate = le32_to_cpu(table->rs_table[0]);
1286 if (rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate)) {
1287 WARN_ON_ONCE(1);
1288 return;
1289 }
1290
1291 /* Here we actually compare this rate to the latest LQ command */
1292 if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) {
1293 IWL_DEBUG_RATE(mvm,
1294 "tx resp color 0x%x does not match 0x%x\n",
1295 lq_color, LQ_FLAG_COLOR_GET(table->flags));
1296
1297 /*
1298 * Since rates mis-match, the last LQ command may have failed.
1299 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
1300 * ... driver.
1301 */
1302 lq_sta->missed_rate_counter++;
1303 if (lq_sta->missed_rate_counter > IWL_MVM_RS_MISSED_RATE_MAX) {
1304 lq_sta->missed_rate_counter = 0;
1305 IWL_DEBUG_RATE(mvm,
1306 "Too many rates mismatch. Send sync LQ. rs_state %d\n",
1307 lq_sta->rs_state);
1308 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
1309 }
1310 /* Regardless, ignore this status info for outdated rate */
1311 return;
1312 } else
1313 /* Rate did match, so reset the missed_rate_counter */
1314 lq_sta->missed_rate_counter = 0;
1315
1316 if (!lq_sta->search_better_tbl) {
1317 curr_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1318 other_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
1319 } else {
1320 curr_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
1321 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1322 }
1323
1324 if (WARN_ON_ONCE(!rs_rate_column_match(&lq_rate, &curr_tbl->rate))) {
1325 IWL_DEBUG_RATE(mvm,
1326 "Neither active nor search matches tx rate\n");
1327 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1328 rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE");
1329 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
1330 rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH");
1331 rs_dump_rate(mvm, &lq_rate, "ACTUAL");
1332
1333 /*
1334 * no matching table found, let's by-pass the data collection
1335 * and continue to perform rate scale to find the rate table
1336 */
1337 rs_stay_in_table(lq_sta, true);
1338 goto done;
1339 }
1340
1341 /*
1342 * Updating the frame history depends on whether packets were
1343 * aggregated.
1344 *
1345 * For aggregation, all packets were transmitted at the same rate, the
1346 * first index into rate scale table.
1347 */
1348 if (info->flags & IEEE80211_TX_STAT_AMPDU) {
1349 rs_collect_tpc_data(mvm, lq_sta, curr_tbl, tx_resp_rate.index,
1350 info->status.ampdu_len,
1351 info->status.ampdu_ack_len,
1352 reduced_txp);
1353
1354 /* ampdu_ack_len = 0 marks no BA was received. For TLC, treat
1355 * it as a single frame loss as we don't want the success ratio
1356 * to dip too quickly because a BA wasn't received.
1357 * For TPC, there's no need for this optimisation since we want
1358 * to recover very quickly from a bad power reduction and,
1359 * therefore we'd like the success ratio to get an immediate hit
1360 * when failing to get a BA, so we'd switch back to a lower or
1361 * zero power reduction. When FW transmits agg with a rate
1362 * different from the initial rate, it will not use reduced txp
1363 * and will send BA notification twice (one empty with reduced
1364 * txp equal to the value from LQ and one with reduced txp 0).
1365 * We need to update counters for each txp level accordingly.
1366 */
1367 if (info->status.ampdu_ack_len == 0)
1368 info->status.ampdu_len = 1;
1369
1370 rs_collect_tlc_data(mvm, mvmsta, tid, curr_tbl, tx_resp_rate.index,
1371 info->status.ampdu_len,
1372 info->status.ampdu_ack_len);
1373
1374 /* Update success/fail counts if not searching for new mode */
1375 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
1376 lq_sta->total_success += info->status.ampdu_ack_len;
1377 lq_sta->total_failed += (info->status.ampdu_len -
1378 info->status.ampdu_ack_len);
1379 }
1380 } else {
1381 /* For legacy, update frame history with for each Tx retry. */
1382 retries = info->status.rates[0].count - 1;
1383 /* HW doesn't send more than 15 retries */
1384 retries = min(retries, 15);
1385
1386 /* The last transmission may have been successful */
1387 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
1388 /* Collect data for each rate used during failed TX attempts */
1389 for (i = 0; i <= retries; ++i) {
1390 lq_hwrate = le32_to_cpu(table->rs_table[i]);
1391 if (rs_rate_from_ucode_rate(lq_hwrate, info->band,
1392 &lq_rate)) {
1393 WARN_ON_ONCE(1);
1394 return;
1395 }
1396
1397 /*
1398 * Only collect stats if retried rate is in the same RS
1399 * table as active/search.
1400 */
1401 if (rs_rate_column_match(&lq_rate, &curr_tbl->rate))
1402 tmp_tbl = curr_tbl;
1403 else if (rs_rate_column_match(&lq_rate,
1404 &other_tbl->rate))
1405 tmp_tbl = other_tbl;
1406 else
1407 continue;
1408
1409 rs_collect_tpc_data(mvm, lq_sta, tmp_tbl,
1410 tx_resp_rate.index, 1,
1411 i < retries ? 0 : legacy_success,
1412 reduced_txp);
1413 rs_collect_tlc_data(mvm, mvmsta, tid, tmp_tbl,
1414 tx_resp_rate.index, 1,
1415 i < retries ? 0 : legacy_success);
1416 }
1417
1418 /* Update success/fail counts if not searching for new mode */
1419 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
1420 lq_sta->total_success += legacy_success;
1421 lq_sta->total_failed += retries + (1 - legacy_success);
1422 }
1423 }
1424 /* The last TX rate is cached in lq_sta; it's set in if/else above */
1425 lq_sta->last_rate_n_flags = lq_hwrate;
1426 IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp);
1427done:
1428 /* See if there's a better rate or modulation mode to try. */
1429 if (sta->supp_rates[info->band])
1430 rs_rate_scale_perform(mvm, sta, lq_sta, tid, ndp);
1431}
1432
1433/* 1200/*
1434 * mac80211 sends us Tx status 1201 * mac80211 sends us Tx status
1435 */ 1202 */
@@ -1442,8 +1209,9 @@ static void rs_drv_mac80211_tx_status(void *mvm_r,
1442 struct iwl_op_mode *op_mode = mvm_r; 1209 struct iwl_op_mode *op_mode = mvm_r;
1443 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 1210 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
1444 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1211 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1212 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1445 1213
1446 if (!iwl_mvm_sta_from_mac80211(sta)->vif) 1214 if (!mvmsta->vif)
1447 return; 1215 return;
1448 1216
1449 if (!ieee80211_is_data(hdr->frame_control) || 1217 if (!ieee80211_is_data(hdr->frame_control) ||
@@ -1584,6 +1352,18 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1584 tbl->expected_tpt = rs_get_expected_tpt_table(lq_sta, column, rate->bw); 1352 tbl->expected_tpt = rs_get_expected_tpt_table(lq_sta, column, rate->bw);
1585} 1353}
1586 1354
1355/* rs uses two tables, one is active and the second is for searching better
1356 * configuration. This function, according to the index of the currently
1357 * active table returns the search table, which is located at the
1358 * index complementary to 1 according to the active table (active = 1,
1359 * search = 0 or active = 0, search = 1).
1360 * Since lq_info is an arary of size 2, make sure index cannot be out of bounds.
1361 */
1362static inline u8 rs_search_tbl(u8 active_tbl)
1363{
1364 return (active_tbl ^ 1) & 1;
1365}
1366
1587static s32 rs_get_best_rate(struct iwl_mvm *mvm, 1367static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1588 struct iwl_lq_sta *lq_sta, 1368 struct iwl_lq_sta *lq_sta,
1589 struct iwl_scale_tbl_info *tbl, /* "search" */ 1369 struct iwl_scale_tbl_info *tbl, /* "search" */
@@ -1794,7 +1574,7 @@ static void rs_update_rate_tbl(struct iwl_mvm *mvm,
1794 struct iwl_scale_tbl_info *tbl) 1574 struct iwl_scale_tbl_info *tbl)
1795{ 1575{
1796 rs_fill_lq_cmd(mvm, sta, lq_sta, &tbl->rate); 1576 rs_fill_lq_cmd(mvm, sta, lq_sta, &tbl->rate);
1797 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false); 1577 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq);
1798} 1578}
1799 1579
1800static bool rs_tweak_rate_tbl(struct iwl_mvm *mvm, 1580static bool rs_tweak_rate_tbl(struct iwl_mvm *mvm,
@@ -1931,9 +1711,9 @@ static int rs_switch_to_column(struct iwl_mvm *mvm,
1931 struct ieee80211_sta *sta, 1711 struct ieee80211_sta *sta,
1932 enum rs_column col_id) 1712 enum rs_column col_id)
1933{ 1713{
1934 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1714 struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl];
1935 struct iwl_scale_tbl_info *search_tbl = 1715 struct iwl_scale_tbl_info *search_tbl =
1936 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); 1716 &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)];
1937 struct rs_rate *rate = &search_tbl->rate; 1717 struct rs_rate *rate = &search_tbl->rate;
1938 const struct rs_tx_column *column = &rs_tx_columns[col_id]; 1718 const struct rs_tx_column *column = &rs_tx_columns[col_id];
1939 const struct rs_tx_column *curr_column = &rs_tx_columns[tbl->column]; 1719 const struct rs_tx_column *curr_column = &rs_tx_columns[tbl->column];
@@ -2341,7 +2121,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2341 if (!lq_sta->search_better_tbl) 2121 if (!lq_sta->search_better_tbl)
2342 active_tbl = lq_sta->active_tbl; 2122 active_tbl = lq_sta->active_tbl;
2343 else 2123 else
2344 active_tbl = 1 - lq_sta->active_tbl; 2124 active_tbl = rs_search_tbl(lq_sta->active_tbl);
2345 2125
2346 tbl = &(lq_sta->lq_info[active_tbl]); 2126 tbl = &(lq_sta->lq_info[active_tbl]);
2347 rate = &tbl->rate; 2127 rate = &tbl->rate;
@@ -2565,7 +2345,7 @@ lq_update:
2565 /* If new "search" mode was selected, set up in uCode table */ 2345 /* If new "search" mode was selected, set up in uCode table */
2566 if (lq_sta->search_better_tbl) { 2346 if (lq_sta->search_better_tbl) {
2567 /* Access the "search" table, clear its history. */ 2347 /* Access the "search" table, clear its history. */
2568 tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); 2348 tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)];
2569 rs_rate_scale_clear_tbl_windows(mvm, tbl); 2349 rs_rate_scale_clear_tbl_windows(mvm, tbl);
2570 2350
2571 /* Use new "search" start rate */ 2351 /* Use new "search" start rate */
@@ -2896,7 +2676,7 @@ void rs_update_last_rssi(struct iwl_mvm *mvm,
2896static void rs_initialize_lq(struct iwl_mvm *mvm, 2676static void rs_initialize_lq(struct iwl_mvm *mvm,
2897 struct ieee80211_sta *sta, 2677 struct ieee80211_sta *sta,
2898 struct iwl_lq_sta *lq_sta, 2678 struct iwl_lq_sta *lq_sta,
2899 enum nl80211_band band, bool update) 2679 enum nl80211_band band)
2900{ 2680{
2901 struct iwl_scale_tbl_info *tbl; 2681 struct iwl_scale_tbl_info *tbl;
2902 struct rs_rate *rate; 2682 struct rs_rate *rate;
@@ -2908,7 +2688,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
2908 if (!lq_sta->search_better_tbl) 2688 if (!lq_sta->search_better_tbl)
2909 active_tbl = lq_sta->active_tbl; 2689 active_tbl = lq_sta->active_tbl;
2910 else 2690 else
2911 active_tbl = 1 - lq_sta->active_tbl; 2691 active_tbl = rs_search_tbl(lq_sta->active_tbl);
2912 2692
2913 tbl = &(lq_sta->lq_info[active_tbl]); 2693 tbl = &(lq_sta->lq_info[active_tbl]);
2914 rate = &tbl->rate; 2694 rate = &tbl->rate;
@@ -2926,7 +2706,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
2926 rs_set_expected_tpt_table(lq_sta, tbl); 2706 rs_set_expected_tpt_table(lq_sta, tbl);
2927 rs_fill_lq_cmd(mvm, sta, lq_sta, rate); 2707 rs_fill_lq_cmd(mvm, sta, lq_sta, rate);
2928 /* TODO restore station should remember the lq cmd */ 2708 /* TODO restore station should remember the lq cmd */
2929 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, !update); 2709 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq);
2930} 2710}
2931 2711
2932static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta, 2712static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta,
@@ -3175,7 +2955,7 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
3175 * Called after adding a new station to initialize rate scaling 2955 * Called after adding a new station to initialize rate scaling
3176 */ 2956 */
3177static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 2957static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
3178 enum nl80211_band band, bool update) 2958 enum nl80211_band band)
3179{ 2959{
3180 int i, j; 2960 int i, j;
3181 struct ieee80211_hw *hw = mvm->hw; 2961 struct ieee80211_hw *hw = mvm->hw;
@@ -3186,6 +2966,8 @@ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
3186 struct ieee80211_supported_band *sband; 2966 struct ieee80211_supported_band *sband;
3187 unsigned long supp; /* must be unsigned long for for_each_set_bit */ 2967 unsigned long supp; /* must be unsigned long for for_each_set_bit */
3188 2968
2969 lockdep_assert_held(&mvmsta->lq_sta.rs_drv.pers.lock);
2970
3189 /* clear all non-persistent lq data */ 2971 /* clear all non-persistent lq data */
3190 memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers)); 2972 memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers));
3191 2973
@@ -3255,7 +3037,7 @@ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
3255#ifdef CONFIG_IWLWIFI_DEBUGFS 3037#ifdef CONFIG_IWLWIFI_DEBUGFS
3256 iwl_mvm_reset_frame_stats(mvm); 3038 iwl_mvm_reset_frame_stats(mvm);
3257#endif 3039#endif
3258 rs_initialize_lq(mvm, sta, lq_sta, band, update); 3040 rs_initialize_lq(mvm, sta, lq_sta, band);
3259} 3041}
3260 3042
3261static void rs_drv_rate_update(void *mvm_r, 3043static void rs_drv_rate_update(void *mvm_r,
@@ -3278,6 +3060,258 @@ static void rs_drv_rate_update(void *mvm_r,
3278 iwl_mvm_rs_rate_init(mvm, sta, sband->band, true); 3060 iwl_mvm_rs_rate_init(mvm, sta, sband->band, true);
3279} 3061}
3280 3062
3063static void __iwl_mvm_rs_tx_status(struct iwl_mvm *mvm,
3064 struct ieee80211_sta *sta,
3065 int tid, struct ieee80211_tx_info *info,
3066 bool ndp)
3067{
3068 int legacy_success;
3069 int retries;
3070 int i;
3071 struct iwl_lq_cmd *table;
3072 u32 lq_hwrate;
3073 struct rs_rate lq_rate, tx_resp_rate;
3074 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
3075 u32 tlc_info = (uintptr_t)info->status.status_driver_data[0];
3076 u8 reduced_txp = tlc_info & RS_DRV_DATA_TXP_MSK;
3077 u8 lq_color = RS_DRV_DATA_LQ_COLOR_GET(tlc_info);
3078 u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1];
3079 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
3080 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta.rs_drv;
3081
3082 /* Treat uninitialized rate scaling data same as non-existing. */
3083 if (!lq_sta) {
3084 IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n");
3085 return;
3086 } else if (!lq_sta->pers.drv) {
3087 IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
3088 return;
3089 }
3090
3091 /* This packet was aggregated but doesn't carry status info */
3092 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
3093 !(info->flags & IEEE80211_TX_STAT_AMPDU))
3094 return;
3095
3096 if (rs_rate_from_ucode_rate(tx_resp_hwrate, info->band,
3097 &tx_resp_rate)) {
3098 WARN_ON_ONCE(1);
3099 return;
3100 }
3101
3102#ifdef CONFIG_MAC80211_DEBUGFS
3103 /* Disable last tx check if we are debugging with fixed rate but
3104 * update tx stats
3105 */
3106 if (lq_sta->pers.dbg_fixed_rate) {
3107 int index = tx_resp_rate.index;
3108 enum rs_column column;
3109 int attempts, success;
3110
3111 column = rs_get_column_from_rate(&tx_resp_rate);
3112 if (WARN_ONCE(column == RS_COLUMN_INVALID,
3113 "Can't map rate 0x%x to column",
3114 tx_resp_hwrate))
3115 return;
3116
3117 if (info->flags & IEEE80211_TX_STAT_AMPDU) {
3118 attempts = info->status.ampdu_len;
3119 success = info->status.ampdu_ack_len;
3120 } else {
3121 attempts = info->status.rates[0].count;
3122 success = !!(info->flags & IEEE80211_TX_STAT_ACK);
3123 }
3124
3125 lq_sta->pers.tx_stats[column][index].total += attempts;
3126 lq_sta->pers.tx_stats[column][index].success += success;
3127
3128 IWL_DEBUG_RATE(mvm, "Fixed rate 0x%x success %d attempts %d\n",
3129 tx_resp_hwrate, success, attempts);
3130 return;
3131 }
3132#endif
3133
3134 if (time_after(jiffies,
3135 (unsigned long)(lq_sta->last_tx +
3136 (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
3137 IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
3138 /* reach here only in case of driver RS, call directly
3139 * the unlocked version
3140 */
3141 rs_drv_rate_init(mvm, sta, info->band);
3142 return;
3143 }
3144 lq_sta->last_tx = jiffies;
3145
3146 /* Ignore this Tx frame response if its initial rate doesn't match
3147 * that of latest Link Quality command. There may be stragglers
3148 * from a previous Link Quality command, but we're no longer interested
3149 * in those; they're either from the "active" mode while we're trying
3150 * to check "search" mode, or a prior "search" mode after we've moved
3151 * to a new "search" mode (which might become the new "active" mode).
3152 */
3153 table = &lq_sta->lq;
3154 lq_hwrate = le32_to_cpu(table->rs_table[0]);
3155 if (rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate)) {
3156 WARN_ON_ONCE(1);
3157 return;
3158 }
3159
3160 /* Here we actually compare this rate to the latest LQ command */
3161 if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) {
3162 IWL_DEBUG_RATE(mvm,
3163 "tx resp color 0x%x does not match 0x%x\n",
3164 lq_color, LQ_FLAG_COLOR_GET(table->flags));
3165
3166 /* Since rates mis-match, the last LQ command may have failed.
3167 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
3168 * ... driver.
3169 */
3170 lq_sta->missed_rate_counter++;
3171 if (lq_sta->missed_rate_counter > IWL_MVM_RS_MISSED_RATE_MAX) {
3172 lq_sta->missed_rate_counter = 0;
3173 IWL_DEBUG_RATE(mvm,
3174 "Too many rates mismatch. Send sync LQ. rs_state %d\n",
3175 lq_sta->rs_state);
3176 iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq);
3177 }
3178 /* Regardless, ignore this status info for outdated rate */
3179 return;
3180 }
3181
3182 /* Rate did match, so reset the missed_rate_counter */
3183 lq_sta->missed_rate_counter = 0;
3184
3185 if (!lq_sta->search_better_tbl) {
3186 curr_tbl = &lq_sta->lq_info[lq_sta->active_tbl];
3187 other_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)];
3188 } else {
3189 curr_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)];
3190 other_tbl = &lq_sta->lq_info[lq_sta->active_tbl];
3191 }
3192
3193 if (WARN_ON_ONCE(!rs_rate_column_match(&lq_rate, &curr_tbl->rate))) {
3194 IWL_DEBUG_RATE(mvm,
3195 "Neither active nor search matches tx rate\n");
3196 tmp_tbl = &lq_sta->lq_info[lq_sta->active_tbl];
3197 rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE");
3198 tmp_tbl = &lq_sta->lq_info[rs_search_tbl(lq_sta->active_tbl)];
3199 rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH");
3200 rs_dump_rate(mvm, &lq_rate, "ACTUAL");
3201
3202 /* no matching table found, let's by-pass the data collection
3203 * and continue to perform rate scale to find the rate table
3204 */
3205 rs_stay_in_table(lq_sta, true);
3206 goto done;
3207 }
3208
3209 /* Updating the frame history depends on whether packets were
3210 * aggregated.
3211 *
3212 * For aggregation, all packets were transmitted at the same rate, the
3213 * first index into rate scale table.
3214 */
3215 if (info->flags & IEEE80211_TX_STAT_AMPDU) {
3216 rs_collect_tpc_data(mvm, lq_sta, curr_tbl, tx_resp_rate.index,
3217 info->status.ampdu_len,
3218 info->status.ampdu_ack_len,
3219 reduced_txp);
3220
3221 /* ampdu_ack_len = 0 marks no BA was received. For TLC, treat
3222 * it as a single frame loss as we don't want the success ratio
3223 * to dip too quickly because a BA wasn't received.
3224 * For TPC, there's no need for this optimisation since we want
3225 * to recover very quickly from a bad power reduction and,
3226 * therefore we'd like the success ratio to get an immediate hit
3227 * when failing to get a BA, so we'd switch back to a lower or
3228 * zero power reduction. When FW transmits agg with a rate
3229 * different from the initial rate, it will not use reduced txp
3230 * and will send BA notification twice (one empty with reduced
3231 * txp equal to the value from LQ and one with reduced txp 0).
3232 * We need to update counters for each txp level accordingly.
3233 */
3234 if (info->status.ampdu_ack_len == 0)
3235 info->status.ampdu_len = 1;
3236
3237 rs_collect_tlc_data(mvm, mvmsta, tid, curr_tbl,
3238 tx_resp_rate.index,
3239 info->status.ampdu_len,
3240 info->status.ampdu_ack_len);
3241
3242 /* Update success/fail counts if not searching for new mode */
3243 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
3244 lq_sta->total_success += info->status.ampdu_ack_len;
3245 lq_sta->total_failed += (info->status.ampdu_len -
3246 info->status.ampdu_ack_len);
3247 }
3248 } else {
3249 /* For legacy, update frame history with for each Tx retry. */
3250 retries = info->status.rates[0].count - 1;
3251 /* HW doesn't send more than 15 retries */
3252 retries = min(retries, 15);
3253
3254 /* The last transmission may have been successful */
3255 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
3256 /* Collect data for each rate used during failed TX attempts */
3257 for (i = 0; i <= retries; ++i) {
3258 lq_hwrate = le32_to_cpu(table->rs_table[i]);
3259 if (rs_rate_from_ucode_rate(lq_hwrate, info->band,
3260 &lq_rate)) {
3261 WARN_ON_ONCE(1);
3262 return;
3263 }
3264
3265 /* Only collect stats if retried rate is in the same RS
3266 * table as active/search.
3267 */
3268 if (rs_rate_column_match(&lq_rate, &curr_tbl->rate))
3269 tmp_tbl = curr_tbl;
3270 else if (rs_rate_column_match(&lq_rate,
3271 &other_tbl->rate))
3272 tmp_tbl = other_tbl;
3273 else
3274 continue;
3275
3276 rs_collect_tpc_data(mvm, lq_sta, tmp_tbl,
3277 tx_resp_rate.index, 1,
3278 i < retries ? 0 : legacy_success,
3279 reduced_txp);
3280 rs_collect_tlc_data(mvm, mvmsta, tid, tmp_tbl,
3281 tx_resp_rate.index, 1,
3282 i < retries ? 0 : legacy_success);
3283 }
3284
3285 /* Update success/fail counts if not searching for new mode */
3286 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN) {
3287 lq_sta->total_success += legacy_success;
3288 lq_sta->total_failed += retries + (1 - legacy_success);
3289 }
3290 }
3291 /* The last TX rate is cached in lq_sta; it's set in if/else above */
3292 lq_sta->last_rate_n_flags = lq_hwrate;
3293 IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp);
3294done:
3295 /* See if there's a better rate or modulation mode to try. */
3296 if (sta->supp_rates[info->band])
3297 rs_rate_scale_perform(mvm, sta, lq_sta, tid, ndp);
3298}
3299
3300void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
3301 int tid, struct ieee80211_tx_info *info, bool ndp)
3302{
3303 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
3304
3305 /* If it's locked we are in middle of init flow
3306 * just wait for next tx status to update the lq_sta data
3307 */
3308 if (!spin_trylock(&mvmsta->lq_sta.rs_drv.pers.lock))
3309 return;
3310
3311 __iwl_mvm_rs_tx_status(mvm, sta, tid, info, ndp);
3312 spin_unlock(&mvmsta->lq_sta.rs_drv.pers.lock);
3313}
3314
3281#ifdef CONFIG_MAC80211_DEBUGFS 3315#ifdef CONFIG_MAC80211_DEBUGFS
3282static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm, 3316static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm,
3283 struct iwl_lq_cmd *lq_cmd, 3317 struct iwl_lq_cmd *lq_cmd,
@@ -3569,7 +3603,7 @@ static void rs_set_lq_ss_params(struct iwl_mvm *mvm,
3569 3603
3570 bfersta_ss_params &= ~LQ_SS_BFER_ALLOWED; 3604 bfersta_ss_params &= ~LQ_SS_BFER_ALLOWED;
3571 bfersta_lq_cmd->ss_params = cpu_to_le32(bfersta_ss_params); 3605 bfersta_lq_cmd->ss_params = cpu_to_le32(bfersta_ss_params);
3572 iwl_mvm_send_lq_cmd(mvm, bfersta_lq_cmd, false); 3606 iwl_mvm_send_lq_cmd(mvm, bfersta_lq_cmd);
3573 3607
3574 ss_params |= LQ_SS_BFER_ALLOWED; 3608 ss_params |= LQ_SS_BFER_ALLOWED;
3575 IWL_DEBUG_RATE(mvm, 3609 IWL_DEBUG_RATE(mvm,
@@ -3735,7 +3769,7 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm,
3735 3769
3736 if (lq_sta->pers.dbg_fixed_rate) { 3770 if (lq_sta->pers.dbg_fixed_rate) {
3737 rs_fill_lq_cmd(mvm, NULL, lq_sta, NULL); 3771 rs_fill_lq_cmd(mvm, NULL, lq_sta, NULL);
3738 iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq, false); 3772 iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq);
3739 } 3773 }
3740} 3774}
3741 3775
@@ -4127,10 +4161,15 @@ static const struct rate_control_ops rs_mvm_ops_drv = {
4127void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 4161void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
4128 enum nl80211_band band, bool update) 4162 enum nl80211_band band, bool update)
4129{ 4163{
4130 if (iwl_mvm_has_tlc_offload(mvm)) 4164 if (iwl_mvm_has_tlc_offload(mvm)) {
4131 rs_fw_rate_init(mvm, sta, band, update); 4165 rs_fw_rate_init(mvm, sta, band, update);
4132 else 4166 } else {
4133 rs_drv_rate_init(mvm, sta, band, update); 4167 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
4168
4169 spin_lock(&mvmsta->lq_sta.rs_drv.pers.lock);
4170 rs_drv_rate_init(mvm, sta, band);
4171 spin_unlock(&mvmsta->lq_sta.rs_drv.pers.lock);
4172 }
4134} 4173}
4135 4174
4136int iwl_mvm_rate_control_register(void) 4175int iwl_mvm_rate_control_register(void)
@@ -4160,7 +4199,7 @@ static int rs_drv_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
4160 lq->flags &= ~LQ_FLAG_USE_RTS_MSK; 4199 lq->flags &= ~LQ_FLAG_USE_RTS_MSK;
4161 } 4200 }
4162 4201
4163 return iwl_mvm_send_lq_cmd(mvm, lq, false); 4202 return iwl_mvm_send_lq_cmd(mvm, lq);
4164} 4203}
4165 4204
4166/** 4205/**