/* Note: TX retry reporting is a bit broken. * Retries are reported only once per AMPDU and often come a frame early * i.e. they are reported in the last status preceding the AMPDU. Apart * from the fact that it's hard to know the length of the AMPDU (which is * required to know to how many consecutive frames retries should be * applied), if status comes early on full FIFO it gets lost and retries * of the whole AMPDU become invisible. * As a work-around encode the desired rate in PKT_ID of TX descriptor * and based on that guess the retries (every rate is tried once). * Only downside here is that for MCS0 we have to rely solely on * transmission failures as no retries can ever be reported. * Not having to read EXT_FIFO has a nice effect of doubling the number * of reports which can be fetched. * Also the vendor driver never uses the EXT_FIFO register so it may be * undertested.
*/ static u8 mt7601u_tx_pktid_enc(struct mt7601u_dev *dev, u8 rate, bool is_probe)
{
u8 encoded = (rate + 1) + is_probe * 8;
/* Because PKT_ID 0 disables status reporting only 15 values are * available but 16 are needed (8 MCS * 2 for encoding is_probe) * - we need to cram together two rates. MCS0 and MCS7 with is_probe * share PKT_ID 9.
*/ if (is_probe && rate == 7) return encoded - 7;
val = FIELD_PREP(MT_EDCA_CFG_AIFSN, params->aifs) |
FIELD_PREP(MT_EDCA_CFG_CWMIN, cw_min) |
FIELD_PREP(MT_EDCA_CFG_CWMAX, cw_max); /* TODO: based on user-controlled EnableTxBurst var vendor drv sets * a really long txop on AC0 (see connect.c:2009) but only on * connect? When not connected should be 0.
*/ if (!hw_q)
val |= 0x60; else
val |= FIELD_PREP(MT_EDCA_CFG_TXOP, params->txop);
mt76_wr(dev, MT_EDCA_CFG_AC(hw_q), val);
val = mt76_rr(dev, MT_WMM_TXOP(hw_q));
val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(hw_q));
val |= params->txop << MT_WMM_TXOP_SHIFT(hw_q);
mt76_wr(dev, MT_WMM_TXOP(hw_q), val);
val = mt76_rr(dev, MT_WMM_AIFSN);
val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(hw_q));
val |= params->aifs << MT_WMM_AIFSN_SHIFT(hw_q);
mt76_wr(dev, MT_WMM_AIFSN, val);
val = mt76_rr(dev, MT_WMM_CWMIN);
val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(hw_q));
val |= cw_min << MT_WMM_CWMIN_SHIFT(hw_q);
mt76_wr(dev, MT_WMM_CWMIN, val);
val = mt76_rr(dev, MT_WMM_CWMAX);
val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(hw_q));
val |= cw_max << MT_WMM_CWMAX_SHIFT(hw_q);
mt76_wr(dev, MT_WMM_CWMAX, val);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.