diff --git a/ath10k-4.16/htt_rx.c b/ath10k-4.16/htt_rx.c index c743b58..991d5e0 100644 --- a/ath10k-4.16/htt_rx.c +++ b/ath10k-4.16/htt_rx.c @@ -2012,13 +2012,19 @@ static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar, tx_done.mpdus_failed = retries_info >> 8; } } - /* ath10k_warn(ar, - "htt tx completion-w2, msdu_id: %d tx-rate-code: 0x%x tx-rate-flags: 0x%x tried: %d failed: %d\n", + /*ath10k_warn(ar, + "htt tx completion-w2, msdu_id: %d tx-rate-code: 0x%x tx-rate-flags: 0x%x tried: %d failed: %d ack-rssi: %d\n", tx_done.msdu_id, tx_done.tx_rate_code, tx_done.tx_rate_flags, tx_done.mpdus_tried, - tx_done.mpdus_failed);*/ + tx_done.mpdus_failed, + tx_done.ack_rssi);*/ + + /* Firmware reports garbage for ack-rssi if packet was not acked. */ + if (unlikely(tx_done.status != HTT_TX_COMPL_STATE_ACK)) + tx_done.ack_rssi = 0; + ath10k_txrx_tx_unref(htt, &tx_done); } } else { diff --git a/ath10k-4.16/txrx.c b/ath10k-4.16/txrx.c index fdac801..baf1c57 100644 --- a/ath10k-4.16/txrx.c +++ b/ath10k-4.16/txrx.c @@ -72,8 +72,14 @@ static void ath10k_set_tx_rate_status(struct ath10k *ar, ch = ar->rx_channel; if (tx_done->mpdus_failed) { - /* Maybe there is a better way to report this tried vs failed stat up the stack? */ - rate->count = tx_done->mpdus_failed + 1; + if (tx_done->status == HTT_TX_COMPL_STATE_ACK) { + /* We failed some, but then succeeded (+1) */ + rate->count = tx_done->mpdus_failed + 1; + } + else { + /* We failed all of them */ + rate->count = tx_done->mpdus_failed; + } } else { rate->count = 1; @@ -133,6 +139,18 @@ static void ath10k_set_tx_rate_status(struct ath10k *ar, rate->flags |= IEEE80211_TX_RC_SHORT_GI; } +#if 0 +static const char* tx_done_state_str(int i) { + switch (i) { + case HTT_TX_COMPL_STATE_NONE: return "NONE"; + case HTT_TX_COMPL_STATE_ACK: return "ACK"; + case HTT_TX_COMPL_STATE_NOACK: return "NOACK"; + case HTT_TX_COMPL_STATE_DISCARD: return "DISCARD"; + default: return "UNKNOWN"; + } +} +#endif + int ath10k_txrx_tx_unref(struct ath10k_htt *htt, const struct htt_tx_done *tx_done) { @@ -164,6 +182,17 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt, return -ENOENT; } + /*ath10k_warn(ar, + "tx_unref, msdu_id: %d len: %d tx-rate-code: 0x%x tx-rate-flags: 0x%x tried: %d failed: %d ack-rssi: %d status: %d (%s)\n", + tx_done->msdu_id, + msdu->len, + tx_done->tx_rate_code, + tx_done->tx_rate_flags, + tx_done->mpdus_tried, + tx_done->mpdus_failed, + tx_done->ack_rssi, + tx_done->status, tx_done_state_str(tx_done->status));*/ + skb_cb = ATH10K_SKB_CB(msdu); txq = skb_cb->txq; diff --git a/ath10k-4.19/htt_rx.c b/ath10k-4.19/htt_rx.c index 574d8c0..033e559 100644 --- a/ath10k-4.19/htt_rx.c +++ b/ath10k-4.19/htt_rx.c @@ -2063,13 +2063,19 @@ static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar, tx_done.mpdus_failed = retries_info >> 8; } } - /* ath10k_warn(ar, - "htt tx completion-w2, msdu_id: %d tx-rate-code: 0x%x tx-rate-flags: 0x%x tried: %d failed: %d\n", + /*ath10k_warn(ar, + "htt tx completion-w2, msdu_id: %d tx-rate-code: 0x%x tx-rate-flags: 0x%x tried: %d failed: %d ack-rssi: %d\n", tx_done.msdu_id, tx_done.tx_rate_code, tx_done.tx_rate_flags, tx_done.mpdus_tried, - tx_done.mpdus_failed);*/ + tx_done.mpdus_failed, + tx_done.ack_rssi);*/ + + /* Firmware reports garbage for ack-rssi if packet was not acked. */ + if (unlikely(tx_done.status != HTT_TX_COMPL_STATE_ACK)) + tx_done.ack_rssi = 0; + ath10k_txrx_tx_unref(htt, &tx_done); } } else { diff --git a/ath10k-4.19/txrx.c b/ath10k-4.19/txrx.c index 7577cd4..b484f2b 100644 --- a/ath10k-4.19/txrx.c +++ b/ath10k-4.19/txrx.c @@ -73,8 +73,14 @@ static void ath10k_set_tx_rate_status(struct ath10k *ar, ch = ar->rx_channel; if (tx_done->mpdus_failed) { - /* Maybe there is a better way to report this tried vs failed stat up the stack? */ - rate->count = tx_done->mpdus_failed + 1; + if (tx_done->status == HTT_TX_COMPL_STATE_ACK) { + /* We failed some, but then succeeded (+1) */ + rate->count = tx_done->mpdus_failed + 1; + } + else { + /* We failed all of them */ + rate->count = tx_done->mpdus_failed; + } } else { rate->count = 1; @@ -134,6 +140,18 @@ static void ath10k_set_tx_rate_status(struct ath10k *ar, rate->flags |= IEEE80211_TX_RC_SHORT_GI; } +#if 0 +static const char* tx_done_state_str(int i) { + switch (i) { + case HTT_TX_COMPL_STATE_NONE: return "NONE"; + case HTT_TX_COMPL_STATE_ACK: return "ACK"; + case HTT_TX_COMPL_STATE_NOACK: return "NOACK"; + case HTT_TX_COMPL_STATE_DISCARD: return "DISCARD"; + default: return "UNKNOWN"; + } +} +#endif + int ath10k_txrx_tx_unref(struct ath10k_htt *htt, const struct htt_tx_done *tx_done) { @@ -165,6 +183,17 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt, return -ENOENT; } + /*ath10k_warn(ar, + "tx_unref, msdu_id: %d len: %d tx-rate-code: 0x%x tx-rate-flags: 0x%x tried: %d failed: %d ack-rssi: %d status: %d (%s)\n", + tx_done->msdu_id, + msdu->len, + tx_done->tx_rate_code, + tx_done->tx_rate_flags, + tx_done->mpdus_tried, + tx_done->mpdus_failed, + tx_done->ack_rssi, + tx_done->status, tx_done_state_str(tx_done->status));*/ + skb_cb = ATH10K_SKB_CB(msdu); txq = skb_cb->txq; diff --git a/ath10k-4.20/htt_rx.c b/ath10k-4.20/htt_rx.c index 8e35cd3..7ad2fe0 100644 --- a/ath10k-4.20/htt_rx.c +++ b/ath10k-4.20/htt_rx.c @@ -2189,13 +2189,19 @@ static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar, tx_done.mpdus_failed = retries_info >> 8; } } - /* ath10k_warn(ar, - "htt tx completion-w2, msdu_id: %d tx-rate-code: 0x%x tx-rate-flags: 0x%x tried: %d failed: %d\n", + /*ath10k_warn(ar, + "htt tx completion-w2, msdu_id: %d tx-rate-code: 0x%x tx-rate-flags: 0x%x tried: %d failed: %d ack-rssi: %d\n", tx_done.msdu_id, tx_done.tx_rate_code, tx_done.tx_rate_flags, tx_done.mpdus_tried, - tx_done.mpdus_failed);*/ + tx_done.mpdus_failed, + tx_done.ack_rssi);*/ + + /* Firmware reports garbage for ack-rssi if packet was not acked. */ + if (unlikely(tx_done.status != HTT_TX_COMPL_STATE_ACK)) + tx_done.ack_rssi = 0; + ath10k_txrx_tx_unref(htt, &tx_done); } } else { diff --git a/ath10k-4.20/txrx.c b/ath10k-4.20/txrx.c index 13a2817..53b07e5 100644 --- a/ath10k-4.20/txrx.c +++ b/ath10k-4.20/txrx.c @@ -73,8 +73,14 @@ static void ath10k_set_tx_rate_status(struct ath10k *ar, ch = ar->rx_channel; if (tx_done->mpdus_failed) { - /* Maybe there is a better way to report this tried vs failed stat up the stack? */ - rate->count = tx_done->mpdus_failed + 1; + if (tx_done->status == HTT_TX_COMPL_STATE_ACK) { + /* We failed some, but then succeeded (+1) */ + rate->count = tx_done->mpdus_failed + 1; + } + else { + /* We failed all of them */ + rate->count = tx_done->mpdus_failed; + } } else { rate->count = 1; @@ -134,6 +140,18 @@ static void ath10k_set_tx_rate_status(struct ath10k *ar, rate->flags |= IEEE80211_TX_RC_SHORT_GI; } +#if 0 +static const char* tx_done_state_str(int i) { + switch (i) { + case HTT_TX_COMPL_STATE_NONE: return "NONE"; + case HTT_TX_COMPL_STATE_ACK: return "ACK"; + case HTT_TX_COMPL_STATE_NOACK: return "NOACK"; + case HTT_TX_COMPL_STATE_DISCARD: return "DISCARD"; + default: return "UNKNOWN"; + } +} +#endif + int ath10k_txrx_tx_unref(struct ath10k_htt *htt, const struct htt_tx_done *tx_done) { @@ -165,6 +183,17 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt, return -ENOENT; } + /*ath10k_warn(ar, + "tx_unref, msdu_id: %d len: %d tx-rate-code: 0x%x tx-rate-flags: 0x%x tried: %d failed: %d ack-rssi: %d status: %d (%s)\n", + tx_done->msdu_id, + msdu->len, + tx_done->tx_rate_code, + tx_done->tx_rate_flags, + tx_done->mpdus_tried, + tx_done->mpdus_failed, + tx_done->ack_rssi, + tx_done->status, tx_done_state_str(tx_done->status));*/ + skb_cb = ATH10K_SKB_CB(msdu); txq = skb_cb->txq;