diff --git a/dma.c b/dma.c index fbc20978..820b1368 100644 --- a/dma.c +++ b/dma.c @@ -358,6 +358,7 @@ mt76_dma_rx_poll(struct napi_struct *napi, int budget) napi_complete(napi); dev->drv->rx_poll_complete(dev, qid); } + mt76_rx_complete(dev, qid); return done; } @@ -372,6 +373,7 @@ mt76_dma_init(struct mt76_dev *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); + skb_queue_head_init(&dev->rx_skb[i]); napi_enable(&dev->napi[i]); } diff --git a/mac80211.c b/mac80211.c index 1beb4a7b..aabfbf2e 100644 --- a/mac80211.c +++ b/mac80211.c @@ -231,6 +231,14 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb) return; } - ieee80211_rx_napi(dev->hw, skb, &dev->napi[q]); + __skb_queue_tail(&dev->rx_skb[q], skb); } EXPORT_SYMBOL_GPL(mt76_rx); + +void mt76_rx_complete(struct mt76_dev *dev, enum mt76_rxq_id q) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(&dev->rx_skb[q])) != NULL) + ieee80211_rx_napi(dev->hw, skb, &dev->napi[q]); +} diff --git a/mt76.h b/mt76.h index 112b17c0..b995f192 100644 --- a/mt76.h +++ b/mt76.h @@ -177,6 +177,7 @@ struct mt76_dev { struct net_device napi_dev; struct napi_struct napi[__MT_RXQ_MAX]; + struct sk_buff_head rx_skb[__MT_RXQ_MAX]; struct list_head txwi_cache; struct mt76_queue q_tx[__MT_TXQ_MAX]; @@ -282,5 +283,6 @@ void mt76_release_buffered_frames(struct ieee80211_hw *hw, /* internal */ void mt76_tx_free(struct mt76_dev *dev); void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); +void mt76_rx_complete(struct mt76_dev *dev, enum mt76_rxq_id q); #endif