diff --git a/dma.c b/dma.c index ad2bb940..bcacb4c5 100644 --- a/dma.c +++ b/dma.c @@ -165,9 +165,46 @@ mt76_dma_kick_queue(struct mt76_dev *dev, struct mt76_queue *q) iowrite32(q->head, &q->regs->cpu_idx); } +static int +mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) +{ + dma_addr_t addr; + void *buf; + int frames = 0; + int len = SKB_WITH_OVERHEAD(q->buf_size); + int offset = q->buf_offset; + int idx; + + spin_lock_bh(&q->lock); + + while (q->queued < q->ndesc - 1) { + buf = kzalloc(q->buf_size, GFP_ATOMIC); + if (!buf) + break; + + addr = dma_map_single(dev->dev, buf, len, DMA_FROM_DEVICE); + if (dma_mapping_error(dev->dev, addr)) { + kfree(buf); + break; + } + + idx = mt76_dma_add_buf(dev, q, addr + offset, len - offset, 0, 0, 0); + q->entry[idx].buf = buf; + frames++; + } + + if (frames) + mt76_dma_kick_queue(dev, q); + + spin_unlock_bh(&q->lock); + + return frames; +} + static const struct mt76_queue_ops mt76_dma_ops = { .alloc = mt76_dma_alloc_queue, .add_buf = mt76_dma_add_buf, + .rx_fill = mt76_dma_rx_fill, .dequeue = mt76_dma_dequeue, .cleanup = mt76_dma_cleanup, .kick = mt76_dma_kick_queue, diff --git a/mt76.h b/mt76.h index 27badb76..edde309e 100644 --- a/mt76.h +++ b/mt76.h @@ -78,6 +78,7 @@ struct mt76_queue { int ndesc; int queued; int buf_size; + int buf_offset; dma_addr_t desc_dma; }; @@ -95,6 +96,8 @@ 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); + void (*kick)(struct mt76_dev *dev, struct mt76_queue *q); }; @@ -205,6 +208,7 @@ static inline u16 mt76_rev(struct mt76_dev *dev) #define mt76_queue_add_buf(dev, ...) (dev)->mt76.queue_ops->add_buf(&((dev)->mt76), __VA_ARGS__) #define mt76_queue_dequeue(dev, ...) (dev)->mt76.queue_ops->dequeue(&((dev)->mt76), __VA_ARGS__) #define mt76_queue_cleanup(dev, ...) (dev)->mt76.queue_ops->cleanup(&((dev)->mt76), __VA_ARGS__) +#define mt76_queue_rx_fill(dev, ...) (dev)->mt76.queue_ops->rx_fill(&((dev)->mt76), __VA_ARGS__) #define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__) #define mt76_tx_queue_skb(dev, ...) (dev)->drv->tx_queue_skb(dev, __VA_ARGS__) diff --git a/mt7603_dma.c b/mt7603_dma.c index 5d4a45ab..4b52320c 100644 --- a/mt7603_dma.c +++ b/mt7603_dma.c @@ -14,48 +14,6 @@ #include "mt7603.h" #include "mt7603_dma.h" -static int -mt7603_dma_add_rx_buf(struct mt7603_dev *dev, struct mt76_queue *q, - dma_addr_t addr, int len) -{ - return mt76_queue_add_buf(dev, q, addr, len, 0, 0, 0); -} - -static int -mt7603_dma_rx_fill(struct mt7603_dev *dev, struct mt76_queue *q) -{ - dma_addr_t addr; - void *buf; - int frames = 0; - int len = SKB_WITH_OVERHEAD(q->buf_size); - int idx; - - spin_lock_bh(&q->lock); - - while (q->queued < q->ndesc - 1) { - buf = kzalloc(q->buf_size, GFP_ATOMIC); - if (!buf) - break; - - addr = dma_map_single(dev->mt76.dev, buf, len, DMA_FROM_DEVICE); - if (dma_mapping_error(dev->mt76.dev, addr)) { - kfree(buf); - break; - } - - idx = mt7603_dma_add_rx_buf(dev, q, addr, len); - q->entry[idx].buf = buf; - frames++; - } - - if (frames) - mt76_queue_kick(dev, q); - - spin_unlock_bh(&q->lock); - - return frames; -} - int mt7603_tx_queue_mcu(struct mt7603_dev *dev, enum mt76_txq_id qid, struct sk_buff *skb) @@ -186,7 +144,7 @@ mt7603_process_rx_queue(struct mt7603_dev *dev, struct mt76_queue *q, int budget done++; } - mt7603_dma_rx_fill(dev, q); + mt76_queue_rx_fill(dev, q); return done; } @@ -314,8 +272,8 @@ int mt7603_dma_init(struct mt7603_dev *dev) if (ret) return ret; - mt7603_dma_rx_fill(dev, &dev->q_rx); - mt7603_dma_rx_fill(dev, &dev->mcu.q_rx); + mt76_queue_rx_fill(dev, &dev->q_rx); + mt76_queue_rx_fill(dev, &dev->mcu.q_rx); mt76_wr(dev, MT_DELAY_INT_CFG, 0); diff --git a/mt76x2_dma.c b/mt76x2_dma.c index e3d2ee76..32e933da 100644 --- a/mt76x2_dma.c +++ b/mt76x2_dma.c @@ -20,14 +20,6 @@ struct mt76_txwi_cache { struct list_head list; }; -static inline int -mt76x2_rx_buf_offset(struct mt76x2_dev *dev) -{ - BUILD_BUG_ON(MT_RX_HEADROOM < sizeof(struct mt76x2_rxwi)); - - return MT_RX_HEADROOM - sizeof(struct mt76x2_rxwi); -} - static struct mt76_txwi_cache * mt76x2_alloc_txwi(struct mt76x2_dev *dev) { @@ -84,50 +76,6 @@ mt76x2_put_txwi(struct mt76x2_dev *dev, struct mt76_txwi_cache *t) spin_unlock_bh(&dev->lock); } -static int -mt76x2_dma_add_rx_buf(struct mt76x2_dev *dev, struct mt76_queue *q, - dma_addr_t addr, int len) -{ - int offset = mt76x2_rx_buf_offset(dev); - - return mt76_queue_add_buf(dev, q, addr + offset, len - offset, 0, 0, 0); -} - -static int -mt76x2_dma_rx_fill(struct mt76x2_dev *dev, struct mt76_queue *q) -{ - dma_addr_t addr; - void *buf; - int frames = 0; - int len = SKB_WITH_OVERHEAD(q->buf_size); - int idx; - - spin_lock_bh(&q->lock); - - while (q->queued < q->ndesc - 1) { - buf = kzalloc(q->buf_size, GFP_ATOMIC); - if (!buf) - break; - - addr = dma_map_single(dev->mt76.dev, buf, len, DMA_FROM_DEVICE); - if (dma_mapping_error(dev->mt76.dev, addr)) { - kfree(buf); - break; - } - - idx = mt76x2_dma_add_rx_buf(dev, q, addr, len); - q->entry[idx].buf = buf; - frames++; - } - - if (frames) - mt76_queue_kick(dev, q); - - spin_unlock_bh(&q->lock); - - return frames; -} - int mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid, struct sk_buff *skb, int cmd, int seq) @@ -338,7 +286,7 @@ mt76x2_process_rx_queue(struct mt76x2_dev *dev, struct mt76_queue *q, int budget done++; } - mt76x2_dma_rx_fill(dev, q); + mt76_queue_rx_fill(dev, q); return done; } @@ -453,8 +401,8 @@ int mt76x2_dma_init(struct mt76x2_dev *dev) if (ret) return ret; - mt76x2_dma_rx_fill(dev, &dev->q_rx); - mt76x2_dma_rx_fill(dev, &dev->mcu.q_rx); + mt76_queue_rx_fill(dev, &dev->q_rx); + mt76_queue_rx_fill(dev, &dev->mcu.q_rx); return 0; } @@ -464,6 +412,10 @@ void mt76x2_dma_cleanup(struct mt76x2_dev *dev) struct mt76_txwi_cache *t; int i; + BUILD_BUG_ON(MT_RX_HEADROOM < sizeof(struct mt76x2_rxwi)); + dev->q_rx.buf_offset = MT_RX_HEADROOM - sizeof(struct mt76x2_rxwi); + dev->mcu.q_rx.buf_offset = MT_RX_HEADROOM - sizeof(struct mt76x2_rxwi); + tasklet_kill(&dev->tx_tasklet); tasklet_kill(&dev->rx_tasklet); for (i = 0; i < ARRAY_SIZE(dev->mt76.q_tx); i++)