mt76x2: move rx queue processing to core

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2016-02-03 14:51:07 +01:00
parent 859aa10d4d
commit 812bcc3a78
5 changed files with 90 additions and 78 deletions
+73
View File
@@ -247,6 +247,78 @@ mt76_dma_init(struct mt76_dev *dev)
return 0;
}
static void
mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
int len, bool more)
{
struct page *page = virt_to_head_page(data);
int offset = data - page_address(page);
struct sk_buff *skb = q->rx_head;
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, offset, len,
q->buf_size);
if (more)
return;
q->rx_head = NULL;
dev->drv->rx_skb(dev, q, skb);
}
static int
mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
{
struct sk_buff *skb;
unsigned char *data;
int len;
int done = 0;
bool napi = q == &dev->q_rx[MT_RXQ_MAIN];
bool more;
while (done < budget) {
u32 info;
data = mt76_dma_dequeue(dev, q, false, &len, &info, &more);
if (!data)
break;
if (q->rx_head) {
mt76_add_fragment(dev, q, data, len, more);
continue;
}
skb = build_skb(data, q->buf_size);
if (!skb) {
skb_free_frag(data);
continue;
}
skb_reserve(skb, q->buf_offset);
if (skb->tail + len > skb->end) {
dev_kfree_skb(skb);
continue;
}
if (q == &dev->q_rx[MT_RXQ_MCU]) {
u32 * rxfce = (u32 *) skb->cb;
*rxfce = info;
}
__skb_put(skb, len);
done++;
if (more) {
q->rx_head = skb;
continue;
}
dev->drv->rx_skb(dev, q, skb);
}
mt76_dma_rx_fill(dev, q, napi);
return done;
}
static const struct mt76_queue_ops mt76_dma_ops = {
.init = mt76_dma_init,
.alloc = mt76_dma_alloc_queue,
@@ -255,6 +327,7 @@ static const struct mt76_queue_ops mt76_dma_ops = {
.dequeue = mt76_dma_dequeue,
.tx_cleanup = mt76_dma_tx_cleanup,
.kick = mt76_dma_kick_queue,
.rx_process = mt76_dma_rx_process,
};
int mt76_dma_attach(struct mt76_dev *dev)
+6
View File
@@ -107,6 +107,8 @@ struct mt76_queue_ops {
int (*rx_fill)(struct mt76_dev *dev, struct mt76_queue *q, bool napi);
int (*rx_process)(struct mt76_dev *dev, struct mt76_queue *q, int budget);
void (*kick)(struct mt76_dev *dev, struct mt76_queue *q);
};
@@ -156,6 +158,9 @@ struct mt76_driver_ops {
int (*tx_queue_skb)(struct mt76_dev *dev, struct mt76_queue *q,
struct sk_buff *skb, struct mt76_txwi_cache *txwi,
struct mt76_wcid *wcid, struct ieee80211_sta *sta);
void (*rx_skb)(struct mt76_dev *mdev, struct mt76_queue *q,
struct sk_buff *skb);
};
struct mt76_dev {
@@ -233,6 +238,7 @@ static inline u16 mt76_rev(struct mt76_dev *dev)
#define mt76_queue_dequeue(dev, ...) (dev)->mt76.queue_ops->dequeue(&((dev)->mt76), __VA_ARGS__)
#define mt76_queue_tx_cleanup(dev, ...) (dev)->mt76.queue_ops->tx_cleanup(&((dev)->mt76), __VA_ARGS__)
#define mt76_queue_rx_fill(dev, ...) (dev)->mt76.queue_ops->rx_fill(&((dev)->mt76), __VA_ARGS__)
#define mt76_queue_rx_process(dev, ...) (dev)->mt76.queue_ops->rx_process(&((dev)->mt76), __VA_ARGS__)
#define mt76_queue_kick(dev, ...) (dev)->mt76.queue_ops->kick(&((dev)->mt76), __VA_ARGS__)
int mt76_register_device(struct mt76_dev *dev, bool vht,
+3
View File
@@ -227,4 +227,7 @@ void mt76x2_pre_tbtt_tasklet(unsigned long data);
void mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq);
void mt76x2_queue_rx_skb(struct mt76_dev *mdev, struct mt76_queue *q,
struct sk_buff *skb);
#endif
+6 -77
View File
@@ -122,13 +122,13 @@ mt76x2_init_tx_queue(struct mt76x2_dev *dev, struct mt76_queue *q,
return 0;
}
static void
mt76x2_process_rx_skb(struct mt76x2_dev *dev, struct mt76_queue *q,
struct sk_buff *skb)
void mt76x2_queue_rx_skb(struct mt76_dev *mdev, struct mt76_queue *q,
struct sk_buff *skb)
{
struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
void *rxwi = skb->data;
if (q == &dev->mt76.q_rx[MT_RXQ_MCU]) {
if (q == &mdev->q_rx[MT_RXQ_MCU]) {
skb_queue_tail(&dev->mcu.res_q, skb);
wake_up(&dev->mcu.wait);
return;
@@ -143,77 +143,6 @@ mt76x2_process_rx_skb(struct mt76x2_dev *dev, struct mt76_queue *q,
mt76x2_rx(dev, skb);
}
static void
mt76x2_add_fragment(struct mt76x2_dev *dev, struct mt76_queue *q, void *data,
int len, bool more)
{
struct page *page = virt_to_head_page(data);
int offset = data - page_address(page);
struct sk_buff *skb = q->rx_head;
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, offset, len,
q->buf_size);
if (!more) {
q->rx_head = NULL;
mt76x2_process_rx_skb(dev, q, skb);
}
}
static int
mt76x2_process_rx_queue(struct mt76x2_dev *dev, struct mt76_queue *q, int budget)
{
struct sk_buff *skb;
unsigned char *data;
int len;
int done = 0;
bool napi = q == &dev->mt76.q_rx[MT_RXQ_MAIN];
bool more;
while (done < budget) {
u32 info;
data = mt76_queue_dequeue(dev, q, false, &len, &info, &more);
if (!data)
break;
if (q->rx_head) {
mt76x2_add_fragment(dev, q, data, len, more);
continue;
}
skb = build_skb(data, q->buf_size);
if (!skb) {
skb_free_frag(data);
continue;
}
skb_reserve(skb, q->buf_offset);
if (skb->tail + len > skb->end) {
dev_kfree_skb(skb);
continue;
}
if (q == &dev->mt76.q_rx[MT_RXQ_MCU]) {
u32 * rxfce = (u32 *) skb->cb;
*rxfce = info;
}
__skb_put(skb, len);
done++;
if (more) {
q->rx_head = skb;
continue;
}
mt76x2_process_rx_skb(dev, q, skb);
}
mt76_queue_rx_fill(dev, q, napi);
return done;
}
static int
mt76x2_init_rx_queue(struct mt76x2_dev *dev, struct mt76_queue *q,
int idx, int n_desc, int bufsize)
@@ -254,7 +183,7 @@ mt76x2_dma_rx_poll(struct napi_struct *napi, int budget)
struct mt76x2_dev *dev = container_of(napi, struct mt76x2_dev, napi);
int done;
done = mt76x2_process_rx_queue(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], budget);
done = mt76_queue_rx_process(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], budget);
if (done < budget) {
napi_complete(napi);
@@ -270,7 +199,7 @@ mt76x2_rx_tasklet(unsigned long data)
struct mt76x2_dev *dev = (struct mt76x2_dev *) data;
struct mt76_queue *q = &dev->mt76.q_rx[MT_RXQ_MCU];
mt76x2_process_rx_queue(dev, q, q->ndesc);
mt76_queue_rx_process(dev, q, q->ndesc);
mt76x2_irq_enable(dev, MT_INT_RX_DONE(1));
}
+2 -1
View File
@@ -590,7 +590,8 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev)
{
static const struct mt76_driver_ops drv_ops = {
.fill_txwi = mt76x2_mac_write_txwi,
.tx_queue_skb = mt76x2_tx_queue_skb
.tx_queue_skb = mt76x2_tx_queue_skb,
.rx_skb = mt76x2_queue_rx_skb,
};
struct ieee80211_hw *hw;
struct mt76x2_dev *dev;