diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/rs.c')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 46 |
1 files changed, 11 insertions, 35 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 7788eefcd2bd..aa785cf3cf68 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. |
4 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH | 4 | * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH |
5 | * Copyright(c) 2016 Intel Deutschland GmbH | 5 | * Copyright(c) 2016 - 2017 Intel Deutschland GmbH |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of version 2 of the GNU General Public License as | 8 | * under the terms of version 2 of the GNU General Public License as |
@@ -1083,34 +1083,6 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta, | |||
1083 | rs_get_lower_rate_in_column(lq_sta, rate); | 1083 | rs_get_lower_rate_in_column(lq_sta, rate); |
1084 | } | 1084 | } |
1085 | 1085 | ||
1086 | /* Check if both rates are identical | ||
1087 | * allow_ant_mismatch enables matching a SISO rate on ANT_A or ANT_B | ||
1088 | * with a rate indicating STBC/BFER and ANT_AB. | ||
1089 | */ | ||
1090 | static inline bool rs_rate_equal(struct rs_rate *a, | ||
1091 | struct rs_rate *b, | ||
1092 | bool allow_ant_mismatch) | ||
1093 | |||
1094 | { | ||
1095 | bool ant_match = (a->ant == b->ant) && (a->stbc == b->stbc) && | ||
1096 | (a->bfer == b->bfer); | ||
1097 | |||
1098 | if (allow_ant_mismatch) { | ||
1099 | if (a->stbc || a->bfer) { | ||
1100 | WARN_ONCE(a->ant != ANT_AB, "stbc %d bfer %d ant %d", | ||
1101 | a->stbc, a->bfer, a->ant); | ||
1102 | ant_match |= (b->ant == ANT_A || b->ant == ANT_B); | ||
1103 | } else if (b->stbc || b->bfer) { | ||
1104 | WARN_ONCE(b->ant != ANT_AB, "stbc %d bfer %d ant %d", | ||
1105 | b->stbc, b->bfer, b->ant); | ||
1106 | ant_match |= (a->ant == ANT_A || a->ant == ANT_B); | ||
1107 | } | ||
1108 | } | ||
1109 | |||
1110 | return (a->type == b->type) && (a->bw == b->bw) && (a->sgi == b->sgi) && | ||
1111 | (a->ldpc == b->ldpc) && (a->index == b->index) && ant_match; | ||
1112 | } | ||
1113 | |||
1114 | /* Check if both rates share the same column */ | 1086 | /* Check if both rates share the same column */ |
1115 | static inline bool rs_rate_column_match(struct rs_rate *a, | 1087 | static inline bool rs_rate_column_match(struct rs_rate *a, |
1116 | struct rs_rate *b) | 1088 | struct rs_rate *b) |
@@ -1182,12 +1154,12 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
1182 | u32 lq_hwrate; | 1154 | u32 lq_hwrate; |
1183 | struct rs_rate lq_rate, tx_resp_rate; | 1155 | struct rs_rate lq_rate, tx_resp_rate; |
1184 | struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; | 1156 | struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; |
1185 | u8 reduced_txp = (uintptr_t)info->status.status_driver_data[0]; | 1157 | u32 tlc_info = (uintptr_t)info->status.status_driver_data[0]; |
1158 | u8 reduced_txp = tlc_info & RS_DRV_DATA_TXP_MSK; | ||
1159 | u8 lq_color = RS_DRV_DATA_LQ_COLOR_GET(tlc_info); | ||
1186 | u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1]; | 1160 | u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1]; |
1187 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); | 1161 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); |
1188 | struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta; | 1162 | struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta; |
1189 | bool allow_ant_mismatch = fw_has_api(&mvm->fw->ucode_capa, | ||
1190 | IWL_UCODE_TLV_API_LQ_SS_PARAMS); | ||
1191 | 1163 | ||
1192 | /* Treat uninitialized rate scaling data same as non-existing. */ | 1164 | /* Treat uninitialized rate scaling data same as non-existing. */ |
1193 | if (!lq_sta) { | 1165 | if (!lq_sta) { |
@@ -1262,10 +1234,10 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
1262 | rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate); | 1234 | rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate); |
1263 | 1235 | ||
1264 | /* Here we actually compare this rate to the latest LQ command */ | 1236 | /* Here we actually compare this rate to the latest LQ command */ |
1265 | if (!rs_rate_equal(&tx_resp_rate, &lq_rate, allow_ant_mismatch)) { | 1237 | if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) { |
1266 | IWL_DEBUG_RATE(mvm, | 1238 | IWL_DEBUG_RATE(mvm, |
1267 | "initial tx resp rate 0x%x does not match 0x%x\n", | 1239 | "tx resp color 0x%x does not match 0x%x\n", |
1268 | tx_resp_hwrate, lq_hwrate); | 1240 | lq_color, LQ_FLAG_COLOR_GET(table->flags)); |
1269 | 1241 | ||
1270 | /* | 1242 | /* |
1271 | * Since rates mis-match, the last LQ command may have failed. | 1243 | * Since rates mis-match, the last LQ command may have failed. |
@@ -3326,6 +3298,7 @@ static void rs_build_rates_table(struct iwl_mvm *mvm, | |||
3326 | u8 valid_tx_ant = 0; | 3298 | u8 valid_tx_ant = 0; |
3327 | struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; | 3299 | struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; |
3328 | bool toggle_ant = false; | 3300 | bool toggle_ant = false; |
3301 | u32 color; | ||
3329 | 3302 | ||
3330 | memcpy(&rate, initial_rate, sizeof(rate)); | 3303 | memcpy(&rate, initial_rate, sizeof(rate)); |
3331 | 3304 | ||
@@ -3380,6 +3353,9 @@ static void rs_build_rates_table(struct iwl_mvm *mvm, | |||
3380 | num_rates, num_retries, valid_tx_ant, | 3353 | num_rates, num_retries, valid_tx_ant, |
3381 | toggle_ant); | 3354 | toggle_ant); |
3382 | 3355 | ||
3356 | /* update the color of the LQ command (as a counter at bits 1-3) */ | ||
3357 | color = LQ_FLAGS_COLOR_INC(LQ_FLAG_COLOR_GET(lq_cmd->flags)); | ||
3358 | lq_cmd->flags = LQ_FLAG_COLOR_SET(lq_cmd->flags, color); | ||
3383 | } | 3359 | } |
3384 | 3360 | ||
3385 | struct rs_bfer_active_iter_data { | 3361 | struct rs_bfer_active_iter_data { |