diff options
author | Yan-Hsuan Chuang <yhchuang@realtek.com> | 2019-10-02 09:35:21 +0300 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2019-10-04 16:44:56 +0300 |
commit | 46ebb1743f339eae14daaa3afe094957f6b67d1d (patch) | |
tree | b12411c21eb411a838586da234285dcb1acd24b1 /drivers/net/wireless/realtek/rtw88/tx.c | |
parent | 3745d3e550d1e6c4301596ac05a5fe82c11301ce (diff) | |
download | linux-46ebb1743f339eae14daaa3afe094957f6b67d1d.tar.xz |
rtw88: take over rate control from mac80211
We can indicate IEEE80211_HW_HAS_RATE_CONTROL to mac80211 because
the hardware has its own rate control algorithm. And what driver needs
to do is to choose an RA mask according the peer's capabilities.
But the hardware is not able to setup BA session by itself. So driver
requires to initiate tx BA session for hardware, and tells it if it is
possible to transmit AMPDU. The hardware can then aggregate MPDUs.
And the size of AMPDU is controlled by the TX descriptor and the
register value. Since the TX descriptor will reference the max AMPDU
size from ieee80211_sta::ht_cap::ampdu_factor, just set the register
value to 0x3f, and let it be controlled by TX descriptor.
Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/realtek/rtw88/tx.c')
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/tx.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c index 1e19bdac1d45..24c39c60c99a 100644 --- a/drivers/net/wireless/realtek/rtw88/tx.c +++ b/drivers/net/wireless/realtek/rtw88/tx.c @@ -384,6 +384,38 @@ out: ieee80211_free_txskb(rtwdev->hw, skb); } +static void rtw_txq_check_agg(struct rtw_dev *rtwdev, + struct rtw_txq *rtwtxq, + struct sk_buff *skb) +{ + struct ieee80211_txq *txq = rtwtxq_to_txq(rtwtxq); + struct ieee80211_tx_info *info; + struct rtw_sta_info *si; + + if (test_bit(RTW_TXQ_AMPDU, &rtwtxq->flags)) { + info = IEEE80211_SKB_CB(skb); + info->flags |= IEEE80211_TX_CTL_AMPDU; + return; + } + + if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) + return; + + if (test_bit(RTW_TXQ_BLOCK_BA, &rtwtxq->flags)) + return; + + if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) + return; + + if (!txq->sta) + return; + + si = (struct rtw_sta_info *)txq->sta->drv_priv; + set_bit(txq->tid, si->tid_ba); + + ieee80211_queue_work(rtwdev->hw, &rtwdev->ba_work); +} + static bool rtw_txq_dequeue(struct rtw_dev *rtwdev, struct rtw_txq *rtwtxq) { @@ -395,6 +427,8 @@ static bool rtw_txq_dequeue(struct rtw_dev *rtwdev, if (!skb) return false; + rtw_txq_check_agg(rtwdev, rtwtxq, skb); + control.sta = txq->sta; rtw_tx(rtwdev, &control, skb); rtwtxq->last_push = jiffies; |