move low level DMA code to mt76.ko

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2015-12-06 21:32:43 +01:00
parent 38702fa03a
commit 66af6b3aad
12 changed files with 312 additions and 261 deletions
+1 -1
View File
@@ -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 \
+129
View File
@@ -0,0 +1,129 @@
/*
* Copyright (C) 2015 Felix Fietkau <[email protected]>
*
* 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 <linux/dma-mapping.h>
#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);
+32
View File
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2015 Felix Fietkau <[email protected]>
*
* 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
+61 -1
View File
@@ -16,6 +16,8 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/skbuff.h>
#include <net/mac80211.h>
#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
+10 -54
View File
@@ -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,
+1 -1
View File
@@ -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);
+54 -161
View File
@@ -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);
+1 -13
View File
@@ -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
+4 -4
View File
@@ -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);
+6 -6
View File
@@ -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);
-7
View File
@@ -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,
+13 -13
View File
@@ -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)