aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorKan Yan <kyan@google.com>2019-02-11 11:47:52 -0500
committerKalle Valo <kvalo@codeaurora.org>2019-02-12 13:44:58 -0500
commitd1ce37b7831ac6445c60f34b680f7214359e87ab (patch)
treed5a2f779c5aa31cb731c8cdbccb6be89fa40adda /drivers/net/wireless/ath
parentbb2edb733586527b8d0957d92f786daecb07e80b (diff)
ath10k: report estimated frame transmit airtime to improve fairness
The airtime of a transmitted frame will be estimated from last used tx rate which the firmware reports with the peer stats feature (WMI_SERVICE_PEER_STATS). The airtime is computed on the tx path and it will be reported to mac80211 upon tx completion. This change is based on Kan's orginal commit in Chromium tree ("CHROMIUM: ath10k: Implementing airtime fairness based TX scheduler") ref: https://chromium-review.googlesource.com/588190 Tested on QCA4019 with firmware version 10.4-3.2.1.1-00015 Tested on QCA9984 with firmware version 10.4-3.9.0.1-00005 Signed-off-by: Kan Yan <kyan@google.com> [rmanohar@codeaurora.org: ported only the airtime computation] Signed-off-by: Rajkumar Manoharan <rmanohar@codeaurora.org> [toke@redhat.com: Rebase to mac80211-next, add test note] Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c57
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c4
4 files changed, 61 insertions, 3 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 4b730eec88d2..59958664dde4 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -126,6 +126,7 @@ struct ath10k_skb_cb {
126 u8 flags; 126 u8 flags;
127 u8 eid; 127 u8 eid;
128 u16 msdu_id; 128 u16 msdu_id;
129 u16 airtime_est;
129 struct ieee80211_vif *vif; 130 struct ieee80211_vif *vif;
130 struct ieee80211_txq *txq; 131 struct ieee80211_txq *txq;
131} __packed; 132} __packed;
@@ -498,6 +499,7 @@ struct ath10k_sta {
498 u16 peer_id; 499 u16 peer_id;
499 struct rate_info txrate; 500 struct rate_info txrate;
500 struct ieee80211_tx_info tx_info; 501 struct ieee80211_tx_info tx_info;
502 u32 last_tx_bitrate;
501 503
502 struct work_struct update_wk; 504 struct work_struct update_wk;
503 u64 rx_duration; 505 u64 rx_duration;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 98c525189087..77f494d52ec3 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -3080,6 +3080,7 @@ ath10k_update_per_peer_tx_stats(struct ath10k *ar,
3080 3080
3081 arsta->txrate.nss = txrate.nss; 3081 arsta->txrate.nss = txrate.nss;
3082 arsta->txrate.bw = ath10k_bw_to_mac80211_bw(txrate.bw); 3082 arsta->txrate.bw = ath10k_bw_to_mac80211_bw(txrate.bw);
3083 arsta->last_tx_bitrate = cfg80211_calculate_bitrate(&arsta->txrate);
3083 if (sgi) 3084 if (sgi)
3084 arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; 3085 arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
3085 3086
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 0d5215da410a..88c7b58c9e2f 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3544,7 +3544,7 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3544static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar, 3544static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
3545 struct ieee80211_vif *vif, 3545 struct ieee80211_vif *vif,
3546 struct ieee80211_txq *txq, 3546 struct ieee80211_txq *txq,
3547 struct sk_buff *skb) 3547 struct sk_buff *skb, u16 airtime)
3548{ 3548{
3549 struct ieee80211_hdr *hdr = (void *)skb->data; 3549 struct ieee80211_hdr *hdr = (void *)skb->data;
3550 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb); 3550 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
@@ -3561,6 +3561,7 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
3561 3561
3562 cb->vif = vif; 3562 cb->vif = vif;
3563 cb->txq = txq; 3563 cb->txq = txq;
3564 cb->airtime_est = airtime;
3564} 3565}
3565 3566
3566bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar) 3567bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
@@ -3948,6 +3949,49 @@ static bool ath10k_mac_tx_can_push(struct ieee80211_hw *hw,
3948 return false; 3949 return false;
3949} 3950}
3950 3951
3952/* Return estimated airtime in microsecond, which is calculated using last
3953 * reported TX rate. This is just a rough estimation because host driver has no
3954 * knowledge of the actual transmit rate, retries or aggregation. If actual
3955 * airtime can be reported by firmware, then delta between estimated and actual
3956 * airtime can be adjusted from deficit.
3957 */
3958#define IEEE80211_ATF_OVERHEAD 100 /* IFS + some slot time */
3959#define IEEE80211_ATF_OVERHEAD_IFS 16 /* IFS only */
3960static u16 ath10k_mac_update_airtime(struct ath10k *ar,
3961 struct ieee80211_txq *txq,
3962 struct sk_buff *skb)
3963{
3964 struct ath10k_sta *arsta;
3965 u32 pktlen;
3966 u16 airtime = 0;
3967
3968 if (!txq || !txq->sta)
3969 return airtime;
3970
3971 spin_lock_bh(&ar->data_lock);
3972 arsta = (struct ath10k_sta *)txq->sta->drv_priv;
3973
3974 pktlen = skb->len + 38; /* Assume MAC header 30, SNAP 8 for most case */
3975 if (arsta->last_tx_bitrate) {
3976 /* airtime in us, last_tx_bitrate in 100kbps */
3977 airtime = (pktlen * 8 * (1000 / 100))
3978 / arsta->last_tx_bitrate;
3979 /* overhead for media access time and IFS */
3980 airtime += IEEE80211_ATF_OVERHEAD_IFS;
3981 } else {
3982 /* This is mostly for throttle excessive BC/MC frames, and the
3983 * airtime/rate doesn't need be exact. Airtime of BC/MC frames
3984 * in 2G get some discount, which helps prevent very low rate
3985 * frames from being blocked for too long.
3986 */
3987 airtime = (pktlen * 8 * (1000 / 100)) / 60; /* 6M */
3988 airtime += IEEE80211_ATF_OVERHEAD;
3989 }
3990 spin_unlock_bh(&ar->data_lock);
3991
3992 return airtime;
3993}
3994
3951int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw, 3995int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3952 struct ieee80211_txq *txq) 3996 struct ieee80211_txq *txq)
3953{ 3997{
@@ -3963,6 +4007,7 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3963 size_t skb_len; 4007 size_t skb_len;
3964 bool is_mgmt, is_presp; 4008 bool is_mgmt, is_presp;
3965 int ret; 4009 int ret;
4010 u16 airtime;
3966 4011
3967 spin_lock_bh(&ar->htt.tx_lock); 4012 spin_lock_bh(&ar->htt.tx_lock);
3968 ret = ath10k_htt_tx_inc_pending(htt); 4013 ret = ath10k_htt_tx_inc_pending(htt);
@@ -3980,7 +4025,8 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
3980 return -ENOENT; 4025 return -ENOENT;
3981 } 4026 }
3982 4027
3983 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb); 4028 airtime = ath10k_mac_update_airtime(ar, txq, skb);
4029 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb, airtime);
3984 4030
3985 skb_len = skb->len; 4031 skb_len = skb->len;
3986 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb); 4032 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
@@ -4247,8 +4293,10 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
4247 bool is_mgmt; 4293 bool is_mgmt;
4248 bool is_presp; 4294 bool is_presp;
4249 int ret; 4295 int ret;
4296 u16 airtime;
4250 4297
4251 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb); 4298 airtime = ath10k_mac_update_airtime(ar, txq, skb);
4299 ath10k_mac_tx_h_fill_cb(ar, vif, txq, skb, airtime);
4252 4300
4253 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb); 4301 txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
4254 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode); 4302 txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
@@ -8604,6 +8652,9 @@ int ath10k_mac_register(struct ath10k *ar)
8604 wiphy_ext_feature_set(ar->hw->wiphy, 8652 wiphy_ext_feature_set(ar->hw->wiphy,
8605 NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); 8653 NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
8606 8654
8655 if (ath10k_peer_stats_enabled(ar))
8656 wiphy_ext_feature_set(ar->hw->wiphy,
8657 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
8607 /* 8658 /*
8608 * on LL hardware queues are managed entirely by the FW 8659 * on LL hardware queues are managed entirely by the FW
8609 * so we only advertise to mac we can do the queues thing 8660 * so we only advertise to mac we can do the queues thing
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index f13d88906b5a..44c13b884603 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -95,6 +95,10 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
95 wake_up(&htt->empty_tx_wq); 95 wake_up(&htt->empty_tx_wq);
96 spin_unlock_bh(&htt->tx_lock); 96 spin_unlock_bh(&htt->tx_lock);
97 97
98 if (txq && txq->sta)
99 ieee80211_sta_register_airtime(txq->sta, txq->tid,
100 skb_cb->airtime_est, 0);
101
98 if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL) 102 if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL)
99 dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); 103 dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
100 104