move txwi cache to core

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2015-12-17 15:50:01 +01:00
parent 85d62175b5
commit 1389db799a
10 changed files with 162 additions and 118 deletions
+2
View File
@@ -111,6 +111,8 @@ mt76_dma_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
q->swq_queued--;
done(dev, q, &entry);
if (entry.txwi)
mt76_put_txwi(dev, entry.txwi);
q->tail = (q->tail + 1) % q->ndesc;
q->queued--;
+12
View File
@@ -166,6 +166,9 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
struct wiphy *wiphy = hw->wiphy;
int ret;
spin_lock_init(&dev->lock);
INIT_LIST_HEAD(&dev->txwi_cache);
SET_IEEE80211_DEV(hw, dev->dev);
wiphy->interface_modes =
@@ -203,3 +206,12 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
return ieee80211_register_hw(hw);
}
EXPORT_SYMBOL_GPL(mt76_register_device);
void mt76_unregister_device(struct mt76_dev *dev)
{
struct ieee80211_hw *hw = dev->hw;
mt76_tx_free(dev);
ieee80211_unregister_hw(hw);
}
EXPORT_SYMBOL_GPL(mt76_unregister_device);
+24 -5
View File
@@ -51,7 +51,7 @@ struct mt76_queue_entry {
struct sk_buff *skb;
union {
void *buf;
struct mt76x2_txwi_cache *txwi;
struct mt76_txwi_cache *txwi;
};
bool schedule;
};
@@ -122,6 +122,12 @@ struct mt76_txq {
bool aggr;
};
struct mt76_txwi_cache {
u32 txwi[6];
dma_addr_t dma_addr;
struct list_head list;
};
enum {
MT76_STATE_INITIALIZED,
MT76_STATE_RUNNING,
@@ -134,19 +140,25 @@ struct mt76_hw_cap {
};
struct mt76_driver_ops {
int (*fill_txwi)(struct mt76_dev *dev, void *txwi_ptr,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta);
int (*tx_queue_skb)(struct mt76_dev *dev, struct mt76_queue *q,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta);
struct sk_buff *skb, struct mt76_txwi_cache *txwi,
struct mt76_wcid *wcid, struct ieee80211_sta *sta);
};
struct mt76_dev {
struct ieee80211_hw *hw;
spinlock_t lock;
const struct mt76_bus_ops *bus;
const struct mt76_driver_ops *drv;
void __iomem *regs;
struct device *dev;
struct list_head txwi_cache;
struct mt76_queue q_tx[__MT_TXQ_MAX];
const struct mt76_queue_ops *queue_ops;
@@ -211,10 +223,9 @@ static inline u16 mt76_rev(struct mt76_dev *dev)
#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__)
int mt76_register_device(struct mt76_dev *dev, bool vht,
struct ieee80211_rate *rates, int n_rates);
void mt76_unregister_device(struct mt76_dev *dev);
struct dentry *mt76_register_debugfs(struct mt76_dev *dev);
@@ -236,6 +247,10 @@ mtxq_to_txq(struct mt76_txq *mtxq)
return container_of(ptr, struct ieee80211_txq, drv_priv);
}
int mt76_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta);
void mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
struct mt76_wcid *wcid, struct sk_buff *skb);
void mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq);
@@ -249,4 +264,8 @@ void mt76_release_buffered_frames(struct ieee80211_hw *hw,
enum ieee80211_frame_release_type reason,
bool more_data);
/* internal */
void mt76_tx_free(struct mt76_dev *dev);
void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t);
#endif
+1 -1
View File
@@ -74,7 +74,7 @@ mt76pci_remove(struct pci_dev *pdev)
{
struct mt7603_dev *dev = pci_get_drvdata(pdev);
ieee80211_unregister_hw(mt76_hw(dev));
mt76_unregister_device(&dev->mt76);
mt7603_mcu_exit(dev);
mt7603_dma_cleanup(dev);
ieee80211_free_hw(mt76_hw(dev));
+3 -5
View File
@@ -104,7 +104,6 @@ struct mt76x2_dev {
u8 txdone_seq;
DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x2_tx_status);
struct list_head txwi_cache;
struct mt76x2_mcu mcu;
struct mt76_queue q_rx;
@@ -121,7 +120,6 @@ struct mt76x2_dev {
struct mt76_wcid __rcu *wcid[254 - 8];
spinlock_t lock;
spinlock_t irq_lock;
u32 irqmask;
@@ -219,9 +217,9 @@ 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);
int mt76x2_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta);
int mt76x2_tx_queue_skb(struct mt76_dev *cdev, struct mt76_queue *q,
struct sk_buff *skb, struct mt76_txwi_cache *t,
struct mt76_wcid *wcid, struct ieee80211_sta *sta);
int mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid,
struct sk_buff *skb, int cmd, int seq);
void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
+5 -90
View File
@@ -14,68 +14,6 @@
#include "mt76x2.h"
#include "mt76x2_dma.h"
struct mt76x2_txwi_cache {
u32 txwi[6];
dma_addr_t dma_addr;
struct list_head list;
};
static struct mt76x2_txwi_cache *
mt76x2_alloc_txwi(struct mt76x2_dev *dev)
{
struct mt76x2_txwi_cache *t;
dma_addr_t addr;
int size;
size = (sizeof(*t) + L1_CACHE_BYTES - 1) & ~(L1_CACHE_BYTES - 1);
t = devm_kzalloc(dev->mt76.dev, size, GFP_ATOMIC);
if (!t)
return NULL;
addr = dma_map_single(dev->mt76.dev, &t->txwi, sizeof(t->txwi), DMA_TO_DEVICE);
t->dma_addr = addr;
return t;
}
static struct mt76x2_txwi_cache *
__mt76x2_get_txwi(struct mt76x2_dev *dev)
{
struct mt76x2_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,
list);
list_del(&t->list);
}
spin_unlock_bh(&dev->lock);
return t;
}
static struct mt76x2_txwi_cache *
mt76x2_get_txwi(struct mt76x2_dev *dev)
{
struct mt76x2_txwi_cache *t = __mt76x2_get_txwi(dev);
if (t)
return t;
return mt76x2_alloc_txwi(dev);
}
static void
mt76x2_put_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi_cache *t)
{
if (!t)
return;
spin_lock_bh(&dev->lock);
list_add(&t->list, &dev->txwi_cache);
spin_unlock_bh(&dev->lock);
}
int
mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid,
struct sk_buff *skb, int cmd, int seq)
@@ -106,31 +44,19 @@ mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid,
int
mt76x2_tx_queue_skb(struct mt76_dev *cdev, struct mt76_queue *q,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta)
struct sk_buff *skb, struct mt76_txwi_cache *t,
struct mt76_wcid *wcid, struct ieee80211_sta *sta)
{
struct mt76x2_dev *dev = container_of(cdev, struct mt76x2_dev, mt76);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct mt76x2_txwi_cache *t;
dma_addr_t addr;
u32 tx_info = 0;
int idx, ret, len;
int qsel = MT_QSEL_EDCA;
ret = -ENOMEM;
t = mt76x2_get_txwi(dev);
if (!t)
goto free;
dma_sync_single_for_cpu(dev->mt76.dev, t->dma_addr, sizeof(t->txwi),
DMA_TO_DEVICE);
mt76x2_mac_write_txwi(dev, &t->txwi, skb, wcid, sta);
dma_sync_single_for_device(dev->mt76.dev, t->dma_addr, sizeof(t->txwi),
DMA_TO_DEVICE);
ret = mt76_insert_hdr_pad(skb);
if (ret)
goto put_txwi;
return ret;
if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
qsel = 0;
@@ -146,7 +72,7 @@ mt76x2_tx_queue_skb(struct mt76_dev *cdev, struct mt76_queue *q,
addr = dma_map_single(dev->mt76.dev, skb->data, skb->len, DMA_TO_DEVICE);
if (dma_mapping_error(dev->mt76.dev, addr))
goto put_txwi;
return -ENOMEM;
idx = mt76_queue_add_buf(dev, q, t->dma_addr, sizeof(struct mt76x2_txwi),
addr, skb->len, tx_info);
@@ -154,12 +80,6 @@ mt76x2_tx_queue_skb(struct mt76_dev *cdev, struct mt76_queue *q,
q->entry[idx].txwi = t;
return idx;
put_txwi:
mt76x2_put_txwi(dev, t);
free:
ieee80211_free_txskb(mt76_hw(dev), skb);
return ret;
}
static void
@@ -170,7 +90,6 @@ mt76x2_tx_cleanup_entry(struct mt76_dev *mdev, struct mt76_queue *q,
if (e->txwi) {
mt76x2_mac_queue_txdone(dev, e->skb, &e->txwi->txwi);
mt76x2_put_txwi(dev, e->txwi);
} else {
dev_kfree_skb_any(e->skb);
}
@@ -406,7 +325,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 __maybe_unused *t;
int i;
BUILD_BUG_ON(sizeof(t->txwi) < sizeof(struct mt76x2_txwi));
@@ -420,8 +339,4 @@ void mt76x2_dma_cleanup(struct mt76x2_dev *dev)
mt76_tx_cleanup(dev, &dev->mt76.q_tx[i], true);
mt76x2_rx_cleanup(dev, &dev->q_rx);
mt76x2_rx_cleanup(dev, &dev->mcu.q_rx);
while ((t = __mt76x2_get_txwi(dev)) != NULL)
dma_unmap_single(dev->mt76.dev, t->dma_addr, sizeof(t->txwi),
DMA_TO_DEVICE);
}
+1 -2
View File
@@ -561,6 +561,7 @@ void mt76x2_cleanup(struct mt76x2_dev *dev)
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
};
struct ieee80211_hw *hw;
@@ -575,7 +576,6 @@ struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev)
dev->mt76.hw = hw;
dev->mt76.drv = &drv_ops;
mutex_init(&dev->mutex);
spin_lock_init(&dev->lock);
spin_lock_init(&dev->irq_lock);
return dev;
@@ -681,7 +681,6 @@ int mt76x2_register_device(struct mt76x2_dev *dev)
wiphy->iface_combinations = if_comb;
wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
INIT_LIST_HEAD(&dev->txwi_cache);
INIT_DELAYED_WORK(&dev->cal_work, mt76x2_phy_calibrate);
INIT_DELAYED_WORK(&dev->mac_work, mt76x2_mac_work);
+11 -8
View File
@@ -145,16 +145,17 @@ mt76x2_mac_tx_rate_val(struct mt76x2_dev *dev, const struct ieee80211_tx_rate *r
void mt76x2_mac_wcid_set_rate(struct mt76x2_dev *dev, struct mt76_wcid *wcid,
const struct ieee80211_tx_rate *rate)
{
spin_lock_bh(&dev->lock);
spin_lock_bh(&dev->mt76.lock);
wcid->tx_rate = mt76x2_mac_tx_rate_val(dev, rate, &wcid->tx_rate_nss);
wcid->tx_rate_set = true;
spin_unlock_bh(&dev->lock);
spin_unlock_bh(&dev->mt76.lock);
}
void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, void *txwi_ptr,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta)
int mt76x2_mac_write_txwi(struct mt76_dev *mdev, void *txwi_ptr,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta)
{
struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rate = &info->control.rates[0];
struct mt76x2_txwi *txwi = txwi_ptr;
@@ -171,14 +172,14 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, void *txwi_ptr,
txwi->pktid = 1;
spin_lock_bh(&dev->lock);
spin_lock_bh(&dev->mt76.lock);
if (rate->idx < 0 || !rate->count) {
txwi->rate = wcid->tx_rate;
nss = wcid->tx_rate_nss;
} else {
txwi->rate = mt76x2_mac_tx_rate_val(dev, rate, &nss);
}
spin_unlock_bh(&dev->lock);
spin_unlock_bh(&dev->mt76.lock);
if (mt76xx_rev(dev) >= MT76XX_REV_E4)
txwi->txstream = 0x13;
@@ -211,6 +212,8 @@ void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, void *txwi_ptr,
txwi->flags |= cpu_to_le16(txwi_flags);
txwi->len_ctl = cpu_to_le16(skb->len);
return 0;
}
int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb, void *rxi)
@@ -583,7 +586,7 @@ mt76_write_beacon(struct mt76x2_dev *dev, int offset, struct sk_buff *skb)
if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x2_txwi)))
return -ENOSPC;
mt76x2_mac_write_txwi(dev, &txwi, skb, NULL, NULL);
mt76x2_mac_write_txwi(&dev->mt76, &txwi, skb, NULL, NULL);
txwi.flags |= cpu_to_le16(MT_TXWI_FLAGS_TS);
mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
+5 -7
View File
@@ -14,14 +14,12 @@
#ifndef __MT76x2_MAC_H
#define __MT76x2_MAC_H
#include "mt76.h"
struct mt76x2_dev;
struct mt76x2_sta;
struct mt76x2_vif;
struct mt76_wcid;
struct mt76x2_txwi;
struct mt76_queue;
struct mt76x2_txwi_cache;
struct mt76x2_tx_status {
u8 valid:1;
@@ -161,9 +159,9 @@ 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, void *txwi_ptr,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta);
int mt76x2_mac_write_txwi(struct mt76_dev *dev, void *txwi_ptr,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta);
void mt76x2_mac_wcid_setup(struct mt76x2_dev *dev, u8 idx, u8 vif_idx, u8 *mac);
int mt76x2_mac_wcid_set_key(struct mt76x2_dev *dev, u8 idx,
struct ieee80211_key_conf *key);
+98
View File
@@ -13,6 +13,71 @@
#include "mt76.h"
static struct mt76_txwi_cache *
mt76_alloc_txwi(struct mt76_dev *dev)
{
struct mt76_txwi_cache *t;
dma_addr_t addr;
int size;
size = (sizeof(*t) + L1_CACHE_BYTES - 1) & ~(L1_CACHE_BYTES - 1);
t = devm_kzalloc(dev->dev, size, GFP_ATOMIC);
if (!t)
return NULL;
addr = dma_map_single(dev->dev, &t->txwi, sizeof(t->txwi), DMA_TO_DEVICE);
t->dma_addr = addr;
return t;
}
static struct mt76_txwi_cache *
__mt76_get_txwi(struct mt76_dev *dev)
{
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 mt76_txwi_cache,
list);
list_del(&t->list);
}
spin_unlock_bh(&dev->lock);
return t;
}
static struct mt76_txwi_cache *
mt76_get_txwi(struct mt76_dev *dev)
{
struct mt76_txwi_cache *t = __mt76_get_txwi(dev);
if (t)
return t;
return mt76_alloc_txwi(dev);
}
void
mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
{
if (!t)
return;
spin_lock_bh(&dev->lock);
list_add(&t->list, &dev->txwi_cache);
spin_unlock_bh(&dev->lock);
}
void mt76_tx_free(struct mt76_dev *dev)
{
struct mt76_txwi_cache *t;
while ((t = __mt76_get_txwi(dev)) != NULL)
dma_unmap_single(dev->dev, t->dma_addr, sizeof(t->txwi),
DMA_TO_DEVICE);
}
static int
mt76_txq_get_qid(struct ieee80211_txq *txq)
{
@@ -22,6 +87,39 @@ mt76_txq_get_qid(struct ieee80211_txq *txq)
return txq->ac;
}
int mt76_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta)
{
struct mt76_txwi_cache *t;
int ret = -ENOMEM;
t = mt76_get_txwi(dev);
if (!t)
goto free;
dma_sync_single_for_cpu(dev->dev, t->dma_addr, sizeof(t->txwi),
DMA_TO_DEVICE);
ret = dev->drv->fill_txwi(dev, &t->txwi, skb, wcid, sta);
dma_sync_single_for_device(dev->dev, t->dma_addr, sizeof(t->txwi),
DMA_TO_DEVICE);
if (ret < 0)
goto free_txwi;
ret = dev->drv->tx_queue_skb(dev, q, skb, t, wcid, sta);
if (ret < 0)
goto free_txwi;
return ret;
free_txwi:
mt76_put_txwi(dev, t);
free:
ieee80211_free_txskb(dev->hw, skb);
return ret;
}
EXPORT_SYMBOL_GPL(mt76_tx_queue_skb);
void
mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
struct mt76_wcid *wcid, struct sk_buff *skb)