diff --git a/Makefile b/Makefile index b01de11a..eeb3c33d 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ EXTRA_CFLAGS += -Werror obj-m := mt76.o mt76x2e.o mt7603e.o mt76-y := \ - mmio.o util.o trace.o + mmio.o util.o trace.o dma.o mt76x2e-y := \ mt76x2_pci.o mt76x2_dma.o \ diff --git a/dma.c b/dma.c new file mode 100644 index 00000000..03802d3d --- /dev/null +++ b/dma.c @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2015 Felix Fietkau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "mt76.h" +#include "dma.h" + +static int +mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q) +{ + int size; + int i; + + size = q->ndesc * sizeof(struct mt76_desc); + q->desc = dmam_alloc_coherent(dev->dev, size, &q->desc_dma, GFP_KERNEL); + if (!q->desc) + return -ENOMEM; + + size = q->ndesc * sizeof(*q->entry); + q->entry = devm_kzalloc(dev->dev, size, GFP_KERNEL); + if (!q->entry) + return -ENOMEM; + + /* clear descriptors */ + for (i = 0; i < q->ndesc; i++) + q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE); + + iowrite32(q->desc_dma, &q->regs->desc_base); + iowrite32(0, &q->regs->cpu_idx); + iowrite32(0, &q->regs->dma_idx); + iowrite32(q->ndesc, &q->regs->ring_size); + + return 0; +} + +static int +mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, + u32 buf0, int len0, u32 buf1, int len1, u32 info) +{ + struct mt76_desc *desc; + u32 ctrl; + int idx; + + ctrl = MT76_SET(MT_DMA_CTL_SD_LEN0, len0) | + MT76_SET(MT_DMA_CTL_SD_LEN1, len1) | + (len1 ? MT_DMA_CTL_LAST_SEC1 : MT_DMA_CTL_LAST_SEC0); + + idx = q->head; + q->head = (q->head + 1) % q->ndesc; + + desc = &q->desc[idx]; + + ACCESS_ONCE(desc->buf0) = cpu_to_le32(buf0); + ACCESS_ONCE(desc->buf1) = cpu_to_le32(buf1); + ACCESS_ONCE(desc->info) = cpu_to_le32(info); + ACCESS_ONCE(desc->ctrl) = cpu_to_le32(ctrl); + + q->queued++; + + return idx; +} + +static void +mt76_dma_tx_cleanup_idx(struct mt76_dev *dev, struct mt76_queue *q, int idx, + struct mt76_queue_entry *prev_e) +{ + struct mt76_queue_entry *e = &q->entry[idx]; + struct sk_buff *skb = e->skb; + dma_addr_t skb_addr; + + if (e->txwi) + skb_addr = ACCESS_ONCE(q->desc[idx].buf1); + else + skb_addr = ACCESS_ONCE(q->desc[idx].buf0); + + dma_unmap_single(dev->dev, skb_addr, skb->len, DMA_TO_DEVICE); + + *prev_e = *e; + memset(e, 0, sizeof(*e)); +} + +static int +mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush) +{ + int ret = -1; + + if (!q->queued) + return -1; + + if (!flush && !(q->desc[q->tail].ctrl & cpu_to_le32(MT_DMA_CTL_DMA_DONE))) + return -1; + + ret = q->tail; + q->tail = (q->tail + 1) % q->ndesc; + q->queued--; + + return ret; +} + +static void +mt76_dma_kick_queue(struct mt76_dev *dev, struct mt76_queue *q) +{ + iowrite32(q->head, &q->regs->cpu_idx); +} + +static const struct mt76_queue_ops mt76_dma_ops = { + .alloc = mt76_dma_alloc_queue, + .add_buf = mt76_dma_add_buf, + .dequeue = mt76_dma_dequeue, + .cleanup_idx = mt76_dma_tx_cleanup_idx, + .kick = mt76_dma_kick_queue, +}; + +int mt76_dma_init(struct mt76_dev *dev) +{ + dev->queue_ops = &mt76_dma_ops; + return 0; +} +EXPORT_SYMBOL_GPL(mt76_dma_init); diff --git a/dma.h b/dma.h new file mode 100644 index 00000000..f9da8b3b --- /dev/null +++ b/dma.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015 Felix Fietkau + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __MT76_DMA_H +#define __MT76_DMA_H + +#define MT_DMA_CTL_SD_LEN1 GENMASK(13, 0) +#define MT_DMA_CTL_LAST_SEC1 BIT(14) +#define MT_DMA_CTL_BURST BIT(15) +#define MT_DMA_CTL_SD_LEN0 GENMASK(29, 16) +#define MT_DMA_CTL_LAST_SEC0 BIT(30) +#define MT_DMA_CTL_DMA_DONE BIT(31) + +struct mt76_desc { + __le32 buf0; + __le32 ctrl; + __le32 buf1; + __le32 info; +} __packed __aligned(4); + +int mt76_dma_init(struct mt76_dev *dev); + +#endif diff --git a/mt76.h b/mt76.h index 11589da0..cd118303 100644 --- a/mt76.h +++ b/mt76.h @@ -16,6 +16,8 @@ #include #include +#include +#include #include #include "util.h" @@ -28,12 +30,63 @@ struct mt76_bus_ops { void (*copy)(struct mt76_dev *dev, u32 offset, const void *data, int len); }; +struct mt76_queue_entry { + struct sk_buff *skb; + union { + void *buf; + struct mt76_txwi_cache *txwi; + }; + bool schedule; +}; + +struct mt76_queue_regs { + u32 desc_base; + u32 ring_size; + u32 cpu_idx; + u32 dma_idx; +} __packed __aligned(4); + +struct mt76_queue { + struct mt76_queue_regs __iomem *regs; + + spinlock_t lock; + struct mt76_queue_entry *entry; + struct mt76_desc *desc; + + struct list_head swq; + int swq_queued; + + u16 head; + u16 tail; + int ndesc; + int queued; + int buf_size; + + dma_addr_t desc_dma; +}; + +struct mt76_queue_ops { + int (*alloc)(struct mt76_dev *dev, struct mt76_queue *q); + + int (*add_buf)(struct mt76_dev *dev, struct mt76_queue *q, + u32 buf0, int len0, u32 buf1, int len1, u32 info); + + int (*dequeue)(struct mt76_dev *dev, struct mt76_queue *q, bool flush); + + void (*cleanup_idx)(struct mt76_dev *dev, struct mt76_queue *q, int idx, + struct mt76_queue_entry *e); + + void (*kick)(struct mt76_dev *dev, struct mt76_queue *q); +}; + struct mt76_dev { + struct ieee80211_hw *hw; + const struct mt76_bus_ops *bus; void __iomem *regs; struct device *dev; - struct ieee80211_hw *hw; + const struct mt76_queue_ops *queue_ops; }; #define mt76_rr(dev, ...) (dev)->mt76.bus->rr(&((dev)->mt76), __VA_ARGS__) @@ -64,4 +117,11 @@ bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs); + +#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_dequeue(dev, ...) (dev)->mt76.queue_ops->dequeue(&((dev)->mt76), __VA_ARGS__) +#define mt76_queue_cleanup_idx(dev, ...) (dev)->mt76.queue_ops->cleanup_idx(&((dev)->mt76), __VA_ARGS__) +#define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__) + #endif diff --git a/mt76x2.h b/mt76x2.h index 87a4f678..aaf7d6da 100644 --- a/mt76x2.h +++ b/mt76x2.h @@ -45,15 +45,6 @@ #include "mt76x2_regs.h" #include "mt76x2_mac.h" -struct mt76x2_queue_entry { - struct sk_buff *skb; - union { - void *buf; - struct mt76x2_txwi_cache *txwi; - }; - bool schedule; -}; - enum { MT76_STATE_INITIALIZED, MT76_STATE_RUNNING, @@ -70,32 +61,13 @@ enum mt76x2_txq_id { __MT_TXQ_MAX }; -struct mt76x2_queue { - struct mt76x2_queue_regs __iomem *regs; - - spinlock_t lock; - struct mt76x2_queue_entry *entry; - struct mt76x2_desc *desc; - - struct list_head swq; - int swq_queued; - - u16 head; - u16 tail; - int ndesc; - int queued; - int buf_size; - - dma_addr_t desc_dma; -}; - struct mt76x2_mcu { struct mutex mutex; wait_queue_head_t wait; struct sk_buff_head res_q; - struct mt76x2_queue q_rx; + struct mt76_queue q_rx; u32 msg_seq; }; @@ -150,20 +122,6 @@ struct mt76x2_rate_power { }; }; -struct mt76x2_dma_ops { - int (*queue_skb)(struct mt76x2_dev *dev, struct mt76x2_queue *q, - struct sk_buff *skb, struct mt76x2_wcid *wcid, - struct ieee80211_sta *sta); - int (*queue_mcu)(struct mt76x2_dev *dev, enum mt76x2_txq_id qid, - struct sk_buff *skb, int cmd, int seq); - - void (*cleanup_idx)(struct mt76x2_dev *dev, struct mt76x2_queue *q, int idx, - bool flush, bool *schedule); - - int (*add_rx_buf)(struct mt76x2_dev *dev, struct mt76x2_queue *q, - dma_addr_t addr, int len); -}; - struct mt76x2_dev { struct mt76_dev mt76; @@ -172,8 +130,6 @@ struct mt76x2_dev { struct mutex mutex; - const struct mt76x2_dma_ops *dma_ops; - const u16 *beacon_offsets; unsigned long wcid_mask[256 / BITS_PER_LONG]; @@ -188,8 +144,8 @@ struct mt76x2_dev { struct list_head txwi_cache; struct mt76x2_mcu mcu; - struct mt76x2_queue q_rx; - struct mt76x2_queue q_tx[__MT_TXQ_MAX]; + struct mt76_queue q_rx; + struct mt76_queue q_tx[__MT_TXQ_MAX]; struct net_device napi_dev; struct napi_struct napi; @@ -249,7 +205,7 @@ struct mt76x2_sta { struct mt76x2_txq { struct list_head list; - struct mt76x2_queue *hwq; + struct mt76_queue *hwq; struct sk_buff_head retry_q; @@ -330,21 +286,21 @@ void mt76x2_dma_cleanup(struct mt76x2_dev *dev); void mt76x2_cleanup(struct mt76x2_dev *dev); void mt76x2_rx(struct mt76x2_dev *dev, struct sk_buff *skb); -#define mt76x2_tx_queue_skb(dev, ...) dev->dma_ops->queue_skb(dev, __VA_ARGS__) -#define mt76x2_tx_queue_mcu(dev, ...) dev->dma_ops->queue_mcu(dev, __VA_ARGS__) - +int mt76x2_tx_queue_skb(struct mt76x2_dev *dev, struct mt76_queue *q, + struct sk_buff *skb, struct mt76x2_wcid *wcid, + struct ieee80211_sta *sta); +int mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76x2_txq_id qid, + struct sk_buff *skb, int cmd, int seq); void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb); void mt76x2_tx_complete(struct mt76x2_dev *dev, struct sk_buff *skb); -void mt76x2_kick_queue(struct mt76x2_dev *dev, struct mt76x2_queue *q); - void mt76x2_pre_tbtt_tasklet(unsigned long data); void mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq); void mt76x2_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq); void mt76x2_txq_remove(struct mt76x2_dev *dev, struct ieee80211_txq *txq); -void mt76x2_txq_schedule(struct mt76x2_dev *dev, struct mt76x2_queue *hwq); +void mt76x2_txq_schedule(struct mt76x2_dev *dev, struct mt76_queue *hwq); void mt76x2_release_buffered_frames(struct ieee80211_hw *hw, struct ieee80211_sta *sta, diff --git a/mt76x2_core.c b/mt76x2_core.c index dee0d12f..4c4df5a0 100644 --- a/mt76x2_core.c +++ b/mt76x2_core.c @@ -71,7 +71,7 @@ irqreturn_t mt76x2_irq_handler(int irq, void *dev_instance) /* send buffered multicast frames now */ if (intr & MT_INT_TBTT) - mt76x2_kick_queue(dev, &dev->q_tx[MT_TXQ_PSD]); + mt76_queue_kick(dev, &dev->q_tx[MT_TXQ_PSD]); if (intr & MT_INT_TX_STAT) { mt76x2_mac_poll_tx_status(dev, true); diff --git a/mt76x2_dma.c b/mt76x2_dma.c index dd233975..7764c03c 100644 --- a/mt76x2_dma.c +++ b/mt76x2_dma.c @@ -14,8 +14,8 @@ #include "mt76x2.h" #include "mt76x2_dma.h" -struct mt76x2_txwi_cache { - struct mt76x2_txwi txwi; +struct mt76_txwi_cache { + struct mt76_txwi txwi; dma_addr_t dma_addr; struct list_head list; }; @@ -28,10 +28,10 @@ mt76x2_rx_buf_offset(struct mt76x2_dev *dev) return MT_RX_HEADROOM - sizeof(struct mt76x2_rxwi); } -static struct mt76x2_txwi_cache * +static struct mt76_txwi_cache * mt76x2_alloc_txwi(struct mt76x2_dev *dev) { - struct mt76x2_txwi_cache *t; + struct mt76_txwi_cache *t; dma_addr_t addr; int size; @@ -46,14 +46,14 @@ mt76x2_alloc_txwi(struct mt76x2_dev *dev) return t; } -static struct mt76x2_txwi_cache * +static struct mt76_txwi_cache * __mt76x2_get_txwi(struct mt76x2_dev *dev) { - struct mt76x2_txwi_cache *t = NULL; + struct mt76_txwi_cache *t = NULL; spin_lock_bh(&dev->lock); if (!list_empty(&dev->txwi_cache)) { - t = list_first_entry(&dev->txwi_cache, struct mt76x2_txwi_cache, + t = list_first_entry(&dev->txwi_cache, struct mt76_txwi_cache, list); list_del(&t->list); } @@ -62,10 +62,10 @@ __mt76x2_get_txwi(struct mt76x2_dev *dev) return t; } -static struct mt76x2_txwi_cache * +static struct mt76_txwi_cache * mt76x2_get_txwi(struct mt76x2_dev *dev) { - struct mt76x2_txwi_cache *t = __mt76x2_get_txwi(dev); + struct mt76_txwi_cache *t = __mt76x2_get_txwi(dev); if (t) return t; @@ -74,7 +74,7 @@ mt76x2_get_txwi(struct mt76x2_dev *dev) } static void -mt76x2_put_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi_cache *t) +mt76x2_put_txwi(struct mt76x2_dev *dev, struct mt76_txwi_cache *t) { if (!t) return; @@ -85,76 +85,16 @@ mt76x2_put_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi_cache *t) } static int -mt76x2_alloc_queue(struct mt76x2_dev *dev, struct mt76x2_queue *q) -{ - int size; - int i; - - size = q->ndesc * sizeof(struct mt76x2_desc); - q->desc = dmam_alloc_coherent(dev->mt76.dev, size, &q->desc_dma, GFP_KERNEL); - if (!q->desc) - return -ENOMEM; - - size = q->ndesc * sizeof(*q->entry); - q->entry = devm_kzalloc(dev->mt76.dev, size, GFP_KERNEL); - if (!q->entry) - return -ENOMEM; - - /* clear descriptors */ - for (i = 0; i < q->ndesc; i++) - q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE); - - iowrite32(q->desc_dma, &q->regs->desc_base); - iowrite32(0, &q->regs->cpu_idx); - iowrite32(0, &q->regs->dma_idx); - iowrite32(q->ndesc, &q->regs->ring_size); - - return 0; -} - -void mt76x2_kick_queue(struct mt76x2_dev *dev, struct mt76x2_queue *q) -{ - iowrite32(q->head, &q->regs->cpu_idx); -} - -static int -mt76x2_queue_add_buf(struct mt76x2_dev *dev, struct mt76x2_queue *q, - u32 buf0, int len0, u32 buf1, int len1, u32 info) -{ - struct mt76x2_desc *desc; - u32 ctrl; - int idx; - - ctrl = MT76_SET(MT_DMA_CTL_SD_LEN0, len0) | - MT76_SET(MT_DMA_CTL_SD_LEN1, len1) | - (len1 ? MT_DMA_CTL_LAST_SEC1 : MT_DMA_CTL_LAST_SEC0); - - idx = q->head; - q->head = (q->head + 1) % q->ndesc; - - desc = &q->desc[idx]; - - ACCESS_ONCE(desc->buf0) = cpu_to_le32(buf0); - ACCESS_ONCE(desc->buf1) = cpu_to_le32(buf1); - ACCESS_ONCE(desc->info) = cpu_to_le32(info); - ACCESS_ONCE(desc->ctrl) = cpu_to_le32(ctrl); - - q->queued++; - - return idx; -} - -static int -mt76x2_dma_add_rx_buf(struct mt76x2_dev *dev, struct mt76x2_queue *q, +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 mt76x2_queue_add_buf(dev, q, addr + offset, len - offset, 0, 0, 0); + 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 mt76x2_queue *q) +mt76x2_dma_rx_fill(struct mt76x2_dev *dev, struct mt76_queue *q) { dma_addr_t addr; void *buf; @@ -175,24 +115,24 @@ mt76x2_dma_rx_fill(struct mt76x2_dev *dev, struct mt76x2_queue *q) break; } - idx = dev->dma_ops->add_rx_buf(dev, q, addr, len); + idx = mt76x2_dma_add_rx_buf(dev, q, addr, len); q->entry[idx].buf = buf; frames++; } if (frames) - mt76x2_kick_queue(dev, q); + mt76_queue_kick(dev, q); spin_unlock_bh(&q->lock); return frames; } -static int -mt76x2_dma_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76x2_txq_id qid, - struct sk_buff *skb, int cmd, int seq) +int +mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76x2_txq_id qid, + struct sk_buff *skb, int cmd, int seq) { - struct mt76x2_queue *q = &dev->q_tx[qid]; + struct mt76_queue *q = &dev->q_tx[qid]; dma_addr_t addr; u32 tx_info; int idx; @@ -208,21 +148,21 @@ mt76x2_dma_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76x2_txq_id qid, return -ENOMEM; spin_lock_bh(&q->lock); - idx = mt76x2_queue_add_buf(dev, q, addr, skb->len, 0, 0, tx_info); + idx = mt76_queue_add_buf(dev, q, addr, skb->len, 0, 0, tx_info); q->entry[idx].skb = skb; - mt76x2_kick_queue(dev, q); + mt76_queue_kick(dev, q); spin_unlock_bh(&q->lock); return 0; } -static int -mt76x2_dma_tx_queue_skb(struct mt76x2_dev *dev, struct mt76x2_queue *q, - struct sk_buff *skb, struct mt76x2_wcid *wcid, - struct ieee80211_sta *sta) +int +mt76x2_tx_queue_skb(struct mt76x2_dev *dev, struct mt76_queue *q, + struct sk_buff *skb, struct mt76x2_wcid *wcid, + struct ieee80211_sta *sta) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct mt76x2_txwi_cache *t; + struct mt76_txwi_cache *t; dma_addr_t addr; u32 tx_info = 0; int idx, ret, len; @@ -259,7 +199,7 @@ mt76x2_dma_tx_queue_skb(struct mt76x2_dev *dev, struct mt76x2_queue *q, if (dma_mapping_error(dev->mt76.dev, addr)) goto put_txwi; - idx = mt76x2_queue_add_buf(dev, q, t->dma_addr, sizeof(t->txwi), + idx = mt76_queue_add_buf(dev, q, t->dma_addr, sizeof(t->txwi), addr, skb->len, tx_info); q->entry[idx].skb = skb; q->entry[idx].txwi = t; @@ -273,62 +213,22 @@ free: return ret; } -static int -mt76x2_dma_dequeue(struct mt76x2_dev *dev, struct mt76x2_queue *q, bool flush) -{ - int ret = -1; - - if (!q->queued) - return -1; - - if (!flush && !(q->desc[q->tail].ctrl & cpu_to_le32(MT_DMA_CTL_DMA_DONE))) - return -1; - - ret = q->tail; - q->tail = (q->tail + 1) % q->ndesc; - q->queued--; - - return ret; -} - static void -mt76x2_dma_tx_cleanup_idx(struct mt76x2_dev *dev, struct mt76x2_queue *q, int idx, - bool flush, bool *schedule) -{ - struct mt76x2_queue_entry *e = &q->entry[idx]; - struct sk_buff *skb = e->skb; - struct mt76x2_txwi_cache *txwi = e->txwi; - dma_addr_t skb_addr; - - *schedule = e->schedule; - - if (txwi) - skb_addr = ACCESS_ONCE(q->desc[idx].buf1); - else - skb_addr = ACCESS_ONCE(q->desc[idx].buf0); - - dma_unmap_single(dev->mt76.dev, skb_addr, skb->len, DMA_TO_DEVICE); - e->skb = NULL; - e->txwi = NULL; - e->schedule = false; - - if (!txwi) { - dev_kfree_skb_any(skb); - return; - } - - mt76x2_mac_queue_txdone(dev, skb, &txwi->txwi); - mt76x2_put_txwi(dev, txwi); -} - -static void -mt76x2_tx_cleanup_entry(struct mt76x2_dev *dev, struct mt76x2_queue *q, int idx, +mt76x2_tx_cleanup_entry(struct mt76x2_dev *dev, struct mt76_queue *q, int idx, bool flush) { - bool schedule; + struct mt76_queue_entry entry; - dev->dma_ops->cleanup_idx(dev, q, idx, flush, &schedule); - if (schedule) { + mt76_queue_cleanup_idx(dev, q, idx, &entry); + + if (entry.txwi) { + mt76x2_mac_queue_txdone(dev, entry.skb, &entry.txwi->txwi); + mt76x2_put_txwi(dev, entry.txwi); + } else { + dev_kfree_skb_any(entry.skb); + } + + if (entry.schedule) { q->swq_queued--; if (!flush) mt76x2_txq_schedule(dev, q); @@ -336,7 +236,7 @@ mt76x2_tx_cleanup_entry(struct mt76x2_dev *dev, struct mt76x2_queue *q, int idx, } static void -mt76x2_tx_cleanup_queue(struct mt76x2_dev *dev, struct mt76x2_queue *q, bool flush) +mt76x2_tx_cleanup_queue(struct mt76x2_dev *dev, struct mt76_queue *q, bool flush) { int last; @@ -360,9 +260,9 @@ mt76x2_tx_cleanup_queue(struct mt76x2_dev *dev, struct mt76x2_queue *q, bool flu } static void * -mt76x2_rx_get_buf(struct mt76x2_dev *dev, struct mt76x2_queue *q, int idx, int *len) +mt76x2_rx_get_buf(struct mt76x2_dev *dev, struct mt76_queue *q, int idx, int *len) { - struct mt76x2_queue_entry *e; + struct mt76_queue_entry *e; dma_addr_t buf_addr; void *buf; int buf_len = SKB_WITH_OVERHEAD(q->buf_size); @@ -381,7 +281,7 @@ mt76x2_rx_get_buf(struct mt76x2_dev *dev, struct mt76x2_queue *q, int idx, int * } static void -mt76x2_rx_cleanup(struct mt76x2_dev *dev, struct mt76x2_queue *q) +mt76x2_rx_cleanup(struct mt76x2_dev *dev, struct mt76_queue *q) { void *buf; int idx; @@ -389,7 +289,7 @@ mt76x2_rx_cleanup(struct mt76x2_dev *dev, struct mt76x2_queue *q) spin_lock_bh(&q->lock); do { - idx = mt76x2_dma_dequeue(dev, q, true); + idx = mt76_queue_dequeue(dev, q, true); if (idx < 0) break; @@ -401,7 +301,7 @@ mt76x2_rx_cleanup(struct mt76x2_dev *dev, struct mt76x2_queue *q) } static int -mt76x2_init_tx_queue(struct mt76x2_dev *dev, struct mt76x2_queue *q, +mt76x2_init_tx_queue(struct mt76x2_dev *dev, struct mt76_queue *q, int idx, int n_desc, bool mcu) { int ret; @@ -409,7 +309,7 @@ mt76x2_init_tx_queue(struct mt76x2_dev *dev, struct mt76x2_queue *q, q->regs = dev->mt76.regs + MT_TX_RING_BASE + idx * MT_RING_SIZE; q->ndesc = n_desc; - ret = mt76x2_alloc_queue(dev, q); + ret = mt76_queue_alloc(dev, q); if (ret) return ret; @@ -419,7 +319,7 @@ mt76x2_init_tx_queue(struct mt76x2_dev *dev, struct mt76x2_queue *q, } static void -mt76x2_process_rx_skb(struct mt76x2_dev *dev, struct mt76x2_queue *q, +mt76x2_process_rx_skb(struct mt76x2_dev *dev, struct mt76_queue *q, struct sk_buff *skb, u32 info) { void *rxwi = skb->data - sizeof(struct mt76x2_rxwi); @@ -447,16 +347,16 @@ mt76x2_process_rx_skb(struct mt76x2_dev *dev, struct mt76x2_queue *q, } static int -mt76x2_process_rx_queue(struct mt76x2_dev *dev, struct mt76x2_queue *q, int budget) +mt76x2_process_rx_queue(struct mt76x2_dev *dev, struct mt76_queue *q, int budget) { - struct mt76x2_desc *desc; + struct mt76_desc *desc; struct sk_buff *skb; unsigned char *data; int idx, len; int done = 0; while (done < budget) { - idx = mt76x2_dma_dequeue(dev, q, false); + idx = mt76_queue_dequeue(dev, q, false); if (idx < 0) break; @@ -485,7 +385,7 @@ mt76x2_process_rx_queue(struct mt76x2_dev *dev, struct mt76x2_queue *q, int budg } static int -mt76x2_init_rx_queue(struct mt76x2_dev *dev, struct mt76x2_queue *q, +mt76x2_init_rx_queue(struct mt76x2_dev *dev, struct mt76_queue *q, int idx, int n_desc, int bufsize) { int ret; @@ -494,7 +394,7 @@ mt76x2_init_rx_queue(struct mt76x2_dev *dev, struct mt76x2_queue *q, q->ndesc = n_desc; q->buf_size = bufsize; - ret = mt76x2_alloc_queue(dev, q); + ret = mt76_queue_alloc(dev, q); if (ret) return ret; @@ -544,13 +444,6 @@ mt76x2_rx_tasklet(unsigned long data) mt76x2_irq_enable(dev, MT_INT_RX_DONE(1)); } -static const struct mt76x2_dma_ops mt76x2_dma_ops = { - .queue_skb = mt76x2_dma_tx_queue_skb, - .queue_mcu = mt76x2_dma_tx_queue_mcu, - .cleanup_idx = mt76x2_dma_tx_cleanup_idx, - .add_rx_buf = mt76x2_dma_add_rx_buf, -}; - int mt76x2_dma_init(struct mt76x2_dev *dev) { static const u8 wmm_queue_map[] = { @@ -562,7 +455,7 @@ int mt76x2_dma_init(struct mt76x2_dev *dev) int ret; int i; - dev->dma_ops = &mt76x2_dma_ops; + mt76_dma_init(&dev->mt76); init_waitqueue_head(&dev->mcu.wait); skb_queue_head_init(&dev->mcu.res_q); @@ -617,7 +510,7 @@ int mt76x2_dma_init(struct mt76x2_dev *dev) void mt76x2_dma_cleanup(struct mt76x2_dev *dev) { - struct mt76x2_txwi_cache *t; + struct mt76_txwi_cache *t; int i; tasklet_kill(&dev->tx_tasklet); diff --git a/mt76x2_dma.h b/mt76x2_dma.h index 2633a287..9d55e9f5 100644 --- a/mt76x2_dma.h +++ b/mt76x2_dma.h @@ -14,12 +14,7 @@ #ifndef __MT76x2_DMA_H #define __MT76x2_DMA_H -#define MT_DMA_CTL_SD_LEN1 GENMASK(13, 0) -#define MT_DMA_CTL_LAST_SEC1 BIT(14) -#define MT_DMA_CTL_BURST BIT(15) -#define MT_DMA_CTL_SD_LEN0 GENMASK(29, 16) -#define MT_DMA_CTL_LAST_SEC0 BIT(30) -#define MT_DMA_CTL_DMA_DONE BIT(31) +#include "dma.h" #define MT_TXD_INFO_LEN GENMASK(13, 0) #define MT_TXD_INFO_NEXT_VLD BIT(16) @@ -67,11 +62,4 @@ enum dma_msg_port { DISCARD, }; -struct mt76x2_desc { - __le32 buf0; - __le32 ctrl; - __le32 buf1; - __le32 info; -} __packed __aligned(4); - #endif diff --git a/mt76x2_mac.c b/mt76x2_mac.c index ab9ebdea..8c2e7264 100644 --- a/mt76x2_mac.c +++ b/mt76x2_mac.c @@ -153,7 +153,7 @@ void mt76x2_mac_wcid_set_rate(struct mt76x2_dev *dev, struct mt76x2_wcid *wcid, spin_unlock_irqrestore(&dev->lock, flags); } -void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, +void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76_txwi *txwi, struct sk_buff *skb, struct mt76x2_wcid *wcid, struct ieee80211_sta *sta) { @@ -441,7 +441,7 @@ void mt76x2_mac_poll_tx_status(struct mt76x2_dev *dev, bool irq) } void mt76x2_mac_queue_txdone(struct mt76x2_dev *dev, struct sk_buff *skb, - struct mt76x2_txwi *txwi) + struct mt76_txwi *txwi) { struct mt76x2_tx_info *txi = mt76x2_skb_tx_info(skb); @@ -579,9 +579,9 @@ static int mt76_write_beacon(struct mt76x2_dev *dev, int offset, struct sk_buff *skb) { int beacon_len = dev->beacon_offsets[1] - dev->beacon_offsets[0]; - struct mt76x2_txwi txwi; + struct mt76_txwi txwi; - if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x2_txwi))) + if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76_txwi))) return -ENOSPC; mt76x2_mac_write_txwi(dev, &txwi, skb, NULL, NULL); diff --git a/mt76x2_mac.h b/mt76x2_mac.h index e2f4f4cd..a6d6b275 100644 --- a/mt76x2_mac.h +++ b/mt76x2_mac.h @@ -19,9 +19,9 @@ struct mt76x2_sta; struct mt76x2_vif; struct mt76x2_wcid; -struct mt76x2_txwi; -struct mt76x2_queue; -struct mt76x2_txwi_cache; +struct mt76_txwi; +struct mt76_queue; +struct mt76_txwi_cache; struct mt76x2_tx_status { u8 valid:1; @@ -140,7 +140,7 @@ enum mt76x2_phy_bandwith { #define MT_TXWI_PKTID_PROBE BIT(7) -struct mt76x2_txwi { +struct mt76_txwi { __le16 flags; __le16 rate; u8 ack_ctl; @@ -169,7 +169,7 @@ void mt76x2_mac_resume(struct mt76x2_dev *dev); void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr); int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, void *rxwi); -void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi, +void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76_txwi *txwi, struct sk_buff *skb, struct mt76x2_wcid *wcid, struct ieee80211_sta *sta); void mt76x2_mac_wcid_setup(struct mt76x2_dev *dev, u8 idx, u8 vif_idx, u8 *mac); @@ -187,7 +187,7 @@ int mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 vif_idx, struct sk_buff *sk void mt76x2_mac_set_beacon_enable(struct mt76x2_dev *dev, u8 vif_idx, bool val); void mt76x2_mac_queue_txdone(struct mt76x2_dev *dev, struct sk_buff *skb, - struct mt76x2_txwi *txwi); + struct mt76_txwi *txwi); void mt76x2_mac_poll_tx_status(struct mt76x2_dev *dev, bool irq); void mt76x2_mac_process_tx_status_fifo(struct mt76x2_dev *dev); diff --git a/mt76x2_regs.h b/mt76x2_regs.h index 50c66069..7be56c00 100644 --- a/mt76x2_regs.h +++ b/mt76x2_regs.h @@ -517,13 +517,6 @@ struct mt76x2_wcid_key { u8 rx_mic[8]; } __packed __aligned(4); -struct mt76x2_queue_regs { - u32 desc_base; - u32 ring_size; - u32 cpu_idx; - u32 dma_idx; -} __packed __aligned(4); - enum mt76x2_cipher_type { MT_CIPHER_NONE, MT_CIPHER_WEP40, diff --git a/mt76x2_tx.c b/mt76x2_tx.c index 323bde82..d20d6e44 100644 --- a/mt76x2_tx.c +++ b/mt76x2_tx.c @@ -28,7 +28,7 @@ void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct mt76x2_vif *mvif = (struct mt76x2_vif *) vif->drv_priv; struct mt76x2_sta *msta = NULL; struct mt76x2_wcid *wcid = &mvif->group_wcid; - struct mt76x2_queue *q; + struct mt76_queue *q; int qid = skb_get_queue_mapping(skb); if (WARN_ON(qid >= MT_TXQ_PSD)) { @@ -49,7 +49,7 @@ void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, spin_lock_bh(&q->lock); mt76x2_tx_queue_skb(dev, q, skb, wcid, control->sta); - mt76x2_kick_queue(dev, q); + mt76_queue_kick(dev, q); if (q->queued > q->ndesc - 8) ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); @@ -59,7 +59,7 @@ void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, void mt76x2_tx_complete(struct mt76x2_dev *dev, struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct mt76x2_queue *q; + struct mt76_queue *q; int qid = skb_get_queue_mapping(skb); if (info->flags & IEEE80211_TX_CTL_AMPDU) { @@ -134,7 +134,7 @@ mt76x2_add_buffered_bc(void *priv, u8 *mac, struct ieee80211_vif *vif) void mt76x2_pre_tbtt_tasklet(unsigned long arg) { struct mt76x2_dev *dev = (struct mt76x2_dev *) arg; - struct mt76x2_queue *q = &dev->q_tx[MT_TXQ_PSD]; + struct mt76_queue *q = &dev->q_tx[MT_TXQ_PSD]; struct beacon_bc_data data = {}; struct sk_buff *skb; int i, nframes; @@ -223,7 +223,7 @@ mt76x2_queue_ps_skb(struct mt76x2_dev *dev, struct ieee80211_sta *sta, { struct mt76x2_sta *msta = (struct mt76x2_sta *) sta->drv_priv; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct mt76x2_queue *hwq = &dev->q_tx[MT_TXQ_PSD]; + struct mt76_queue *hwq = &dev->q_tx[MT_TXQ_PSD]; struct mt76x2_wcid *wcid = &msta->wcid; info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE; @@ -242,7 +242,7 @@ mt76x2_release_buffered_frames(struct ieee80211_hw *hw, struct ieee80211_sta *st { struct mt76x2_dev *dev = hw->priv; struct sk_buff *last_skb = NULL; - struct mt76x2_queue *hwq = &dev->q_tx[MT_TXQ_PSD]; + struct mt76_queue *hwq = &dev->q_tx[MT_TXQ_PSD]; int i; for (i = 0; tids && nframes; i++, tids >>= 1) { @@ -273,11 +273,11 @@ mt76x2_release_buffered_frames(struct ieee80211_hw *hw, struct ieee80211_sta *st return; mt76x2_queue_ps_skb(dev, sta, last_skb, true); - mt76x2_kick_queue(dev, hwq); + mt76_queue_kick(dev, hwq); } static int -mt76x2_txq_send_burst(struct mt76x2_dev *dev, struct mt76x2_queue *hwq, +mt76x2_txq_send_burst(struct mt76x2_dev *dev, struct mt76_queue *hwq, struct mt76x2_txq *mtxq, bool *empty) { struct ieee80211_txq *txq = mtxq_to_txq(mtxq); @@ -360,13 +360,13 @@ mt76x2_txq_send_burst(struct mt76x2_dev *dev, struct mt76x2_queue *hwq, hwq->entry[idx].schedule = true; } - mt76x2_kick_queue(dev, hwq); + mt76_queue_kick(dev, hwq); return n_frames; } static int -mt76x2_txq_schedule_list(struct mt76x2_dev *dev, struct mt76x2_queue *hwq) +mt76x2_txq_schedule_list(struct mt76x2_dev *dev, struct mt76_queue *hwq) { struct mt76x2_txq *mtxq, *mtxq_last; int len = 0; @@ -410,7 +410,7 @@ restart: return len; } -void mt76x2_txq_schedule(struct mt76x2_dev *dev, struct mt76x2_queue *hwq) +void mt76x2_txq_schedule(struct mt76x2_dev *dev, struct mt76_queue *hwq) { int len; @@ -457,7 +457,7 @@ void mt76x2_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq) { struct mt76x2_dev *dev = hw->priv; struct mt76x2_txq *mtxq = (struct mt76x2_txq *) txq->drv_priv; - struct mt76x2_queue *hwq = mtxq->hwq; + struct mt76_queue *hwq = mtxq->hwq; spin_lock_bh(&hwq->lock); if (list_empty(&mtxq->list)) @@ -469,7 +469,7 @@ void mt76x2_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq) void mt76x2_txq_remove(struct mt76x2_dev *dev, struct ieee80211_txq *txq) { struct mt76x2_txq *mtxq; - struct mt76x2_queue *hwq; + struct mt76_queue *hwq; struct sk_buff *skb; if (!txq)