tx: move dma mapping code to core, unify tx callbacks into one that prepares tx_info, skb and txwi

Signed-off-by: Felix Fietkau <[email protected]>
This commit is contained in:
Felix Fietkau
2016-02-03 20:14:53 +01:00
parent 2c2fa07e98
commit b08f5433d1
12 changed files with 83 additions and 100 deletions
+4 -6
View File
@@ -147,13 +147,11 @@ 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);
u16 txwi_size;
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);
int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta, u32 *tx_info);
void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q,
struct sk_buff *skb);
+2 -5
View File
@@ -101,9 +101,6 @@ void mt7603_dma_cleanup(struct mt7603_dev *dev);
int mt7603_mcu_init(struct mt7603_dev *dev);
int mt7603_tx_queue_mcu(struct mt7603_dev *dev, enum mt76_txq_id qid,
struct sk_buff *skb);
int mt7603_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);
void mt7603_set_irq_mask(struct mt7603_dev *dev, u32 clear, u32 set);
@@ -134,9 +131,9 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, int wcid,
struct ieee80211_tx_rate *rates,
int n_rates);
int mt7603_mac_write_txwi(struct mt76_dev *mdev, void *txwi_ptr,
int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta);
struct ieee80211_sta *sta, u32 *tx_info);
void mt7603_queue_rx_skb(struct mt76_dev *dev, enum mt76_rxq_id q,
struct sk_buff *skb);
-21
View File
@@ -36,27 +36,6 @@ mt7603_tx_queue_mcu(struct mt7603_dev *dev, enum mt76_txq_id qid,
return 0;
}
int
mt7603_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)
{
struct mt7603_dev *dev = container_of(cdev, struct mt7603_dev, mt76);
dma_addr_t addr;
int idx;
addr = dma_map_single(dev->mt76.dev, skb->data, skb->len, DMA_TO_DEVICE);
if (dma_mapping_error(dev->mt76.dev, addr))
return -ENOMEM;
idx = mt76_queue_add_buf(dev, q, t->dma_addr, MT_TXD_SIZE,
addr, skb->len, 0);
q->entry[idx].skb = skb;
q->entry[idx].txwi = t;
return idx;
}
static void
mt7603_tx_cleanup_entry(struct mt76_dev *mdev, struct mt76_queue *q,
struct mt76_queue_entry *e)
+2 -2
View File
@@ -19,8 +19,8 @@
struct mt7603_dev *mt7603_alloc_device(struct device *pdev)
{
static const struct mt76_driver_ops drv_ops = {
.fill_txwi = mt7603_mac_write_txwi,
.tx_queue_skb = mt7603_tx_queue_skb,
.txwi_size = MT_TXD_SIZE,
.tx_prepare_skb = mt7603_tx_prepare_skb,
.rx_skb = mt7603_queue_rx_skb,
.rx_poll_complete = mt7603_rx_poll_complete,
};
+13 -5
View File
@@ -337,15 +337,14 @@ void mt7603_wtbl_set_rates(struct mt7603_dev *dev, int wcid,
bw_idx ? bw_idx - 1 : 7);
}
int mt7603_mac_write_txwi(struct mt76_dev *mdev, void *txwi_ptr,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta)
static int
mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta)
{
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rate = &info->control.rates[0];
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
__le32 *txwi = txwi_ptr;
int wlan_idx;
int hdr_len = ieee80211_get_hdrlen_from_skb(skb);
u8 frame_type, frame_subtype;
@@ -422,6 +421,15 @@ int mt7603_mac_write_txwi(struct mt76_dev *mdev, void *txwi_ptr,
return 0;
}
int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta, u32 *tx_info)
{
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
mt7603_mac_write_txwi(dev, txwi_ptr, skb, wcid, sta);
return 0;
}
void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data)
{
struct ieee80211_tx_info info = {};
+3 -3
View File
@@ -201,14 +201,14 @@ 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 *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,
struct sk_buff *skb);
void mt76x2_tx_complete(struct mt76x2_dev *dev, struct sk_buff *skb);
int mt76x2_tx_prepare_skb(struct mt76_dev *dev, void *txwi_ptr,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta, u32 *tx_info);
void mt76x2_pre_tbtt_tasklet(unsigned long data);
-40
View File
@@ -42,46 +42,6 @@ mt76x2_tx_queue_mcu(struct mt76x2_dev *dev, enum mt76_txq_id qid,
return 0;
}
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)
{
struct mt76x2_dev *dev = container_of(cdev, struct mt76x2_dev, mt76);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
dma_addr_t addr;
u32 tx_info = 0;
int idx, ret, len;
int qsel = MT_QSEL_EDCA;
ret = mt76_insert_hdr_pad(skb);
if (ret)
return ret;
if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
qsel = 0;
len = skb->len + sizeof(struct mt76x2_txwi);
len += mt76x2_mac_skb_tx_overhead(dev, skb);
tx_info = MT76_SET(MT_TXD_INFO_LEN, len) |
MT76_SET(MT_TXD_INFO_QSEL, qsel) |
MT_TXD_INFO_80211;
if (!wcid || wcid->hw_key_idx == 0xff)
tx_info |= MT_TXD_INFO_WIV;
addr = dma_map_single(dev->mt76.dev, skb->data, skb->len, DMA_TO_DEVICE);
if (dma_mapping_error(dev->mt76.dev, addr))
return -ENOMEM;
idx = mt76_queue_add_buf(dev, q, t->dma_addr, sizeof(struct mt76x2_txwi),
addr, skb->len, tx_info);
q->entry[idx].skb = skb;
q->entry[idx].txwi = t;
return idx;
}
static void
mt76x2_tx_cleanup_entry(struct mt76_dev *mdev, struct mt76_queue *q,
struct mt76_queue_entry *e)
+2 -2
View File
@@ -605,8 +605,8 @@ 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,
.txwi_size = sizeof(struct mt76x2_txwi),
.tx_prepare_skb = mt76x2_tx_prepare_skb,
.rx_skb = mt76x2_queue_rx_skb,
.rx_poll_complete = mt76x2_rx_poll_complete,
};
+4 -8
View File
@@ -151,14 +151,12 @@ void mt76x2_mac_wcid_set_rate(struct mt76x2_dev *dev, struct mt76_wcid *wcid,
spin_unlock_bh(&dev->mt76.lock);
}
int mt76x2_mac_write_txwi(struct mt76_dev *mdev, void *txwi_ptr,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta)
void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi,
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;
u16 rate_ht_mask = MT76_SET(MT_RXWI_RATE_PHY, BIT(1) | BIT(2));
u16 txwi_flags = 0;
u8 nss;
@@ -212,8 +210,6 @@ int mt76x2_mac_write_txwi(struct mt76_dev *mdev, 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)
@@ -595,7 +591,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->mt76, &txwi, skb, NULL, NULL);
mt76x2_mac_write_txwi(dev, &txwi, skb, NULL, NULL);
txwi.flags |= cpu_to_le16(MT_TXWI_FLAGS_TS);
mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
+3 -3
View File
@@ -159,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);
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_write_txwi(struct mt76x2_dev *dev, struct mt76x2_txwi *txwi,
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);
+31
View File
@@ -12,6 +12,7 @@
*/
#include "mt76x2.h"
#include "mt76x2_dma.h"
struct beacon_bc_data {
struct mt76x2_dev *dev;
@@ -57,6 +58,36 @@ void mt76x2_tx_complete(struct mt76x2_dev *dev, struct sk_buff *skb)
ieee80211_wake_queue(mt76_hw(dev), qid);
}
int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta, u32 *tx_info)
{
struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int len, qsel = MT_QSEL_EDCA;
int ret;
mt76x2_mac_write_txwi(dev, txwi, skb, wcid, sta);
ret = mt76_insert_hdr_pad(skb);
if (ret)
return ret;
if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
qsel = 0;
len = skb->len + sizeof(struct mt76x2_txwi);
len += mt76x2_mac_skb_tx_overhead(dev, skb);
*tx_info = MT76_SET(MT_TXD_INFO_LEN, len) |
MT76_SET(MT_TXD_INFO_QSEL, qsel) |
MT_TXD_INFO_80211;
if (!wcid || wcid->hw_key_idx == 0xff)
*tx_info |= MT_TXD_INFO_WIV;
return 0;
}
static void
mt76x2_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
{
+19 -5
View File
@@ -92,23 +92,37 @@ int mt76_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
struct ieee80211_sta *sta)
{
struct mt76_txwi_cache *t;
int ret = -ENOMEM;
dma_addr_t addr;
u32 tx_info = 0;
int ret;
t = mt76_get_txwi(dev);
if (!t)
if (!t) {
ret = -ENOMEM;
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);
ret = dev->drv->tx_prepare_skb(dev, &t->txwi, skb, wcid, sta, &tx_info);
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)
addr = dma_map_single(dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
if (dma_mapping_error(dev->dev, addr)) {
ret = -ENOMEM;
goto free_txwi;
}
ret = dev->queue_ops->add_buf(dev, q, t->dma_addr, dev->drv->txwi_size,
addr, skb->len, tx_info);
if (ret < 0)
return ret;
q->entry[ret].skb = skb;
q->entry[ret].txwi = t;
return ret;