diff --git a/dma.c b/dma.c index 0db35fdb..f8ca17fa 100644 --- a/dma.c +++ b/dma.c @@ -236,17 +236,6 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q) spin_unlock_bh(&q->lock); } -static int -mt76_dma_init(struct mt76_dev *dev) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) - mt76_dma_rx_fill(dev, &dev->q_rx[i], false); - - return 0; -} - static void mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data, int len, bool more) @@ -272,7 +261,6 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget) unsigned char *data; int len; int done = 0; - bool napi = q == &dev->q_rx[MT_RXQ_MAIN]; bool more; while (done < budget) { @@ -315,17 +303,50 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget) dev->drv->rx_skb(dev, q - dev->q_rx, skb); } - mt76_dma_rx_fill(dev, q, napi); + mt76_dma_rx_fill(dev, q, true); return done; } +static int +mt76_dma_rx_poll(struct napi_struct *napi, int budget) +{ + struct mt76_dev *dev; + int qid, done; + + dev = container_of(napi->dev, struct mt76_dev, napi_dev); + qid = napi - dev->napi; + + done = mt76_dma_rx_process(dev, &dev->q_rx[qid], budget); + if (done < budget) { + napi_complete(napi); + dev->drv->rx_poll_complete(dev, qid); + } + + return done; +} + +static int +mt76_dma_init(struct mt76_dev *dev) +{ + int i; + + init_dummy_netdev(&dev->napi_dev); + + for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) { + netif_napi_add(&dev->napi_dev, &dev->napi[i], mt76_dma_rx_poll, 64); + mt76_dma_rx_fill(dev, &dev->q_rx[i], false); + napi_enable(&dev->napi[i]); + } + + return 0; +} + static const struct mt76_queue_ops mt76_dma_ops = { .init = mt76_dma_init, .alloc = mt76_dma_alloc_queue, .add_buf = mt76_dma_add_buf, .tx_cleanup = mt76_dma_tx_cleanup, .kick = mt76_dma_kick_queue, - .rx_process = mt76_dma_rx_process, }; int mt76_dma_attach(struct mt76_dev *dev) @@ -352,7 +373,10 @@ void mt76_dma_cleanup(struct mt76_dev *dev) for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++) mt76_dma_tx_cleanup(dev, &dev->q_tx[i], true, mt76_tx_cleanup_entry); - for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) + + for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) { + netif_napi_del(&dev->napi[i]); mt76_dma_rx_cleanup(dev, &dev->q_rx[i]); + } } EXPORT_SYMBOL_GPL(mt76_dma_cleanup); diff --git a/mt76.h b/mt76.h index f2fae9c2..38184ff1 100644 --- a/mt76.h +++ b/mt76.h @@ -105,8 +105,6 @@ struct mt76_queue_ops { void (*done)(struct mt76_dev *dev, struct mt76_queue *q, struct mt76_queue_entry *e)); - int (*rx_process)(struct mt76_dev *dev, struct mt76_queue *q, int budget); - void (*kick)(struct mt76_dev *dev, struct mt76_queue *q); }; @@ -159,6 +157,8 @@ struct mt76_driver_ops { void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb); + + void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q); }; struct mt76_dev { @@ -170,6 +170,9 @@ struct mt76_dev { void __iomem *regs; struct device *dev; + struct net_device napi_dev; + struct napi_struct napi[__MT_RXQ_MAX]; + struct list_head txwi_cache; struct mt76_queue q_tx[__MT_TXQ_MAX]; struct mt76_queue q_rx[__MT_RXQ_MAX]; @@ -234,7 +237,6 @@ static inline u16 mt76_rev(struct mt76_dev *dev) #define mt76_queue_alloc(dev, ...) (dev)->mt76.queue_ops->alloc(&((dev)->mt76), __VA_ARGS__) #define mt76_queue_add_buf(dev, ...) (dev)->mt76.queue_ops->add_buf(&((dev)->mt76), __VA_ARGS__) #define mt76_queue_tx_cleanup(dev, ...) (dev)->mt76.queue_ops->tx_cleanup(&((dev)->mt76), __VA_ARGS__) -#define mt76_queue_rx_process(dev, ...) (dev)->mt76.queue_ops->rx_process(&((dev)->mt76), __VA_ARGS__) #define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__) int mt76_register_device(struct mt76_dev *dev, bool vht, diff --git a/mt7603.h b/mt7603.h index dc16f133..d2ff8ee3 100644 --- a/mt7603.h +++ b/mt7603.h @@ -84,11 +84,7 @@ struct mt7603_dev { struct mt7603_mcu mcu; struct mt76_queue q_rx; - struct net_device napi_dev; - struct napi_struct napi; - struct tasklet_struct tx_tasklet; - struct tasklet_struct rx_tasklet; struct tasklet_struct pre_tbtt_tasklet; }; @@ -145,5 +141,6 @@ int mt7603_mac_write_txwi(struct mt76_dev *mdev, void *txwi_ptr, 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); #endif diff --git a/mt7603_core.c b/mt7603_core.c index 76e8093e..e0257c44 100644 --- a/mt7603_core.c +++ b/mt7603_core.c @@ -25,6 +25,12 @@ void mt7603_set_irq_mask(struct mt7603_dev *dev, u32 clear, u32 set) spin_unlock_irqrestore(&dev->irq_lock, flags); } +void mt7603_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q) +{ + struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76); + mt7603_irq_enable(dev, MT_INT_RX_DONE(q)); +} + irqreturn_t mt7603_irq_handler(int irq, void *dev_instance) { struct mt7603_dev *dev = dev_instance; @@ -45,12 +51,12 @@ irqreturn_t mt7603_irq_handler(int irq, void *dev_instance) if (intr & MT_INT_RX_DONE(0)) { mt7603_irq_disable(dev, MT_INT_RX_DONE(0)); - napi_schedule(&dev->napi); + napi_schedule(&dev->mt76.napi[0]); } if (intr & MT_INT_RX_DONE(1)) { mt7603_irq_disable(dev, MT_INT_RX_DONE(1)); - tasklet_schedule(&dev->rx_tasklet); + napi_schedule(&dev->mt76.napi[1]); } #if 0 diff --git a/mt7603_dma.c b/mt7603_dma.c index 2b8da2b3..e6f7a51e 100644 --- a/mt7603_dma.c +++ b/mt7603_dma.c @@ -155,32 +155,6 @@ mt7603_tx_tasklet(unsigned long data) mt7603_irq_enable(dev, MT_INT_TX_DONE_ALL); } -static int -mt7603_dma_rx_poll(struct napi_struct *napi, int budget) -{ - struct mt7603_dev *dev = container_of(napi, struct mt7603_dev, napi); - int done; - - done = mt76_queue_rx_process(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], budget); - - if (done < budget) { - napi_complete(napi); - mt7603_irq_enable(dev, MT_INT_RX_DONE(0)); - } - - return done; -} - -static void -mt7603_rx_tasklet(unsigned long data) -{ - struct mt7603_dev *dev = (struct mt7603_dev *) data; - struct mt76_queue *q = &dev->mt76.q_rx[MT_RXQ_MCU]; - - mt76_queue_rx_process(dev, q, q->ndesc); - mt7603_irq_enable(dev, MT_INT_RX_DONE(1)); -} - int mt7603_dma_init(struct mt7603_dev *dev) { static const u8 wmm_queue_map[] = { @@ -197,12 +171,7 @@ int mt7603_dma_init(struct mt7603_dev *dev) init_waitqueue_head(&dev->mcu.wait); skb_queue_head_init(&dev->mcu.res_q); - init_dummy_netdev(&dev->napi_dev); - netif_napi_add(&dev->napi_dev, &dev->napi, mt7603_dma_rx_poll, 64); - napi_enable(&dev->napi); - tasklet_init(&dev->tx_tasklet, mt7603_tx_tasklet, (unsigned long) dev); - tasklet_init(&dev->rx_tasklet, mt7603_rx_tasklet, (unsigned long) dev); mt76_clear(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_EN | @@ -261,6 +230,5 @@ void mt7603_dma_cleanup(struct mt7603_dev *dev) MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE); tasklet_kill(&dev->tx_tasklet); - tasklet_kill(&dev->rx_tasklet); mt76_dma_cleanup(&dev->mt76); } diff --git a/mt7603_init.c b/mt7603_init.c index 88c7dcfe..3ffb5a57 100644 --- a/mt7603_init.c +++ b/mt7603_init.c @@ -22,6 +22,7 @@ struct mt7603_dev *mt7603_alloc_device(struct device *pdev) .fill_txwi = mt7603_mac_write_txwi, .tx_queue_skb = mt7603_tx_queue_skb, .rx_skb = mt7603_queue_rx_skb, + .rx_poll_complete = mt7603_rx_poll_complete, }; struct ieee80211_hw *hw; struct mt7603_dev *dev; diff --git a/mt76x2.h b/mt76x2.h index 1347b39a..f77d8449 100644 --- a/mt76x2.h +++ b/mt76x2.h @@ -105,11 +105,7 @@ struct mt76x2_dev { struct mt76x2_mcu mcu; struct sk_buff *rx_head; - struct net_device napi_dev; - struct napi_struct napi; - struct tasklet_struct tx_tasklet; - struct tasklet_struct rx_tasklet; struct tasklet_struct pre_tbtt_tasklet; struct delayed_work cal_work; struct delayed_work mac_work; @@ -227,6 +223,8 @@ void mt76x2_pre_tbtt_tasklet(unsigned long data); void mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq); + +void mt76x2_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q); void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, struct sk_buff *skb); diff --git a/mt76x2_core.c b/mt76x2_core.c index 9274cac5..7c0bf2d5 100644 --- a/mt76x2_core.c +++ b/mt76x2_core.c @@ -36,6 +36,12 @@ void mt76x2_set_irq_mask(struct mt76x2_dev *dev, u32 clear, u32 set) spin_unlock_irqrestore(&dev->irq_lock, flags); } +void mt76x2_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q) +{ + struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76); + mt76x2_irq_enable(dev, MT_INT_RX_DONE(q)); +} + irqreturn_t mt76x2_irq_handler(int irq, void *dev_instance) { struct mt76x2_dev *dev = dev_instance; @@ -58,12 +64,12 @@ irqreturn_t mt76x2_irq_handler(int irq, void *dev_instance) if (intr & MT_INT_RX_DONE(0)) { mt76x2_irq_disable(dev, MT_INT_RX_DONE(0)); - napi_schedule(&dev->napi); + napi_schedule(&dev->mt76.napi[0]); } if (intr & MT_INT_RX_DONE(1)) { mt76x2_irq_disable(dev, MT_INT_RX_DONE(1)); - tasklet_schedule(&dev->rx_tasklet); + napi_schedule(&dev->mt76.napi[1]); } if (intr & MT_INT_PRE_TBTT) diff --git a/mt76x2_dma.c b/mt76x2_dma.c index 1a56a4ad..95d47aa2 100644 --- a/mt76x2_dma.c +++ b/mt76x2_dma.c @@ -177,33 +177,6 @@ mt76x2_tx_tasklet(unsigned long data) mt76x2_irq_enable(dev, MT_INT_TX_DONE_ALL); } -static int -mt76x2_dma_rx_poll(struct napi_struct *napi, int budget) -{ - struct mt76x2_dev *dev = container_of(napi, struct mt76x2_dev, napi); - int done; - - done = mt76_queue_rx_process(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], budget); - - if (done < budget) { - napi_complete(napi); - mt76x2_irq_enable(dev, MT_INT_RX_DONE(0)); - } - - return done; -} - -static void -mt76x2_rx_tasklet(unsigned long data) -{ - struct mt76x2_dev *dev = (struct mt76x2_dev *) data; - struct mt76_queue *q = &dev->mt76.q_rx[MT_RXQ_MCU]; - - mt76_queue_rx_process(dev, q, q->ndesc); - - mt76x2_irq_enable(dev, MT_INT_RX_DONE(1)); -} - int mt76x2_dma_init(struct mt76x2_dev *dev) { static const u8 wmm_queue_map[] = { @@ -225,11 +198,7 @@ int mt76x2_dma_init(struct mt76x2_dev *dev) init_waitqueue_head(&dev->mcu.wait); skb_queue_head_init(&dev->mcu.res_q); - init_dummy_netdev(&dev->napi_dev); - netif_napi_add(&dev->napi_dev, &dev->napi, mt76x2_dma_rx_poll, 64); - tasklet_init(&dev->tx_tasklet, mt76x2_tx_tasklet, (unsigned long) dev); - tasklet_init(&dev->rx_tasklet, mt76x2_rx_tasklet, (unsigned long) dev); mt76_wr(dev, MT_WPDMA_RST_IDX, ~0); @@ -268,6 +237,5 @@ int mt76x2_dma_init(struct mt76x2_dev *dev) void mt76x2_dma_cleanup(struct mt76x2_dev *dev) { tasklet_kill(&dev->tx_tasklet); - tasklet_kill(&dev->rx_tasklet); mt76_dma_cleanup(&dev->mt76); } diff --git a/mt76x2_init.c b/mt76x2_init.c index b160e4e9..00e785a0 100644 --- a/mt76x2_init.c +++ b/mt76x2_init.c @@ -592,6 +592,7 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev) .fill_txwi = mt76x2_mac_write_txwi, .tx_queue_skb = mt76x2_tx_queue_skb, .rx_skb = mt76x2_queue_rx_skb, + .rx_poll_complete = mt76x2_rx_poll_complete, }; struct ieee80211_hw *hw; struct mt76x2_dev *dev; diff --git a/mt76x2_main.c b/mt76x2_main.c index 9ae94156..81e9a454 100644 --- a/mt76x2_main.c +++ b/mt76x2_main.c @@ -31,7 +31,6 @@ mt76x2_start(struct ieee80211_hw *hw) ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work, MT_CALIBRATE_INTERVAL); - napi_enable(&dev->napi); set_bit(MT76_STATE_RUNNING, &dev->mt76.state); @@ -46,7 +45,6 @@ mt76x2_stop(struct ieee80211_hw *hw) struct mt76x2_dev *dev = hw->priv; mutex_lock(&dev->mutex); - napi_disable(&dev->napi); clear_bit(MT76_STATE_RUNNING, &dev->mt76.state); mt76x2_stop_hardware(dev); mutex_unlock(&dev->mutex);