From eeebc4cbd0fb6d16e10c40a7366e3f0ae47b5578 Mon Sep 17 00:00:00 2001 From: pigworlds Date: Sat, 26 Dec 2020 06:23:53 -0800 Subject: [PATCH] Fix mira_node statistics in driver (#466) The itlwm driver uses MiRA algorithm to control the tx rate (upload). There is a bit disconnect between what the MiRA rate adaption statistics wants and what the iwm/iwn driver passed. Note, the iwx driver uses firmware based RA and do not use MiRA. In the mira formula, txfail mean the whole single frame or the whole AMPDU frame get lost. The driver deduce the number of txfail from the number of missing ACKs in BA. This looks wrong to me that a temporary sub-frame lost in the ACK would count as whole frame lost. Counting on the number of retries is sufficient to calculate in the mira formula. Also in mira formula, it calculate ampdu_size * agglen to count the number of bytes transmitted. The ampdu_size should be the average of each sub-frame ampdu size, rather than the total ampdu size of all sub-frames. In the AMPDU code for iwm, there was an early return on iwm_rx_tx_cmd when frame count more than 1. This seems unnecessary and would affect mira statistics collection. --- itlwm/hal_iwm/mac80211.cpp | 19 +++---------------- itlwm/hal_iwn/ItlIwn.cpp | 7 +++---- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/itlwm/hal_iwm/mac80211.cpp b/itlwm/hal_iwm/mac80211.cpp index ac73a028f..299e1d834 100644 --- a/itlwm/hal_iwm/mac80211.cpp +++ b/itlwm/hal_iwm/mac80211.cpp @@ -773,9 +773,9 @@ iwm_ampdu_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni, (SEQ_LT(ba->ba_winend, s) || (ba->ba_bitmap & (1 << bit)) == 0)) { have_ack++; - wn->in_mn.frames = txdata->ampdu_nframes; - wn->in_mn.agglen = txdata->ampdu_nframes; - wn->in_mn.ampdu_size = txdata->ampdu_size; + wn->in_mn.frames++; + wn->in_mn.agglen++; + wn->in_mn.ampdu_size = txdata->ampdu_size / txdata->ampdu_nframes; if (txdata->retries > 1) wn->in_mn.retries++; if (!SEQ_LT(ba->ba_winend, s)) @@ -788,7 +788,6 @@ iwm_ampdu_rate_control(struct iwm_softc *sc, struct ieee80211_node *ni, } if (have_ack > 0) { - wn->in_mn.txfail = wn->in_mn.frames - have_ack; iwm_mira_choose(sc, ni); } } @@ -1157,18 +1156,6 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt, le16_to_cpu((&tx_resp->status)[i].idx))); } - /* - * In the multi-frame case the firmware has just transmitted a bunch - * of frames in an A-MPDU. The final Tx status of those frames won't - * be known until the peer ACKs subframes with a block ack or firmware - * gives up on a particular subframe. - * Subframes for which the firmware never sees an ACK will be retried - * and will eventually arrive here as a single-frame Tx failure. - * So there is nothing to do, for now. - */ - if (tx_resp->frame_count != 1) - return; - txd = &ring->data[idx]; if (txd->m == NULL) return; diff --git a/itlwm/hal_iwn/ItlIwn.cpp b/itlwm/hal_iwn/ItlIwn.cpp index 6f49d165c..fd3c96d9f 100644 --- a/itlwm/hal_iwn/ItlIwn.cpp +++ b/itlwm/hal_iwn/ItlIwn.cpp @@ -2347,9 +2347,9 @@ iwn_ampdu_rate_control(struct iwn_softc *sc, struct ieee80211_node *ni, (SEQ_LT(ba->ba_winend, s) || (ba->ba_bitmap & (1 << bit)) == 0)) { have_ack++; - wn->mn.frames = txdata->ampdu_nframes; - wn->mn.agglen = txdata->ampdu_nframes; - wn->mn.ampdu_size = txdata->ampdu_size; + wn->mn.frames++; + wn->mn.agglen++; + wn->mn.ampdu_size = txdata->ampdu_size / txdata->ampdu_nframes; if (txdata->retries > 1) wn->mn.retries++; if (!SEQ_LT(ba->ba_winend, s)) @@ -2362,7 +2362,6 @@ iwn_ampdu_rate_control(struct iwn_softc *sc, struct ieee80211_node *ni, } if (have_ack > 0) { - wn->mn.txfail = wn->mn.frames - have_ack; iwn_mira_choose(sc, ni); } }