From e394b5757badea65c578d0ece59e800c7bb19aa5 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 11 Oct 2019 22:57:08 +0200 Subject: [PATCH] mt76: add support for an extra wiphy in the tx status path This is preparation for supporting multiple wiphys per device to support the concurrent dual-band feature of MT7615D Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/dma.c | 4 +++- drivers/net/wireless/mediatek/mt76/mt76.h | 17 +++++++++++++ drivers/net/wireless/mediatek/mt76/tx.c | 29 +++++++++++++++++++---- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index eed387b10d48..67d10099cb71 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -286,6 +286,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid, struct mt76_tx_info tx_info = { .skb = skb, }; + struct ieee80211_hw *hw; int len, n = 0, ret = -ENOMEM; struct mt76_queue_entry e; struct mt76_txwi_cache *t; @@ -295,7 +296,8 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid, t = mt76_get_txwi(dev); if (!t) { - ieee80211_free_txskb(dev->hw, skb); + hw = mt76_tx_status_get_hw(dev, skb); + ieee80211_free_txskb(hw, skb); return -ENOMEM; } txwi = mt76_get_txwi_ptr(dev, t); diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 4fd36b3e9440..604d70fd06e7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -177,6 +177,9 @@ enum mt76_wcid_flags { #define MT76_N_WCIDS 128 +/* stored in ieee80211_tx_info::hw_queue */ +#define MT_TX_HW_QUEUE_EXT_PHY BIT(3) + DECLARE_EWMA(signal, 10, 8); #define MT_WCID_TX_INFO_RATE GENMASK(15, 0) @@ -793,6 +796,20 @@ u32 mt76_calc_tx_airtime(struct mt76_dev *dev, struct ieee80211_tx_info *info, int len); /* internal */ +static inline struct ieee80211_hw * +mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hw *hw = dev->phy.hw; + + if ((info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY) && dev->phy2) + hw = dev->phy2->hw; + + info->hw_queue &= ~MT_TX_HW_QUEUE_EXT_PHY; + + return hw; +} + void mt76_tx_free(struct mt76_dev *dev); struct mt76_txwi_cache *mt76_get_txwi(struct mt76_dev *dev); void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c index d9fccbeff206..c993ad7ef2e3 100644 --- a/drivers/net/wireless/mediatek/mt76/tx.c +++ b/drivers/net/wireless/mediatek/mt76/tx.c @@ -109,13 +109,17 @@ void mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list) __releases(&dev->status_list.unlock) { + struct ieee80211_hw *hw; struct sk_buff *skb; spin_unlock_bh(&dev->status_list.lock); __release(&dev->status_list.unlock); - while ((skb = __skb_dequeue(list)) != NULL) - ieee80211_tx_status(dev->hw, skb); + while ((skb = __skb_dequeue(list)) != NULL) { + hw = mt76_tx_status_get_hw(dev, skb); + ieee80211_tx_status(hw, skb); + } + } EXPORT_SYMBOL_GPL(mt76_tx_status_unlock); @@ -231,10 +235,12 @@ EXPORT_SYMBOL_GPL(mt76_tx_status_check); void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb) { + struct ieee80211_hw *hw; struct sk_buff_head list; if (!skb->prev) { - ieee80211_free_txskb(dev->hw, skb); + hw = mt76_tx_status_get_hw(dev, skb); + ieee80211_free_txskb(hw, skb); return; } @@ -253,6 +259,7 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta, struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct mt76_queue *q; int qid = skb_get_queue_mapping(skb); + bool ext_phy = phy != &dev->phy; if (WARN_ON(qid >= MT_TXQ_PSD)) { qid = MT_TXQ_BE; @@ -276,6 +283,9 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta, mt76_check_agg_ssn(mtxq, skb); } + if (ext_phy) + info->hw_queue |= MT_TX_HW_QUEUE_EXT_PHY; + q = dev->q_tx[qid].q; spin_lock_bh(&q->lock); @@ -295,6 +305,8 @@ static struct sk_buff * mt76_txq_dequeue(struct mt76_phy *phy, struct mt76_txq *mtxq, bool ps) { struct ieee80211_txq *txq = mtxq_to_txq(mtxq); + struct ieee80211_tx_info *info; + bool ext_phy = phy != &phy->dev->phy; struct sk_buff *skb; skb = skb_dequeue(&mtxq->retry_q); @@ -311,6 +323,10 @@ mt76_txq_dequeue(struct mt76_phy *phy, struct mt76_txq *mtxq, bool ps) if (!skb) return NULL; + info = IEEE80211_SKB_CB(skb); + if (ext_phy) + info->hw_queue |= MT_TX_HW_QUEUE_EXT_PHY; + return skb; } @@ -597,6 +613,7 @@ EXPORT_SYMBOL_GPL(mt76_wake_tx_queue); void mt76_txq_remove(struct mt76_dev *dev, struct ieee80211_txq *txq) { + struct ieee80211_hw *hw; struct mt76_txq *mtxq; struct sk_buff *skb; @@ -605,8 +622,10 @@ void mt76_txq_remove(struct mt76_dev *dev, struct ieee80211_txq *txq) mtxq = (struct mt76_txq *)txq->drv_priv; - while ((skb = skb_dequeue(&mtxq->retry_q)) != NULL) - ieee80211_free_txskb(dev->hw, skb); + while ((skb = skb_dequeue(&mtxq->retry_q)) != NULL) { + hw = mt76_tx_status_get_hw(dev, skb); + ieee80211_free_txskb(hw, skb); + } } EXPORT_SYMBOL_GPL(mt76_txq_remove); -- 2.20.1