|
@@ -2,7 +2,7 @@
|
|
|
*
|
|
|
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
|
|
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
|
|
- * Copyright(c) 2016 Intel Deutschland GmbH
|
|
|
+ * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
|
|
*
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
* 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,
|
|
|
rs_get_lower_rate_in_column(lq_sta, rate);
|
|
|
}
|
|
|
|
|
|
-/* Check if both rates are identical
|
|
|
- * allow_ant_mismatch enables matching a SISO rate on ANT_A or ANT_B
|
|
|
- * with a rate indicating STBC/BFER and ANT_AB.
|
|
|
- */
|
|
|
-static inline bool rs_rate_equal(struct rs_rate *a,
|
|
|
- struct rs_rate *b,
|
|
|
- bool allow_ant_mismatch)
|
|
|
-
|
|
|
-{
|
|
|
- bool ant_match = (a->ant == b->ant) && (a->stbc == b->stbc) &&
|
|
|
- (a->bfer == b->bfer);
|
|
|
-
|
|
|
- if (allow_ant_mismatch) {
|
|
|
- if (a->stbc || a->bfer) {
|
|
|
- WARN_ONCE(a->ant != ANT_AB, "stbc %d bfer %d ant %d",
|
|
|
- a->stbc, a->bfer, a->ant);
|
|
|
- ant_match |= (b->ant == ANT_A || b->ant == ANT_B);
|
|
|
- } else if (b->stbc || b->bfer) {
|
|
|
- WARN_ONCE(b->ant != ANT_AB, "stbc %d bfer %d ant %d",
|
|
|
- b->stbc, b->bfer, b->ant);
|
|
|
- ant_match |= (a->ant == ANT_A || a->ant == ANT_B);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return (a->type == b->type) && (a->bw == b->bw) && (a->sgi == b->sgi) &&
|
|
|
- (a->ldpc == b->ldpc) && (a->index == b->index) && ant_match;
|
|
|
-}
|
|
|
-
|
|
|
/* Check if both rates share the same column */
|
|
|
static inline bool rs_rate_column_match(struct rs_rate *a,
|
|
|
struct rs_rate *b)
|
|
@@ -1182,12 +1154,12 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
|
|
u32 lq_hwrate;
|
|
|
struct rs_rate lq_rate, tx_resp_rate;
|
|
|
struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
|
|
|
- u8 reduced_txp = (uintptr_t)info->status.status_driver_data[0];
|
|
|
+ u32 tlc_info = (uintptr_t)info->status.status_driver_data[0];
|
|
|
+ u8 reduced_txp = tlc_info & RS_DRV_DATA_TXP_MSK;
|
|
|
+ u8 lq_color = RS_DRV_DATA_LQ_COLOR_GET(tlc_info);
|
|
|
u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1];
|
|
|
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
|
|
struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;
|
|
|
- bool allow_ant_mismatch = fw_has_api(&mvm->fw->ucode_capa,
|
|
|
- IWL_UCODE_TLV_API_LQ_SS_PARAMS);
|
|
|
|
|
|
/* Treat uninitialized rate scaling data same as non-existing. */
|
|
|
if (!lq_sta) {
|
|
@@ -1262,10 +1234,10 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
|
|
rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate);
|
|
|
|
|
|
/* Here we actually compare this rate to the latest LQ command */
|
|
|
- if (!rs_rate_equal(&tx_resp_rate, &lq_rate, allow_ant_mismatch)) {
|
|
|
+ if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) {
|
|
|
IWL_DEBUG_RATE(mvm,
|
|
|
- "initial tx resp rate 0x%x does not match 0x%x\n",
|
|
|
- tx_resp_hwrate, lq_hwrate);
|
|
|
+ "tx resp color 0x%x does not match 0x%x\n",
|
|
|
+ lq_color, LQ_FLAG_COLOR_GET(table->flags));
|
|
|
|
|
|
/*
|
|
|
* 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,
|
|
|
u8 valid_tx_ant = 0;
|
|
|
struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
|
|
|
bool toggle_ant = false;
|
|
|
+ u32 color;
|
|
|
|
|
|
memcpy(&rate, initial_rate, sizeof(rate));
|
|
|
|
|
@@ -3380,6 +3353,9 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
|
|
|
num_rates, num_retries, valid_tx_ant,
|
|
|
toggle_ant);
|
|
|
|
|
|
+ /* update the color of the LQ command (as a counter at bits 1-3) */
|
|
|
+ color = LQ_FLAGS_COLOR_INC(LQ_FLAG_COLOR_GET(lq_cmd->flags));
|
|
|
+ lq_cmd->flags = LQ_FLAG_COLOR_SET(lq_cmd->flags, color);
|
|
|
}
|
|
|
|
|
|
struct rs_bfer_active_iter_data {
|