diff options
| author | Kan Yan <kyan@google.com> | 2019-02-11 11:47:52 -0500 |
|---|---|---|
| committer | Kalle Valo <kvalo@codeaurora.org> | 2019-02-12 13:44:58 -0500 |
| commit | d1ce37b7831ac6445c60f34b680f7214359e87ab (patch) | |
| tree | d5a2f779c5aa31cb731c8cdbccb6be89fa40adda /drivers/net/wireless/ath | |
| parent | bb2edb733586527b8d0957d92f786daecb07e80b (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.h | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath10k/htt_rx.c | 1 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath10k/mac.c | 57 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath10k/txrx.c | 4 |
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, | |||
| 3544 | static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar, | 3544 | static 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 | ||
| 3566 | bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar) | 3567 | bool 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 */ | ||
| 3960 | static 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 | |||
| 3951 | int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw, | 3995 | int 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 | ||
