mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-07-01 16:27:08 +08:00
534 lines
16 KiB
Diff
534 lines
16 KiB
Diff
From 1b8bb94c0612cf32e418e90ae93cf37214d84669 Mon Sep 17 00:00:00 2001
|
|
From: Wen Gong <quic_wgong@quicinc.com>
|
|
Date: Mon, 20 Dec 2021 18:11:09 +0200
|
|
Subject: [PATCH 146/151] ath11k: report tx bitrate for iw wlan station dump
|
|
|
|
HTT_T2H_MSG_TYPE_PPDU_STATS_IND is a message which include the ppdu
|
|
info, currently it is not report from firmware for ath11k, then the
|
|
tx bitrate of "iw wlan0 station dump" always show an invalid value
|
|
"tx bitrate: 6.0 MBit/s".
|
|
|
|
To address the issue, this is to parse the info of tx complete report
|
|
from firmware and indicate the tx rate to mac80211.
|
|
|
|
After that, "iw wlan0 station dump" show the correct tx bit rate such
|
|
as:
|
|
tx bitrate: 78.0 MBit/s MCS 12
|
|
tx bitrate: 144.4 MBit/s VHT-MCS 7 short GI VHT-NSS 2
|
|
tx bitrate: 286.7 MBit/s HE-MCS 11 HE-NSS 2 HE-GI 0 HE-DCM 0
|
|
tx bitrate: 1921.5 MBit/s 160MHz HE-MCS 9 HE-NSS 2 HE-GI 0 HE-DCM 0
|
|
|
|
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1
|
|
|
|
Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
|
|
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
|
|
Link: https://lore.kernel.org/r/20211217093722.5739-1-quic_wgong@quicinc.com
|
|
---
|
|
drivers/net/wireless/ath/ath11k/core.h | 1 +
|
|
drivers/net/wireless/ath/ath11k/debugfs_sta.c | 78 +------------
|
|
drivers/net/wireless/ath/ath11k/debugfs_sta.h | 2 -
|
|
drivers/net/wireless/ath/ath11k/dp_rx.c | 28 +----
|
|
drivers/net/wireless/ath/ath11k/dp_tx.c | 106 +++++++++++++++++-
|
|
drivers/net/wireless/ath/ath11k/dp_tx.h | 1 +
|
|
drivers/net/wireless/ath/ath11k/hal_rx.c | 4 +-
|
|
drivers/net/wireless/ath/ath11k/hal_rx.h | 27 -----
|
|
drivers/net/wireless/ath/ath11k/mac.c | 93 +++++++++++++++
|
|
drivers/net/wireless/ath/ath11k/mac.h | 3 +
|
|
10 files changed, 210 insertions(+), 133 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/core.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/core.h
|
|
@@ -382,6 +382,7 @@ struct ath11k_sta {
|
|
struct work_struct update_wk;
|
|
struct work_struct set_4addr_wk;
|
|
struct rate_info txrate;
|
|
+ u32 peer_nss;
|
|
struct rate_info last_txrate;
|
|
u64 rx_duration;
|
|
u64 tx_duration;
|
|
--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c
|
|
@@ -126,85 +126,9 @@ void ath11k_debugfs_sta_add_tx_stats(str
|
|
}
|
|
|
|
void ath11k_debugfs_sta_update_txcompl(struct ath11k *ar,
|
|
- struct sk_buff *msdu,
|
|
struct hal_tx_status *ts)
|
|
{
|
|
- struct ath11k_base *ab = ar->ab;
|
|
- struct ath11k_per_peer_tx_stats *peer_stats = &ar->cached_stats;
|
|
- enum hal_tx_rate_stats_pkt_type pkt_type;
|
|
- enum hal_tx_rate_stats_sgi sgi;
|
|
- enum hal_tx_rate_stats_bw bw;
|
|
- struct ath11k_peer *peer;
|
|
- struct ath11k_sta *arsta;
|
|
- struct ieee80211_sta *sta;
|
|
- u16 rate;
|
|
- u8 rate_idx = 0;
|
|
- int ret;
|
|
- u8 mcs;
|
|
-
|
|
- rcu_read_lock();
|
|
- spin_lock_bh(&ab->base_lock);
|
|
- peer = ath11k_peer_find_by_id(ab, ts->peer_id);
|
|
- if (!peer || !peer->sta) {
|
|
- ath11k_warn(ab, "failed to find the peer\n");
|
|
- spin_unlock_bh(&ab->base_lock);
|
|
- rcu_read_unlock();
|
|
- return;
|
|
- }
|
|
-
|
|
- sta = peer->sta;
|
|
- arsta = (struct ath11k_sta *)sta->drv_priv;
|
|
-
|
|
- memset(&arsta->txrate, 0, sizeof(arsta->txrate));
|
|
- pkt_type = FIELD_GET(HAL_TX_RATE_STATS_INFO0_PKT_TYPE,
|
|
- ts->rate_stats);
|
|
- mcs = FIELD_GET(HAL_TX_RATE_STATS_INFO0_MCS,
|
|
- ts->rate_stats);
|
|
- sgi = FIELD_GET(HAL_TX_RATE_STATS_INFO0_SGI,
|
|
- ts->rate_stats);
|
|
- bw = FIELD_GET(HAL_TX_RATE_STATS_INFO0_BW, ts->rate_stats);
|
|
-
|
|
- if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11A ||
|
|
- pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11B) {
|
|
- ret = ath11k_mac_hw_ratecode_to_legacy_rate(mcs,
|
|
- pkt_type,
|
|
- &rate_idx,
|
|
- &rate);
|
|
- if (ret < 0)
|
|
- goto err_out;
|
|
- arsta->txrate.legacy = rate;
|
|
- } else if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11N) {
|
|
- if (mcs > 7) {
|
|
- ath11k_warn(ab, "Invalid HT mcs index %d\n", mcs);
|
|
- goto err_out;
|
|
- }
|
|
-
|
|
- arsta->txrate.mcs = mcs + 8 * (arsta->last_txrate.nss - 1);
|
|
- arsta->txrate.flags = RATE_INFO_FLAGS_MCS;
|
|
- if (sgi)
|
|
- arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
|
- } else if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AC) {
|
|
- if (mcs > 9) {
|
|
- ath11k_warn(ab, "Invalid VHT mcs index %d\n", mcs);
|
|
- goto err_out;
|
|
- }
|
|
-
|
|
- arsta->txrate.mcs = mcs;
|
|
- arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
|
|
- if (sgi)
|
|
- arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
|
- } else if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AX) {
|
|
- /* TODO */
|
|
- }
|
|
-
|
|
- arsta->txrate.nss = arsta->last_txrate.nss;
|
|
- arsta->txrate.bw = ath11k_mac_bw_to_mac80211_bw(bw);
|
|
-
|
|
- ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx);
|
|
-
|
|
-err_out:
|
|
- spin_unlock_bh(&ab->base_lock);
|
|
- rcu_read_unlock();
|
|
+ ath11k_dp_tx_update_txcompl(ar, ts);
|
|
}
|
|
|
|
static ssize_t ath11k_dbg_sta_dump_tx_stats(struct file *file,
|
|
--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.h
|
|
@@ -19,7 +19,6 @@ void ath11k_debugfs_sta_add_tx_stats(str
|
|
struct ath11k_per_peer_tx_stats *peer_stats,
|
|
u8 legacy_rate_idx);
|
|
void ath11k_debugfs_sta_update_txcompl(struct ath11k *ar,
|
|
- struct sk_buff *msdu,
|
|
struct hal_tx_status *ts);
|
|
|
|
#else /* CPTCFG_ATH11K_DEBUGFS */
|
|
@@ -34,7 +33,6 @@ ath11k_debugfs_sta_add_tx_stats(struct a
|
|
}
|
|
|
|
static inline void ath11k_debugfs_sta_update_txcompl(struct ath11k *ar,
|
|
- struct sk_buff *msdu,
|
|
struct hal_tx_status *ts)
|
|
{
|
|
}
|
|
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
|
@@ -1360,25 +1360,6 @@ int ath11k_dp_htt_tlv_iter(struct ath11k
|
|
return 0;
|
|
}
|
|
|
|
-static inline u32 ath11k_he_gi_to_nl80211_he_gi(u8 sgi)
|
|
-{
|
|
- u32 ret = 0;
|
|
-
|
|
- switch (sgi) {
|
|
- case RX_MSDU_START_SGI_0_8_US:
|
|
- ret = NL80211_RATE_INFO_HE_GI_0_8;
|
|
- break;
|
|
- case RX_MSDU_START_SGI_1_6_US:
|
|
- ret = NL80211_RATE_INFO_HE_GI_1_6;
|
|
- break;
|
|
- case RX_MSDU_START_SGI_3_2_US:
|
|
- ret = NL80211_RATE_INFO_HE_GI_3_2;
|
|
- break;
|
|
- }
|
|
-
|
|
- return ret;
|
|
-}
|
|
-
|
|
static void
|
|
ath11k_update_per_peer_tx_stats(struct ath11k *ar,
|
|
struct htt_ppdu_stats *ppdu_stats, u8 user)
|
|
@@ -1497,14 +1478,15 @@ ath11k_update_per_peer_tx_stats(struct a
|
|
arsta->txrate.mcs = mcs;
|
|
arsta->txrate.flags = RATE_INFO_FLAGS_HE_MCS;
|
|
arsta->txrate.he_dcm = dcm;
|
|
- arsta->txrate.he_gi = ath11k_he_gi_to_nl80211_he_gi(sgi);
|
|
- arsta->txrate.he_ru_alloc = ath11k_he_ru_tones_to_nl80211_he_ru_alloc(
|
|
- (user_rate->ru_end -
|
|
+ arsta->txrate.he_gi = ath11k_mac_he_gi_to_nl80211_he_gi(sgi);
|
|
+ arsta->txrate.he_ru_alloc = ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc
|
|
+ ((user_rate->ru_end -
|
|
user_rate->ru_start) + 1);
|
|
break;
|
|
}
|
|
|
|
arsta->txrate.nss = nss;
|
|
+
|
|
arsta->txrate.bw = ath11k_mac_bw_to_mac80211_bw(bw);
|
|
arsta->tx_duration += tx_duration;
|
|
memcpy(&arsta->last_txrate, &arsta->txrate, sizeof(struct rate_info));
|
|
@@ -2384,7 +2366,7 @@ static void ath11k_dp_rx_h_rate(struct a
|
|
}
|
|
rx_status->encoding = RX_ENC_HE;
|
|
rx_status->nss = nss;
|
|
- rx_status->he_gi = ath11k_he_gi_to_nl80211_he_gi(sgi);
|
|
+ rx_status->he_gi = ath11k_mac_he_gi_to_nl80211_he_gi(sgi);
|
|
rx_status->bw = ath11k_mac_bw_to_mac80211_bw(bw);
|
|
break;
|
|
}
|
|
--- a/drivers/net/wireless/ath/ath11k/dp_tx.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.c
|
|
@@ -415,6 +415,105 @@ static void ath11k_dp_tx_cache_peer_stat
|
|
}
|
|
}
|
|
|
|
+void ath11k_dp_tx_update_txcompl(struct ath11k *ar, struct hal_tx_status *ts)
|
|
+{
|
|
+ struct ath11k_base *ab = ar->ab;
|
|
+ struct ath11k_per_peer_tx_stats *peer_stats = &ar->cached_stats;
|
|
+ enum hal_tx_rate_stats_pkt_type pkt_type;
|
|
+ enum hal_tx_rate_stats_sgi sgi;
|
|
+ enum hal_tx_rate_stats_bw bw;
|
|
+ struct ath11k_peer *peer;
|
|
+ struct ath11k_sta *arsta;
|
|
+ struct ieee80211_sta *sta;
|
|
+ u16 rate, ru_tones;
|
|
+ u8 mcs, rate_idx, ofdma;
|
|
+ int ret;
|
|
+
|
|
+ spin_lock_bh(&ab->base_lock);
|
|
+ peer = ath11k_peer_find_by_id(ab, ts->peer_id);
|
|
+ if (!peer || !peer->sta) {
|
|
+ ath11k_dbg(ab, ATH11K_DBG_DP_TX,
|
|
+ "failed to find the peer by id %u\n", ts->peer_id);
|
|
+ goto err_out;
|
|
+ }
|
|
+
|
|
+ sta = peer->sta;
|
|
+ arsta = (struct ath11k_sta *)sta->drv_priv;
|
|
+
|
|
+ memset(&arsta->txrate, 0, sizeof(arsta->txrate));
|
|
+ pkt_type = FIELD_GET(HAL_TX_RATE_STATS_INFO0_PKT_TYPE,
|
|
+ ts->rate_stats);
|
|
+ mcs = FIELD_GET(HAL_TX_RATE_STATS_INFO0_MCS,
|
|
+ ts->rate_stats);
|
|
+ sgi = FIELD_GET(HAL_TX_RATE_STATS_INFO0_SGI,
|
|
+ ts->rate_stats);
|
|
+ bw = FIELD_GET(HAL_TX_RATE_STATS_INFO0_BW, ts->rate_stats);
|
|
+ ru_tones = FIELD_GET(HAL_TX_RATE_STATS_INFO0_TONES_IN_RU, ts->rate_stats);
|
|
+ ofdma = FIELD_GET(HAL_TX_RATE_STATS_INFO0_OFDMA_TX, ts->rate_stats);
|
|
+
|
|
+ /* This is to prefer choose the real NSS value arsta->last_txrate.nss,
|
|
+ * if it is invalid, then choose the NSS value while assoc.
|
|
+ */
|
|
+ if (arsta->last_txrate.nss)
|
|
+ arsta->txrate.nss = arsta->last_txrate.nss;
|
|
+ else
|
|
+ arsta->txrate.nss = arsta->peer_nss;
|
|
+
|
|
+ if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11A ||
|
|
+ pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11B) {
|
|
+ ret = ath11k_mac_hw_ratecode_to_legacy_rate(mcs,
|
|
+ pkt_type,
|
|
+ &rate_idx,
|
|
+ &rate);
|
|
+ if (ret < 0)
|
|
+ goto err_out;
|
|
+ arsta->txrate.legacy = rate;
|
|
+ } else if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11N) {
|
|
+ if (mcs > 7) {
|
|
+ ath11k_warn(ab, "Invalid HT mcs index %d\n", mcs);
|
|
+ goto err_out;
|
|
+ }
|
|
+
|
|
+ if (arsta->txrate.nss != 0)
|
|
+ arsta->txrate.mcs = mcs + 8 * (arsta->txrate.nss - 1);
|
|
+ arsta->txrate.flags = RATE_INFO_FLAGS_MCS;
|
|
+ if (sgi)
|
|
+ arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
|
+ } else if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AC) {
|
|
+ if (mcs > 9) {
|
|
+ ath11k_warn(ab, "Invalid VHT mcs index %d\n", mcs);
|
|
+ goto err_out;
|
|
+ }
|
|
+
|
|
+ arsta->txrate.mcs = mcs;
|
|
+ arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
|
|
+ if (sgi)
|
|
+ arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
|
+ } else if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AX) {
|
|
+ if (mcs > 11) {
|
|
+ ath11k_warn(ab, "Invalid HE mcs index %d\n", mcs);
|
|
+ goto err_out;
|
|
+ }
|
|
+
|
|
+ arsta->txrate.mcs = mcs;
|
|
+ arsta->txrate.flags = RATE_INFO_FLAGS_HE_MCS;
|
|
+ arsta->txrate.he_gi = ath11k_mac_he_gi_to_nl80211_he_gi(sgi);
|
|
+ }
|
|
+
|
|
+ arsta->txrate.bw = ath11k_mac_bw_to_mac80211_bw(bw);
|
|
+ if (ofdma && pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AX) {
|
|
+ arsta->txrate.bw = RATE_INFO_BW_HE_RU;
|
|
+ arsta->txrate.he_ru_alloc =
|
|
+ ath11k_mac_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones);
|
|
+ }
|
|
+
|
|
+ if (ath11k_debugfs_is_extd_tx_stats_enabled(ar))
|
|
+ ath11k_debugfs_sta_add_tx_stats(arsta, peer_stats, rate_idx);
|
|
+
|
|
+err_out:
|
|
+ spin_unlock_bh(&ab->base_lock);
|
|
+}
|
|
+
|
|
static void ath11k_dp_tx_complete_msdu(struct ath11k *ar,
|
|
struct sk_buff *msdu,
|
|
struct hal_tx_status *ts)
|
|
@@ -460,7 +559,8 @@ static void ath11k_dp_tx_complete_msdu(s
|
|
(info->flags & IEEE80211_TX_CTL_NO_ACK))
|
|
info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
|
|
|
|
- if (unlikely(ath11k_debugfs_is_extd_tx_stats_enabled(ar))) {
|
|
+ if (unlikely(ath11k_debugfs_is_extd_tx_stats_enabled(ar)) ||
|
|
+ ab->hw_params.single_pdev_only) {
|
|
if (ts->flags & HAL_TX_STATUS_FLAGS_FIRST_MSDU) {
|
|
if (ar->last_ppdu_id == 0) {
|
|
ar->last_ppdu_id = ts->ppdu_id;
|
|
@@ -468,12 +568,12 @@ static void ath11k_dp_tx_complete_msdu(s
|
|
ar->cached_ppdu_id == ar->last_ppdu_id) {
|
|
ar->cached_ppdu_id = ar->last_ppdu_id;
|
|
ar->cached_stats.is_ampdu = true;
|
|
- ath11k_debugfs_sta_update_txcompl(ar, msdu, ts);
|
|
+ ath11k_dp_tx_update_txcompl(ar, ts);
|
|
memset(&ar->cached_stats, 0,
|
|
sizeof(struct ath11k_per_peer_tx_stats));
|
|
} else {
|
|
ar->cached_stats.is_ampdu = false;
|
|
- ath11k_debugfs_sta_update_txcompl(ar, msdu, ts);
|
|
+ ath11k_dp_tx_update_txcompl(ar, ts);
|
|
memset(&ar->cached_stats, 0,
|
|
sizeof(struct ath11k_per_peer_tx_stats));
|
|
}
|
|
--- a/drivers/net/wireless/ath/ath11k/dp_tx.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/dp_tx.h
|
|
@@ -15,6 +15,7 @@ struct ath11k_dp_htt_wbm_tx_status {
|
|
int ack_rssi;
|
|
};
|
|
|
|
+void ath11k_dp_tx_update_txcompl(struct ath11k *ar, struct hal_tx_status *ts);
|
|
int ath11k_dp_tx_htt_h2t_ver_req_msg(struct ath11k_base *ab);
|
|
int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
|
struct ath11k_sta *arsta, struct sk_buff *skb);
|
|
--- a/drivers/net/wireless/ath/ath11k/hal_rx.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
|
|
@@ -1039,7 +1039,9 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
|
|
|
|
ru_tones = FIELD_GET(HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION,
|
|
info0);
|
|
- ppdu_info->ru_alloc = ath11k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones);
|
|
+ ppdu_info->ru_alloc =
|
|
+ ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(ru_tones);
|
|
+
|
|
ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;
|
|
break;
|
|
}
|
|
--- a/drivers/net/wireless/ath/ath11k/hal_rx.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.h
|
|
@@ -363,33 +363,6 @@ ath11k_hal_rx_parse_mon_status(struct at
|
|
struct hal_rx_mon_ppdu_info *ppdu_info,
|
|
struct sk_buff *skb);
|
|
|
|
-static inline u32 ath11k_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones)
|
|
-{
|
|
- u32 ret = 0;
|
|
-
|
|
- switch (ru_tones) {
|
|
- case RU_26:
|
|
- ret = NL80211_RATE_INFO_HE_RU_ALLOC_26;
|
|
- break;
|
|
- case RU_52:
|
|
- ret = NL80211_RATE_INFO_HE_RU_ALLOC_52;
|
|
- break;
|
|
- case RU_106:
|
|
- ret = NL80211_RATE_INFO_HE_RU_ALLOC_106;
|
|
- break;
|
|
- case RU_242:
|
|
- ret = NL80211_RATE_INFO_HE_RU_ALLOC_242;
|
|
- break;
|
|
- case RU_484:
|
|
- ret = NL80211_RATE_INFO_HE_RU_ALLOC_484;
|
|
- break;
|
|
- case RU_996:
|
|
- ret = NL80211_RATE_INFO_HE_RU_ALLOC_996;
|
|
- break;
|
|
- }
|
|
- return ret;
|
|
-}
|
|
-
|
|
#define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0 0xDDBEEF
|
|
#define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1 0xADBEEF
|
|
#define REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2 0xBDBEEF
|
|
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
|
@@ -246,6 +246,93 @@ static const u32 ath11k_smps_map[] = {
|
|
static int ath11k_start_vdev_delay(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif);
|
|
|
|
+enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy)
|
|
+{
|
|
+ enum nl80211_he_ru_alloc ret;
|
|
+
|
|
+ switch (ru_phy) {
|
|
+ case RU_26:
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_26;
|
|
+ break;
|
|
+ case RU_52:
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_52;
|
|
+ break;
|
|
+ case RU_106:
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_106;
|
|
+ break;
|
|
+ case RU_242:
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_242;
|
|
+ break;
|
|
+ case RU_484:
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_484;
|
|
+ break;
|
|
+ case RU_996:
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_996;
|
|
+ break;
|
|
+ default:
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_26;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+enum nl80211_he_ru_alloc ath11k_mac_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones)
|
|
+{
|
|
+ enum nl80211_he_ru_alloc ret;
|
|
+
|
|
+ switch (ru_tones) {
|
|
+ case 26:
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_26;
|
|
+ break;
|
|
+ case 52:
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_52;
|
|
+ break;
|
|
+ case 106:
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_106;
|
|
+ break;
|
|
+ case 242:
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_242;
|
|
+ break;
|
|
+ case 484:
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_484;
|
|
+ break;
|
|
+ case 996:
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_996;
|
|
+ break;
|
|
+ case (996 * 2):
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_2x996;
|
|
+ break;
|
|
+ default:
|
|
+ ret = NL80211_RATE_INFO_HE_RU_ALLOC_26;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+enum nl80211_he_gi ath11k_mac_he_gi_to_nl80211_he_gi(u8 sgi)
|
|
+{
|
|
+ enum nl80211_he_gi ret;
|
|
+
|
|
+ switch (sgi) {
|
|
+ case RX_MSDU_START_SGI_0_8_US:
|
|
+ ret = NL80211_RATE_INFO_HE_GI_0_8;
|
|
+ break;
|
|
+ case RX_MSDU_START_SGI_1_6_US:
|
|
+ ret = NL80211_RATE_INFO_HE_GI_1_6;
|
|
+ break;
|
|
+ case RX_MSDU_START_SGI_3_2_US:
|
|
+ ret = NL80211_RATE_INFO_HE_GI_3_2;
|
|
+ break;
|
|
+ default:
|
|
+ ret = NL80211_RATE_INFO_HE_GI_0_8;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
u8 ath11k_mac_bw_to_mac80211_bw(u8 bw)
|
|
{
|
|
u8 ret = 0;
|
|
@@ -2541,8 +2628,12 @@ static void ath11k_peer_assoc_prepare(st
|
|
struct peer_assoc_params *arg,
|
|
bool reassoc)
|
|
{
|
|
+ struct ath11k_sta *arsta;
|
|
+
|
|
lockdep_assert_held(&ar->conf_mutex);
|
|
|
|
+ arsta = (struct ath11k_sta *)sta->drv_priv;
|
|
+
|
|
memset(arg, 0, sizeof(*arg));
|
|
|
|
reinit_completion(&ar->peer_assoc_done);
|
|
@@ -2559,6 +2650,8 @@ static void ath11k_peer_assoc_prepare(st
|
|
ath11k_peer_assoc_h_qos(ar, vif, sta, arg);
|
|
ath11k_peer_assoc_h_smps(sta, arg);
|
|
|
|
+ arsta->peer_nss = arg->peer_nss;
|
|
+
|
|
/* TODO: amsdu_disable req? */
|
|
}
|
|
|
|
--- a/drivers/net/wireless/ath/ath11k/mac.h
|
|
+++ b/drivers/net/wireless/ath/ath11k/mac.h
|
|
@@ -162,6 +162,9 @@ void ath11k_mac_drain_tx(struct ath11k *
|
|
void ath11k_mac_peer_cleanup_all(struct ath11k *ar);
|
|
int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx);
|
|
u8 ath11k_mac_bw_to_mac80211_bw(u8 bw);
|
|
+u32 ath11k_mac_he_gi_to_nl80211_he_gi(u8 sgi);
|
|
+enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy);
|
|
+enum nl80211_he_ru_alloc ath11k_mac_he_ru_tones_to_nl80211_he_ru_alloc(u16 ru_tones);
|
|
enum ath11k_supported_bw ath11k_mac_mac80211_bw_to_ath11k_bw(enum rate_info_bw bw);
|
|
enum hal_encrypt_type ath11k_dp_tx_get_encrypt_type(u32 cipher);
|
|
void ath11k_mac_handle_beacon(struct ath11k *ar, struct sk_buff *skb);
|