mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 13:26:48 +00:00
unify tx completion handling, allow a driver callback to clean up tx skbs
Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
@@ -123,13 +123,14 @@ mt76_dma_tx_cleanup_idx(struct mt76_dev *dev, struct mt76_queue *q, int idx,
|
||||
}
|
||||
|
||||
static void
|
||||
mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
|
||||
void (*done)(struct mt76_dev *dev, struct mt76_queue *q,
|
||||
struct mt76_queue_entry *e))
|
||||
mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
|
||||
{
|
||||
struct mt76_queue_entry entry;
|
||||
int last;
|
||||
|
||||
if (!q->ndesc)
|
||||
return;
|
||||
|
||||
spin_lock_bh(&q->lock);
|
||||
if (flush)
|
||||
last = -1;
|
||||
@@ -142,7 +143,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
|
||||
q->swq_queued--;
|
||||
|
||||
if (entry.skb)
|
||||
done(dev, q, &entry);
|
||||
dev->drv->tx_complete_skb(dev, q, &entry, flush);
|
||||
|
||||
if (entry.txwi)
|
||||
mt76_put_txwi(dev, entry.txwi);
|
||||
@@ -391,23 +392,12 @@ int mt76_dma_attach(struct mt76_dev *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_dma_attach);
|
||||
|
||||
static void
|
||||
mt76_tx_cleanup_entry(struct mt76_dev *dev, struct mt76_queue *q,
|
||||
struct mt76_queue_entry *e)
|
||||
{
|
||||
if (e->txwi)
|
||||
ieee80211_free_txskb(dev->hw, e->skb);
|
||||
else
|
||||
dev_kfree_skb_any(e->skb);
|
||||
}
|
||||
|
||||
void mt76_dma_cleanup(struct mt76_dev *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++)
|
||||
mt76_dma_tx_cleanup(dev, &dev->q_tx[i], true,
|
||||
mt76_tx_cleanup_entry);
|
||||
mt76_dma_tx_cleanup(dev, &dev->q_tx[i], true);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) {
|
||||
netif_napi_del(&dev->napi[i]);
|
||||
|
||||
@@ -107,9 +107,7 @@ struct mt76_queue_ops {
|
||||
void *(*dequeue)(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
|
||||
int *len, u32 *info, bool *more);
|
||||
|
||||
void (*tx_cleanup)(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
|
||||
void (*done)(struct mt76_dev *dev, struct mt76_queue *q,
|
||||
struct mt76_queue_entry *e));
|
||||
void (*tx_cleanup)(struct mt76_dev *dev, struct mt76_queue *q, bool flush);
|
||||
|
||||
void (*kick)(struct mt76_dev *dev, struct mt76_queue *q);
|
||||
};
|
||||
@@ -159,6 +157,9 @@ struct mt76_driver_ops {
|
||||
struct sk_buff *skb, struct mt76_wcid *wcid,
|
||||
struct ieee80211_sta *sta, u32 *tx_info);
|
||||
|
||||
void (*tx_complete_skb)(struct mt76_dev *dev, struct mt76_queue *q,
|
||||
struct mt76_queue_entry *e, bool flush);
|
||||
|
||||
void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q,
|
||||
struct sk_buff *skb);
|
||||
|
||||
|
||||
@@ -135,6 +135,9 @@ int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
struct sk_buff *skb, struct mt76_wcid *wcid,
|
||||
struct ieee80211_sta *sta, u32 *tx_info);
|
||||
|
||||
void mt7603_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
|
||||
struct mt76_queue_entry *e, bool flush);
|
||||
|
||||
void mt7603_queue_rx_skb(struct mt76_dev *dev, enum mt76_rxq_id q,
|
||||
struct sk_buff *skb);
|
||||
void mt7603_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q);
|
||||
|
||||
+1
-20
@@ -38,25 +38,6 @@ mt7603_tx_queue_mcu(struct mt7603_dev *dev, enum mt76_txq_id qid,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7603_tx_cleanup_entry(struct mt76_dev *mdev, struct mt76_queue *q,
|
||||
struct mt76_queue_entry *e)
|
||||
{
|
||||
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
|
||||
|
||||
(void) dev;
|
||||
if (e->txwi)
|
||||
ieee80211_free_txskb(mdev->hw, e->skb);
|
||||
else
|
||||
dev_kfree_skb_any(e->skb);
|
||||
}
|
||||
|
||||
static void
|
||||
mt7603_tx_cleanup(struct mt7603_dev *dev, struct mt76_queue *q, bool flush)
|
||||
{
|
||||
mt76_queue_tx_cleanup(dev, q, flush, mt7603_tx_cleanup_entry);
|
||||
}
|
||||
|
||||
static int
|
||||
mt7603_init_tx_queue(struct mt7603_dev *dev, struct mt76_queue *q,
|
||||
int idx, int n_desc)
|
||||
@@ -131,7 +112,7 @@ mt7603_tx_tasklet(unsigned long data)
|
||||
int i;
|
||||
|
||||
for (i = ARRAY_SIZE(dev->mt76.q_tx) - 1; i >= 0; i--)
|
||||
mt7603_tx_cleanup(dev, &dev->mt76.q_tx[i], false);
|
||||
mt76_queue_tx_cleanup(dev, &dev->mt76.q_tx[i], false);
|
||||
|
||||
mt7603_irq_enable(dev, MT_INT_TX_DONE_ALL);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ struct mt7603_dev *mt7603_alloc_device(struct device *pdev)
|
||||
static const struct mt76_driver_ops drv_ops = {
|
||||
.txwi_size = MT_TXD_SIZE,
|
||||
.tx_prepare_skb = mt7603_tx_prepare_skb,
|
||||
.tx_complete_skb = mt7603_tx_complete_skb,
|
||||
.rx_skb = mt7603_queue_rx_skb,
|
||||
.rx_poll_complete = mt7603_rx_poll_complete,
|
||||
};
|
||||
|
||||
@@ -491,6 +491,15 @@ out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
void mt7603_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
|
||||
struct mt76_queue_entry *e, bool flush)
|
||||
{
|
||||
if (e->txwi)
|
||||
ieee80211_free_txskb(mdev->hw, e->skb);
|
||||
else
|
||||
dev_kfree_skb_any(e->skb);
|
||||
}
|
||||
|
||||
void mt7603_mac_start(struct mt7603_dev *dev)
|
||||
{
|
||||
mt76_clear(dev, MT_WF_ARB_SCR, MT_WF_ARB_TX_DISABLE | MT_WF_ARB_RX_DISABLE);
|
||||
|
||||
@@ -209,6 +209,8 @@ void mt76x2_tx_complete(struct mt76x2_dev *dev, struct sk_buff *skb);
|
||||
int mt76x2_tx_prepare_skb(struct mt76_dev *dev, void *txwi_ptr,
|
||||
struct sk_buff *skb, struct mt76_wcid *wcid,
|
||||
struct ieee80211_sta *sta, u32 *tx_info);
|
||||
void mt76x2_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
|
||||
struct mt76_queue_entry *e, bool flush);
|
||||
|
||||
void mt76x2_pre_tbtt_tasklet(unsigned long data);
|
||||
|
||||
|
||||
+1
-23
@@ -44,28 +44,6 @@ mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mt76x2_tx_cleanup_entry(struct mt76_dev *mdev, struct mt76_queue *q,
|
||||
struct mt76_queue_entry *e)
|
||||
{
|
||||
struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
|
||||
|
||||
if (e->txwi) {
|
||||
mt76x2_mac_queue_txdone(dev, e->skb, &e->txwi->txwi);
|
||||
} else {
|
||||
dev_kfree_skb_any(e->skb);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mt76x2_tx_cleanup(struct mt76x2_dev *dev, struct mt76_queue *q, bool flush)
|
||||
{
|
||||
if (!q->desc)
|
||||
return;
|
||||
|
||||
mt76_queue_tx_cleanup(dev, q, flush, mt76x2_tx_cleanup_entry);
|
||||
}
|
||||
|
||||
static int
|
||||
mt76x2_init_tx_queue(struct mt76x2_dev *dev, struct mt76_queue *q,
|
||||
int idx, int n_desc)
|
||||
@@ -133,7 +111,7 @@ mt76x2_tx_tasklet(unsigned long data)
|
||||
mt76x2_mac_process_tx_status_fifo(dev);
|
||||
|
||||
for (i = ARRAY_SIZE(dev->mt76.q_tx) - 1; i >= 0; i--)
|
||||
mt76x2_tx_cleanup(dev, &dev->mt76.q_tx[i], false);
|
||||
mt76_queue_tx_cleanup(dev, &dev->mt76.q_tx[i], false);
|
||||
|
||||
mt76x2_mac_poll_tx_status(dev, false);
|
||||
mt76x2_irq_enable(dev, MT_INT_TX_DONE_ALL);
|
||||
|
||||
@@ -607,6 +607,7 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev)
|
||||
static const struct mt76_driver_ops drv_ops = {
|
||||
.txwi_size = sizeof(struct mt76x2_txwi),
|
||||
.tx_prepare_skb = mt76x2_tx_prepare_skb,
|
||||
.tx_complete_skb = mt76x2_tx_complete_skb,
|
||||
.rx_skb = mt76x2_queue_rx_skb,
|
||||
.rx_poll_complete = mt76x2_rx_poll_complete,
|
||||
};
|
||||
|
||||
+15
-2
@@ -446,8 +446,9 @@ void mt76x2_mac_poll_tx_status(struct mt76x2_dev *dev, bool irq)
|
||||
}
|
||||
}
|
||||
|
||||
void mt76x2_mac_queue_txdone(struct mt76x2_dev *dev, struct sk_buff *skb,
|
||||
void *txwi_ptr)
|
||||
static void
|
||||
mt76x2_mac_queue_txdone(struct mt76x2_dev *dev, struct sk_buff *skb,
|
||||
void *txwi_ptr)
|
||||
{
|
||||
struct mt76x2_tx_info *txi = mt76x2_skb_tx_info(skb);
|
||||
struct mt76x2_txwi *txwi = txwi_ptr;
|
||||
@@ -471,6 +472,18 @@ void mt76x2_mac_process_tx_status_fifo(struct mt76x2_dev *dev)
|
||||
mt76x2_send_tx_status(dev, &stat, &update);
|
||||
}
|
||||
|
||||
void mt76x2_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
|
||||
struct mt76_queue_entry *e, bool flush)
|
||||
{
|
||||
struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
|
||||
|
||||
if (e->txwi) {
|
||||
mt76x2_mac_queue_txdone(dev, e->skb, &e->txwi->txwi);
|
||||
} else {
|
||||
dev_kfree_skb_any(e->skb);
|
||||
}
|
||||
}
|
||||
|
||||
static enum mt76x2_cipher_type
|
||||
mt76x2_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data)
|
||||
{
|
||||
|
||||
@@ -176,9 +176,6 @@ int mt76x2_mac_skb_tx_overhead(struct mt76x2_dev *dev, struct sk_buff *skb);
|
||||
int mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 vif_idx, struct sk_buff *skb);
|
||||
void mt76x2_mac_set_beacon_enable(struct mt76x2_dev *dev, u8 vif_idx, bool val);
|
||||
|
||||
void mt76x2_mac_queue_txdone(struct mt76x2_dev *dev, struct sk_buff *skb,
|
||||
void *txwi_ptr);
|
||||
|
||||
void mt76x2_mac_poll_tx_status(struct mt76x2_dev *dev, bool irq);
|
||||
void mt76x2_mac_process_tx_status_fifo(struct mt76x2_dev *dev);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user