diff --git a/dma.c b/dma.c index 8d91a8ef..7220b91a 100644 --- a/dma.c +++ b/dma.c @@ -175,7 +175,7 @@ mt76_dma_kick_queue(struct mt76_dev *dev, struct mt76_queue *q) } static int -mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) +mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q, bool napi) { dma_addr_t addr; void *buf; @@ -183,17 +183,23 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) int len = SKB_WITH_OVERHEAD(q->buf_size); int offset = q->buf_offset; int idx; + void *(*alloc)(unsigned int fragsz); + + if (napi) + alloc = napi_alloc_frag; + else + alloc = netdev_alloc_frag; spin_lock_bh(&q->lock); while (q->queued < q->ndesc - 1) { - buf = kzalloc(q->buf_size, GFP_ATOMIC); + buf = alloc(q->buf_size); if (!buf) break; addr = dma_map_single(dev->dev, buf, len, DMA_FROM_DEVICE); if (dma_mapping_error(dev->dev, addr)) { - kfree(buf); + skb_free_frag(buf); break; } diff --git a/mt76.h b/mt76.h index 75320ac0..2a8cd5ab 100644 --- a/mt76.h +++ b/mt76.h @@ -96,7 +96,7 @@ struct mt76_queue_ops { void (*done)(struct mt76_dev *dev, struct mt76_queue *q, struct mt76_queue_entry *e)); - int (*rx_fill)(struct mt76_dev *dev, struct mt76_queue *q); + int (*rx_fill)(struct mt76_dev *dev, struct mt76_queue *q, bool napi); void (*kick)(struct mt76_dev *dev, struct mt76_queue *q); }; diff --git a/mt7603_dma.c b/mt7603_dma.c index c0e84a81..86490e15 100644 --- a/mt7603_dma.c +++ b/mt7603_dma.c @@ -78,7 +78,7 @@ mt7603_rx_cleanup(struct mt7603_dev *dev, struct mt76_queue *q) if (!buf) break; - kfree(buf); + skb_free_frag(buf); } while (1); spin_unlock_bh(&q->lock); } @@ -145,9 +145,9 @@ mt7603_process_rx_queue(struct mt7603_dev *dev, struct mt76_queue *q, int budget if (!data) break; - skb = build_skb(data, 0); + skb = build_skb(data, q->buf_size); if (!skb) { - kfree(data); + skb_free_frag(data); continue; } @@ -161,7 +161,7 @@ mt7603_process_rx_queue(struct mt7603_dev *dev, struct mt76_queue *q, int budget done++; } - mt76_queue_rx_fill(dev, q); + mt76_queue_rx_fill(dev, q, true); return done; } @@ -289,8 +289,8 @@ int mt7603_dma_init(struct mt7603_dev *dev) if (ret) return ret; - mt76_queue_rx_fill(dev, &dev->q_rx); - mt76_queue_rx_fill(dev, &dev->mcu.q_rx); + mt76_queue_rx_fill(dev, &dev->q_rx, false); + mt76_queue_rx_fill(dev, &dev->mcu.q_rx, false); mt76_wr(dev, MT_DELAY_INT_CFG, 0); diff --git a/mt76x2_dma.c b/mt76x2_dma.c index a7275ea8..d62ec2ad 100644 --- a/mt76x2_dma.c +++ b/mt76x2_dma.c @@ -106,7 +106,7 @@ mt76x2_rx_cleanup(struct mt76x2_dev *dev, struct mt76_queue *q) if (!buf) break; - kfree(buf); + skb_free_frag(buf); } while (1); spin_unlock_bh(&q->lock); } @@ -181,9 +181,9 @@ mt76x2_process_rx_queue(struct mt76x2_dev *dev, struct mt76_queue *q, int budget if (!data) break; - skb = build_skb(data, 0); + skb = build_skb(data, q->buf_size); if (!skb) { - kfree(data); + skb_free_frag(data); continue; } @@ -198,7 +198,7 @@ mt76x2_process_rx_queue(struct mt76x2_dev *dev, struct mt76_queue *q, int budget done++; } - mt76_queue_rx_fill(dev, q); + mt76_queue_rx_fill(dev, q, true); return done; } @@ -320,8 +320,8 @@ int mt76x2_dma_init(struct mt76x2_dev *dev) if (ret) return ret; - mt76_queue_rx_fill(dev, &dev->q_rx); - mt76_queue_rx_fill(dev, &dev->mcu.q_rx); + mt76_queue_rx_fill(dev, &dev->q_rx, false); + mt76_queue_rx_fill(dev, &dev->mcu.q_rx, false); return 0; }