mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 13:26:48 +00:00
mt76: add support for reporting tx status with skb
MT76x2/MT76x0 has somewhat unreliable tx status reporting, and for that reason the driver currently does not report per-skb tx ack status at all. This breaks things like client idle polling, which relies on the tx ack status of a transmitted nullfunc frame. This patch adds code to report skb-attached tx status if requested by mac80211 or the rate control module. Since tx status is polled from a simple FIFO register, the code needs to account for the possibility of tx status events getting lost. The code keeps a list of skbs for which tx status is required and passes them to mac80211 once tx status has been filled in and the DMA queue is done with it. If a tx status event is not received after one second, the status rates are cleared, and a succesful ACK is indicated to avoid spurious disassoc during assoc or client polling. Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
+7
-18
@@ -140,21 +140,6 @@ void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev *dev, s8 txpwr)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x02_tx_set_txpwr_auto);
|
||||
|
||||
void mt76x02_tx_complete(struct mt76_dev *dev, struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
if (info->flags & IEEE80211_TX_CTL_AMPDU) {
|
||||
ieee80211_free_txskb(dev->hw, skb);
|
||||
} else {
|
||||
ieee80211_tx_info_clear_status(info);
|
||||
info->status.rates[0].idx = -1;
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
ieee80211_tx_status(dev->hw, skb);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x02_tx_complete);
|
||||
|
||||
bool mt76x02_tx_status_data(struct mt76_dev *mdev, u8 *update)
|
||||
{
|
||||
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
|
||||
@@ -169,14 +154,15 @@ bool mt76x02_tx_status_data(struct mt76_dev *mdev, u8 *update)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x02_tx_status_data);
|
||||
|
||||
int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
|
||||
int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
struct sk_buff *skb, struct mt76_queue *q,
|
||||
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
|
||||
u32 *tx_info)
|
||||
{
|
||||
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct mt76x02_txwi *txwi = txwi_ptr;
|
||||
int qsel = MT_QSEL_EDCA;
|
||||
int pid;
|
||||
int ret;
|
||||
|
||||
if (q == &dev->mt76.q_tx[MT_TXQ_PSD] && wcid && wcid->idx < 128)
|
||||
@@ -184,11 +170,14 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
|
||||
|
||||
mt76x02_mac_write_txwi(dev, txwi, skb, wcid, sta, skb->len);
|
||||
|
||||
pid = mt76_tx_status_skb_add(mdev, wcid, skb);
|
||||
txwi->pktid = pid;
|
||||
|
||||
ret = mt76x02_insert_hdr_pad(skb);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
|
||||
if (pid && pid != MT_PACKET_ID_NO_ACK)
|
||||
qsel = MT_QSEL_MGMT;
|
||||
|
||||
*tx_info = FIELD_PREP(MT_TXD_INFO_QSEL, qsel) |
|
||||
|
||||
Reference in New Issue
Block a user