mirror of
https://github.com/outbackdingo/mt76.git
synced 2026-10-24 13:26:48 +00:00
mt76: convert from tx tasklet to tx worker thread
This should improve performance by allowing the scheduler to move the tx scheduling work to idle CPUs Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
@@ -606,6 +606,7 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
mt76_worker_disable(&dev->tx_worker);
|
||||
netif_napi_del(&dev->tx_napi);
|
||||
for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++)
|
||||
mt76_dma_tx_cleanup(dev, i, true);
|
||||
|
||||
+11
-3
@@ -2,6 +2,7 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Felix Fietkau <[email protected]>
|
||||
*/
|
||||
#include <uapi/linux/sched/types.h>
|
||||
#include <linux/of.h>
|
||||
#include "mt76.h"
|
||||
|
||||
@@ -442,8 +443,6 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
|
||||
for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++)
|
||||
skb_queue_head_init(&dev->rx_skb[i]);
|
||||
|
||||
tasklet_init(&dev->tx_tasklet, mt76_tx_tasklet, (unsigned long)dev);
|
||||
|
||||
dev->wq = alloc_ordered_workqueue("mt76", 0);
|
||||
if (!dev->wq) {
|
||||
ieee80211_free_hw(hw);
|
||||
@@ -457,6 +456,7 @@ EXPORT_SYMBOL_GPL(mt76_alloc_device);
|
||||
int mt76_register_device(struct mt76_dev *dev, bool vht,
|
||||
struct ieee80211_rate *rates, int n_rates)
|
||||
{
|
||||
struct sched_param sparam = {.sched_priority = 1};
|
||||
struct ieee80211_hw *hw = dev->hw;
|
||||
struct mt76_phy *phy = &dev->phy;
|
||||
int ret;
|
||||
@@ -486,7 +486,14 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ieee80211_register_hw(hw);
|
||||
ret = ieee80211_register_hw(hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
WARN_ON(mt76_worker_setup(hw, &dev->tx_worker, mt76_tx_worker, "tx"));
|
||||
sched_setscheduler(dev->tx_worker.task, SCHED_FIFO, &sparam);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_register_device);
|
||||
|
||||
@@ -503,6 +510,7 @@ EXPORT_SYMBOL_GPL(mt76_unregister_device);
|
||||
|
||||
void mt76_free_device(struct mt76_dev *dev)
|
||||
{
|
||||
mt76_worker_teardown(&dev->tx_worker);
|
||||
if (dev->wq) {
|
||||
destroy_workqueue(dev->wq);
|
||||
dev->wq = NULL;
|
||||
|
||||
@@ -610,7 +610,7 @@ struct mt76_dev {
|
||||
const struct mt76_queue_ops *queue_ops;
|
||||
int tx_dma_idx[4];
|
||||
|
||||
struct tasklet_struct tx_tasklet;
|
||||
struct mt76_worker tx_worker;
|
||||
struct napi_struct tx_napi;
|
||||
struct delayed_work mac_work;
|
||||
|
||||
@@ -920,7 +920,7 @@ void mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta,
|
||||
void mt76_tx_check_agg_ssn(struct ieee80211_sta *sta, struct sk_buff *skb);
|
||||
void mt76_txq_schedule(struct mt76_phy *phy, enum mt76_txq_id qid);
|
||||
void mt76_txq_schedule_all(struct mt76_phy *phy);
|
||||
void mt76_tx_tasklet(unsigned long data);
|
||||
void mt76_tx_worker(struct mt76_worker *w);
|
||||
void mt76_release_buffered_frames(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
u16 tids, int nframes,
|
||||
|
||||
+1
-2
@@ -165,7 +165,7 @@ static int mt7603_poll_tx(struct napi_struct *napi, int budget)
|
||||
|
||||
mt7603_mac_sta_poll(dev);
|
||||
|
||||
tasklet_schedule(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_schedule(&dev->mt76.tx_worker);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -249,6 +249,5 @@ void mt7603_dma_cleanup(struct mt7603_dev *dev)
|
||||
MT_WPDMA_GLO_CFG_RX_DMA_EN |
|
||||
MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE);
|
||||
|
||||
tasklet_kill(&dev->mt76.tx_tasklet);
|
||||
mt76_dma_cleanup(&dev->mt76);
|
||||
}
|
||||
|
||||
+2
-2
@@ -1405,7 +1405,7 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev)
|
||||
/* lock/unlock all queues to ensure that no tx is pending */
|
||||
mt76_txq_schedule_all(&dev->mphy);
|
||||
|
||||
tasklet_disable(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_disable(&dev->mt76.tx_worker);
|
||||
tasklet_disable(&dev->mt76.pre_tbtt_tasklet);
|
||||
napi_disable(&dev->mt76.napi[0]);
|
||||
napi_disable(&dev->mt76.napi[1]);
|
||||
@@ -1454,7 +1454,7 @@ skip_dma_reset:
|
||||
clear_bit(MT76_RESET, &dev->mphy.state);
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
|
||||
tasklet_enable(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_enable(&dev->mt76.tx_worker);
|
||||
napi_enable(&dev->mt76.tx_napi);
|
||||
napi_schedule(&dev->mt76.tx_napi);
|
||||
|
||||
|
||||
+1
-2
@@ -118,7 +118,7 @@ static int mt7615_poll_tx(struct napi_struct *napi, int budget)
|
||||
mt7615_tx_cleanup(dev);
|
||||
|
||||
mt7615_pm_power_save_sched(dev);
|
||||
tasklet_schedule(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_schedule(&dev->mt76.tx_worker);
|
||||
|
||||
if (napi_complete_done(napi, 0))
|
||||
mt7615_irq_enable(dev, MT_INT_TX_DONE_ALL);
|
||||
@@ -324,6 +324,5 @@ void mt7615_dma_cleanup(struct mt7615_dev *dev)
|
||||
MT_WPDMA_GLO_CFG_RX_DMA_EN);
|
||||
mt76_set(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_SW_RESET);
|
||||
|
||||
tasklet_kill(&dev->mt76.tx_tasklet);
|
||||
mt76_dma_cleanup(&dev->mt76);
|
||||
}
|
||||
|
||||
+4
-4
@@ -1447,7 +1447,7 @@ static void mt7615_mac_tx_free(struct mt7615_dev *dev, struct sk_buff *skb)
|
||||
rcu_read_unlock();
|
||||
|
||||
mt7615_pm_power_save_sched(dev);
|
||||
tasklet_schedule(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_schedule(&dev->mt76.tx_worker);
|
||||
}
|
||||
|
||||
void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
|
||||
@@ -1872,7 +1872,7 @@ void mt7615_pm_wake_work(struct work_struct *work)
|
||||
}
|
||||
spin_unlock_bh(&dev->pm.txq_lock);
|
||||
|
||||
tasklet_schedule(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_schedule(&dev->mt76.tx_worker);
|
||||
|
||||
out:
|
||||
ieee80211_wake_queues(mphy->hw);
|
||||
@@ -2114,7 +2114,7 @@ void mt7615_mac_reset_work(struct work_struct *work)
|
||||
if (ext_phy)
|
||||
mt76_txq_schedule_all(ext_phy);
|
||||
|
||||
tasklet_disable(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_disable(&dev->mt76.tx_worker);
|
||||
napi_disable(&dev->mt76.napi[0]);
|
||||
napi_disable(&dev->mt76.napi[1]);
|
||||
napi_disable(&dev->mt76.tx_napi);
|
||||
@@ -2135,7 +2135,7 @@ void mt7615_mac_reset_work(struct work_struct *work)
|
||||
clear_bit(MT76_MCU_RESET, &dev->mphy.state);
|
||||
clear_bit(MT76_RESET, &dev->mphy.state);
|
||||
|
||||
tasklet_enable(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_enable(&dev->mt76.tx_worker);
|
||||
napi_enable(&dev->mt76.tx_napi);
|
||||
napi_schedule(&dev->mt76.tx_napi);
|
||||
|
||||
|
||||
+1
-1
@@ -707,7 +707,7 @@ mt7615_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
|
||||
}
|
||||
|
||||
dev->pm.last_activity = jiffies;
|
||||
tasklet_schedule(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_schedule(&dev->mt76.tx_worker);
|
||||
}
|
||||
|
||||
static void mt7615_tx(struct ieee80211_hw *hw,
|
||||
|
||||
+2
-1
@@ -88,7 +88,7 @@ static int mt7615_pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
}
|
||||
|
||||
napi_disable(&mdev->tx_napi);
|
||||
tasklet_kill(&mdev->tx_tasklet);
|
||||
mt76_worker_disable(&mdev->tx_worker);
|
||||
|
||||
mt76_for_each_q_rx(mdev, i) {
|
||||
napi_disable(&mdev->napi[i]);
|
||||
@@ -162,6 +162,7 @@ static int mt7615_pci_resume(struct pci_dev *pdev)
|
||||
if (pdma_reset)
|
||||
dev_err(mdev->dev, "PDMA engine must be reinitialized\n");
|
||||
|
||||
mt76_worker_enable(&mdev->tx_worker);
|
||||
mt76_for_each_q_rx(mdev, i) {
|
||||
napi_enable(&mdev->napi[i]);
|
||||
napi_schedule(&mdev->napi[i]);
|
||||
|
||||
@@ -179,9 +179,7 @@ static int mt7663u_suspend(struct usb_interface *intf, pm_message_t state)
|
||||
}
|
||||
|
||||
mt76u_stop_rx(&dev->mt76);
|
||||
|
||||
mt76u_stop_tx(&dev->mt76);
|
||||
tasklet_kill(&dev->mt76.tx_tasklet);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -204,7 +204,7 @@ static void mt76x0e_cleanup(struct mt76x02_dev *dev)
|
||||
tasklet_disable(&dev->mt76.pre_tbtt_tasklet);
|
||||
mt76x0_chip_onoff(dev, false, false);
|
||||
mt76x0e_stop_hw(dev);
|
||||
mt76x02_dma_cleanup(dev);
|
||||
mt76_dma_cleanup(&dev->mt76);
|
||||
mt76x02_mcu_cleanup(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,5 @@ mt76x02_wait_for_wpdma(struct mt76_dev *dev, int timeout)
|
||||
|
||||
int mt76x02_dma_init(struct mt76x02_dev *dev);
|
||||
void mt76x02_dma_disable(struct mt76x02_dev *dev);
|
||||
void mt76x02_dma_cleanup(struct mt76x02_dev *dev);
|
||||
|
||||
#endif /* __MT76x02_DMA_H */
|
||||
|
||||
+8
-14
@@ -150,9 +150,11 @@ static void mt76x02_process_tx_status_fifo(struct mt76x02_dev *dev)
|
||||
mt76x02_send_tx_status(dev, &stat, &update);
|
||||
}
|
||||
|
||||
static void mt76x02_tx_tasklet(unsigned long data)
|
||||
static void mt76x02_tx_worker(struct mt76_worker *w)
|
||||
{
|
||||
struct mt76x02_dev *dev = (struct mt76x02_dev *)data;
|
||||
struct mt76x02_dev *dev;
|
||||
|
||||
dev = container_of(w, struct mt76x02_dev, mt76.tx_worker);
|
||||
|
||||
mt76x02_mac_poll_tx_status(dev, false);
|
||||
mt76x02_process_tx_status_fifo(dev);
|
||||
@@ -177,7 +179,7 @@ static int mt76x02_poll_tx(struct napi_struct *napi, int budget)
|
||||
for (i = MT_TXQ_MCU; i >= 0; i--)
|
||||
mt76_queue_tx_cleanup(dev, i, false);
|
||||
|
||||
tasklet_schedule(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_schedule(&dev->mt76.tx_worker);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -196,8 +198,7 @@ int mt76x02_dma_init(struct mt76x02_dev *dev)
|
||||
if (!status_fifo)
|
||||
return -ENOMEM;
|
||||
|
||||
tasklet_init(&dev->mt76.tx_tasklet, mt76x02_tx_tasklet,
|
||||
(unsigned long)dev);
|
||||
dev->mt76.tx_worker.fn = mt76x02_tx_worker;
|
||||
tasklet_init(&dev->mt76.pre_tbtt_tasklet, mt76x02_pre_tbtt_tasklet,
|
||||
(unsigned long)dev);
|
||||
|
||||
@@ -325,13 +326,6 @@ static void mt76x02_dma_enable(struct mt76x02_dev *dev)
|
||||
MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE);
|
||||
}
|
||||
|
||||
void mt76x02_dma_cleanup(struct mt76x02_dev *dev)
|
||||
{
|
||||
tasklet_kill(&dev->mt76.tx_tasklet);
|
||||
mt76_dma_cleanup(&dev->mt76);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x02_dma_cleanup);
|
||||
|
||||
void mt76x02_dma_disable(struct mt76x02_dev *dev)
|
||||
{
|
||||
u32 val = mt76_rr(dev, MT_WPDMA_GLO_CFG);
|
||||
@@ -449,7 +443,7 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)
|
||||
set_bit(MT76_RESET, &dev->mphy.state);
|
||||
|
||||
tasklet_disable(&dev->mt76.pre_tbtt_tasklet);
|
||||
tasklet_disable(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_disable(&dev->mt76.tx_worker);
|
||||
napi_disable(&dev->mt76.tx_napi);
|
||||
|
||||
mt76_for_each_q_rx(&dev->mt76, i) {
|
||||
@@ -506,7 +500,7 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)
|
||||
|
||||
clear_bit(MT76_RESET, &dev->mphy.state);
|
||||
|
||||
tasklet_enable(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_enable(&dev->mt76.tx_worker);
|
||||
napi_enable(&dev->mt76.tx_napi);
|
||||
napi_schedule(&dev->mt76.tx_napi);
|
||||
|
||||
|
||||
+2
-1
@@ -113,7 +113,7 @@ mt76x2e_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
|
||||
napi_disable(&mdev->tx_napi);
|
||||
tasklet_kill(&mdev->pre_tbtt_tasklet);
|
||||
tasklet_kill(&mdev->tx_tasklet);
|
||||
mt76_worker_disable(&mdev->tx_worker);
|
||||
|
||||
mt76_for_each_q_rx(mdev, i)
|
||||
napi_disable(&mdev->napi[i]);
|
||||
@@ -147,6 +147,7 @@ mt76x2e_resume(struct pci_dev *pdev)
|
||||
|
||||
pci_restore_state(pdev);
|
||||
|
||||
mt76_worker_enable(&mdev->tx_worker);
|
||||
mt76_for_each_q_rx(mdev, i) {
|
||||
napi_enable(&mdev->napi[i]);
|
||||
napi_schedule(&mdev->napi[i]);
|
||||
|
||||
+1
-1
@@ -283,7 +283,7 @@ void mt76x2_cleanup(struct mt76x02_dev *dev)
|
||||
tasklet_disable(&dev->dfs_pd.dfs_tasklet);
|
||||
tasklet_disable(&dev->mt76.pre_tbtt_tasklet);
|
||||
mt76x2_stop_hardware(dev);
|
||||
mt76x02_dma_cleanup(dev);
|
||||
mt76_dma_cleanup(&dev->mt76);
|
||||
mt76x02_mcu_cleanup(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -273,6 +273,5 @@ void mt7915_dma_cleanup(struct mt7915_dev *dev)
|
||||
MT_WFDMA0_RST_DMASHDL_ALL_RST |
|
||||
MT_WFDMA0_RST_LOGIC_RST);
|
||||
|
||||
tasklet_kill(&dev->mt76.tx_tasklet);
|
||||
mt76_dma_cleanup(&dev->mt76);
|
||||
}
|
||||
|
||||
+3
-3
@@ -1010,7 +1010,7 @@ void mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb)
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
mt7915_mac_sta_poll(dev);
|
||||
tasklet_schedule(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_schedule(&dev->mt76.tx_worker);
|
||||
}
|
||||
|
||||
void mt7915_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
|
||||
@@ -1283,7 +1283,7 @@ void mt7915_mac_reset_work(struct work_struct *work)
|
||||
if (ext_phy)
|
||||
mt76_txq_schedule_all(ext_phy);
|
||||
|
||||
tasklet_disable(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_disable(&dev->mt76.tx_worker);
|
||||
napi_disable(&dev->mt76.napi[0]);
|
||||
napi_disable(&dev->mt76.napi[1]);
|
||||
napi_disable(&dev->mt76.napi[2]);
|
||||
@@ -1303,7 +1303,7 @@ void mt7915_mac_reset_work(struct work_struct *work)
|
||||
clear_bit(MT76_MCU_RESET, &dev->mphy.state);
|
||||
clear_bit(MT76_RESET, &dev->mphy.state);
|
||||
|
||||
tasklet_enable(&dev->mt76.tx_tasklet);
|
||||
mt76_worker_enable(&dev->mt76.tx_worker);
|
||||
napi_enable(&dev->mt76.tx_napi);
|
||||
napi_schedule(&dev->mt76.tx_napi);
|
||||
|
||||
|
||||
+3
-3
@@ -160,7 +160,7 @@ mt76_testmode_tx_start(struct mt76_dev *dev)
|
||||
td->tx_queued = 0;
|
||||
td->tx_done = 0;
|
||||
td->tx_pending = td->tx_count;
|
||||
tasklet_schedule(&dev->tx_tasklet);
|
||||
mt76_worker_schedule(&dev->tx_worker);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -168,11 +168,11 @@ mt76_testmode_tx_stop(struct mt76_dev *dev)
|
||||
{
|
||||
struct mt76_testmode_data *td = &dev->test;
|
||||
|
||||
tasklet_disable(&dev->tx_tasklet);
|
||||
mt76_worker_disable(&dev->tx_worker);
|
||||
|
||||
td->tx_pending = 0;
|
||||
|
||||
tasklet_enable(&dev->tx_tasklet);
|
||||
mt76_worker_enable(&dev->tx_worker);
|
||||
|
||||
wait_event_timeout(dev->tx_wait, td->tx_done == td->tx_queued, 10 * HZ);
|
||||
|
||||
|
||||
@@ -576,9 +576,9 @@ void mt76_txq_schedule_all(struct mt76_phy *phy)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_txq_schedule_all);
|
||||
|
||||
void mt76_tx_tasklet(unsigned long data)
|
||||
void mt76_tx_worker(struct mt76_worker *w)
|
||||
{
|
||||
struct mt76_dev *dev = (struct mt76_dev *)data;
|
||||
struct mt76_dev *dev = container_of(w, struct mt76_dev, tx_worker);
|
||||
|
||||
mt76_txq_schedule_all(&dev->phy);
|
||||
if (dev->phy2)
|
||||
@@ -621,7 +621,7 @@ void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
|
||||
if (!test_bit(MT76_STATE_RUNNING, &phy->state))
|
||||
return;
|
||||
|
||||
tasklet_schedule(&dev->tx_tasklet);
|
||||
mt76_worker_schedule(&dev->tx_worker);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_wake_tx_queue);
|
||||
|
||||
|
||||
@@ -792,9 +792,9 @@ int mt76u_resume_rx(struct mt76_dev *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76u_resume_rx);
|
||||
|
||||
static void mt76u_tx_tasklet(unsigned long data)
|
||||
static void mt76u_tx_worker(struct mt76_worker *w)
|
||||
{
|
||||
struct mt76_dev *dev = (struct mt76_dev *)data;
|
||||
struct mt76_dev *dev = container_of(w, struct mt76_dev, tx_worker);
|
||||
struct mt76_queue_entry entry;
|
||||
struct mt76_sw_queue *sq;
|
||||
struct mt76_queue *q;
|
||||
@@ -882,7 +882,7 @@ static void mt76u_complete_tx(struct urb *urb)
|
||||
dev_err(dev->dev, "tx urb failed: %d\n", urb->status);
|
||||
e->done = true;
|
||||
|
||||
tasklet_schedule(&dev->tx_tasklet);
|
||||
mt76_worker_schedule(&dev->tx_worker);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1037,6 +1037,8 @@ void mt76u_stop_tx(struct mt76_dev *dev)
|
||||
struct mt76_queue *q;
|
||||
int i, j, ret;
|
||||
|
||||
mt76_worker_disable(&dev->tx_worker);
|
||||
|
||||
ret = wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(&dev->phy),
|
||||
HZ / 5);
|
||||
if (!ret) {
|
||||
@@ -1048,8 +1050,6 @@ void mt76u_stop_tx(struct mt76_dev *dev)
|
||||
usb_kill_urb(q->entry[j].urb);
|
||||
}
|
||||
|
||||
tasklet_kill(&dev->tx_tasklet);
|
||||
|
||||
/* On device removal we maight queue skb's, but mt76u_tx_kick()
|
||||
* will fail to submit urb, cleanup those skb's manually.
|
||||
*/
|
||||
@@ -1072,6 +1072,8 @@ void mt76u_stop_tx(struct mt76_dev *dev)
|
||||
cancel_work_sync(&dev->usb.stat_work);
|
||||
clear_bit(MT76_READING_STATS, &dev->phy.state);
|
||||
|
||||
mt76_worker_enable(&dev->tx_worker);
|
||||
|
||||
mt76_tx_status_check(dev, NULL, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76u_stop_tx);
|
||||
@@ -1121,8 +1123,8 @@ int mt76u_init(struct mt76_dev *dev,
|
||||
mt76u_ops.rmw = ext ? mt76u_rmw_ext : mt76u_rmw;
|
||||
mt76u_ops.write_copy = ext ? mt76u_copy_ext : mt76u_copy;
|
||||
|
||||
dev->tx_worker.fn = mt76u_tx_worker;
|
||||
tasklet_init(&usb->rx_tasklet, mt76u_rx_tasklet, (unsigned long)dev);
|
||||
tasklet_init(&dev->tx_tasklet, mt76u_tx_tasklet, (unsigned long)dev);
|
||||
INIT_WORK(&usb->stat_work, mt76u_tx_status_data);
|
||||
|
||||
usb->data_len = usb_maxpacket(udev, usb_sndctrlpipe(udev, 0), 1);
|
||||
|
||||
Reference in New Issue
Block a user