From b08f5433d111282ff2a57d4a6065a7005f7ff830 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 3 Feb 2016 18:28:13 +0100 Subject: [PATCH] tx: move dma mapping code to core, unify tx callbacks into one that prepares tx_info, skb and txwi Signed-off-by: Felix Fietkau --- mt76.h | 10 ++++------ mt7603.h | 7 ++----- mt7603_dma.c | 21 --------------------- mt7603_init.c | 4 ++-- mt7603_mac.c | 18 +++++++++++++----- mt76x2.h | 6 +++--- mt76x2_dma.c | 40 ---------------------------------------- mt76x2_init.c | 4 ++-- mt76x2_mac.c | 12 ++++-------- mt76x2_mac.h | 6 +++--- mt76x2_tx.c | 31 +++++++++++++++++++++++++++++++ tx.c | 24 +++++++++++++++++++----- 12 files changed, 83 insertions(+), 100 deletions(-) diff --git a/mt76.h b/mt76.h index 6210df3f..795d287e 100644 --- a/mt76.h +++ b/mt76.h @@ -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); diff --git a/mt7603.h b/mt7603.h index 5f486ddc..ddc14895 100644 --- a/mt7603.h +++ b/mt7603.h @@ -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); diff --git a/mt7603_dma.c b/mt7603_dma.c index e6f7a51e..ed148176 100644 --- a/mt7603_dma.c +++ b/mt7603_dma.c @@ -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) diff --git a/mt7603_init.c b/mt7603_init.c index 3ffb5a57..ea590046 100644 --- a/mt7603_init.c +++ b/mt7603_init.c @@ -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, }; diff --git a/mt7603_mac.c b/mt7603_mac.c index b5ae5fb1..2cc9047d 100644 --- a/mt7603_mac.c +++ b/mt7603_mac.c @@ -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 = {}; diff --git a/mt76x2.h b/mt76x2.h index a61f801a..44816554 100644 --- a/mt76x2.h +++ b/mt76x2.h @@ -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); diff --git a/mt76x2_dma.c b/mt76x2_dma.c index 95d47aa2..d29464b3 100644 --- a/mt76x2_dma.c +++ b/mt76x2_dma.c @@ -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) diff --git a/mt76x2_init.c b/mt76x2_init.c index 6deb6242..2ba85d0e 100644 --- a/mt76x2_init.c +++ b/mt76x2_init.c @@ -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, }; diff --git a/mt76x2_mac.c b/mt76x2_mac.c index e7db09f8..53efec38 100644 --- a/mt76x2_mac.c +++ b/mt76x2_mac.c @@ -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)); diff --git a/mt76x2_mac.h b/mt76x2_mac.h index 38bd60a4..f6cb88ab 100644 --- a/mt76x2_mac.h +++ b/mt76x2_mac.h @@ -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); diff --git a/mt76x2_tx.c b/mt76x2_tx.c index 95622307..e98fa172 100644 --- a/mt76x2_tx.c +++ b/mt76x2_tx.c @@ -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) { diff --git a/tx.c b/tx.c index 14423b96..884f355f 100644 --- a/tx.c +++ b/tx.c @@ -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;