openwrt-ipq-breeze303/package/kernel/mac80211/patches/nss/ath11k/108-ath11k-enable-ul-ofdma-ru-allocation-in-peer-stats.patch
Sean Khan 6ec201e486 ath11k_nss: Bump version 6.6.15 to 6.9.9
Signed-off-by: Sean Khan <datapronix@protonmail.com>
2024-10-11 19:19:12 -04:00

453 lines
16 KiB
Diff

--- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c
+++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c
@@ -525,6 +525,12 @@ static ssize_t ath11k_dbg_sta_dump_rx_st
len += scnprintf(buf + len, size - len, "%10llu%s",
rx_stats->byte_stats.rx_rate[i],
(i + 1) % (he_rates_avail ? 12 : 8) ? "\t" : "\n");
+ len += scnprintf(buf + len, size - len,
+ "\nDCM: %llu\nRU26: %llu \nRU52: %llu \nRU106: %llu \nRU242: %llu \nRU484: %llu \nRU996: %llu\n",
+ rx_stats->dcm_count, rx_stats->ru_alloc_cnt[0],
+ rx_stats->ru_alloc_cnt[1], rx_stats->ru_alloc_cnt[2],
+ rx_stats->ru_alloc_cnt[3], rx_stats->ru_alloc_cnt[4],
+ rx_stats->ru_alloc_cnt[5]);
len += scnprintf(buf + len, size - len, "\n");
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -2902,11 +2902,12 @@ exit:
static void
ath11k_dp_rx_update_peer_rate_table_stats(struct ath11k_rx_peer_stats *rx_stats,
struct hal_rx_mon_ppdu_info *ppdu_info,
+ struct hal_rx_user_status* user_stats,
u32 num_msdu)
{
u32 rate_idx = 0;
- u32 mcs_idx = ppdu_info->mcs;
- u32 nss_idx = ppdu_info->nss - 1;
+ u32 mcs_idx = (user_stats) ? user_stats->mcs : ppdu_info->mcs;
+ u32 nss_idx = (user_stats) ? user_stats->nss - 1 : ppdu_info->nss - 1;
u32 bw_idx = ppdu_info->bw;
u32 gi_idx = ppdu_info->gi;
@@ -2928,10 +2929,13 @@ ath11k_dp_rx_update_peer_rate_table_stat
}
rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu;
- rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len;
+ if (user_stats)
+ rx_stats->byte_stats.rx_rate[rate_idx] += user_stats->mpdu_ok_byte_count;
+ else
+ rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len;
}
-static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta,
+static void ath11k_dp_rx_update_peer_su_stats(struct ath11k_sta *arsta,
struct hal_rx_mon_ppdu_info *ppdu_info)
{
struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats;
@@ -2989,7 +2993,6 @@ static void ath11k_dp_rx_update_peer_sta
rx_stats->num_mpdu_fcs_ok += ppdu_info->num_mpdu_fcs_ok;
rx_stats->num_mpdu_fcs_err += ppdu_info->num_mpdu_fcs_err;
rx_stats->dcm_count += ppdu_info->dcm;
- rx_stats->ru_alloc_cnt[ppdu_info->ru_alloc] += num_msdu;
BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) >
ARRAY_SIZE(ppdu_info->rssi_chain_pri20));
@@ -3007,10 +3010,10 @@ static void ath11k_dp_rx_update_peer_sta
if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N &&
ppdu_info->mcs <= HAL_RX_MAX_MCS_HT) {
- rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu;
- rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;
- /* To fit into rate table for HT packets */
- ppdu_info->mcs = ppdu_info->mcs % 8;
+ rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu;
+ rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;
+ /* To fit into rate table for HT packets */
+ ppdu_info->mcs = ppdu_info->mcs % 8;
}
if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC &&
@@ -3043,7 +3046,120 @@ static void ath11k_dp_rx_update_peer_sta
rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len;
}
- ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, num_msdu);
+ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, NULL, num_msdu);
+
+}
+
+static void ath11k_dp_rx_update_user_stats(struct ath11k *ar,
+ struct hal_rx_mon_ppdu_info *ppdu_info,
+ u32 uid)
+{
+ struct ath11k_sta *arsta = NULL;
+ struct ath11k_rx_peer_stats *rx_stats = NULL;
+ struct hal_rx_user_status* user_stats = &ppdu_info->userstats[uid];
+ struct ath11k_peer *peer;
+ u32 num_msdu;
+
+ if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF)
+ return;
+
+ peer = ath11k_peer_find_by_ast(ar->ab, user_stats->ast_index);
+
+ if (peer == NULL) {
+ ath11k_warn(ar->ab, "peer ast idx %d can't be found\n",
+ user_stats->ast_index);
+ return;
+ }
+
+ arsta = (struct ath11k_sta *)peer->sta->drv_priv;
+ rx_stats = arsta->rx_stats;
+
+ if (!rx_stats)
+ return;
+
+ arsta->rssi_comb = ppdu_info->rssi_comb;
+
+ num_msdu = user_stats->tcp_msdu_count + user_stats->tcp_ack_msdu_count +
+ user_stats->udp_msdu_count + user_stats->other_msdu_count;
+
+ rx_stats->num_msdu += num_msdu;
+ rx_stats->tcp_msdu_count += user_stats->tcp_msdu_count +
+ user_stats->tcp_ack_msdu_count;
+ rx_stats->udp_msdu_count += user_stats->udp_msdu_count;
+ rx_stats->other_msdu_count += user_stats->other_msdu_count;
+
+ if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX)
+ rx_stats->coding_count[ppdu_info->ldpc] += num_msdu;
+
+ if (user_stats->tid <= IEEE80211_NUM_TIDS)
+ rx_stats->tid_count[user_stats->tid] += num_msdu;
+
+ if (user_stats->preamble_type < HAL_RX_PREAMBLE_MAX)
+ rx_stats->pream_cnt[user_stats->preamble_type] += num_msdu;
+
+ if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX)
+ rx_stats->reception_type[ppdu_info->reception_type] += num_msdu;
+
+ if (ppdu_info->is_stbc)
+ rx_stats->stbc_count += num_msdu;
+
+ if (ppdu_info->beamformed)
+ rx_stats->beamformed_count += num_msdu;
+
+ if (user_stats->mpdu_cnt_fcs_ok > 1)
+ rx_stats->ampdu_msdu_count += num_msdu;
+ else
+ rx_stats->non_ampdu_msdu_count += num_msdu;
+
+ rx_stats->num_mpdu_fcs_ok += user_stats->mpdu_cnt_fcs_ok;
+ rx_stats->num_mpdu_fcs_err += user_stats->mpdu_cnt_fcs_err;
+ rx_stats->dcm_count += ppdu_info->dcm;
+ if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA ||
+ ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)
+ rx_stats->ru_alloc_cnt[user_stats->ul_ofdma_ru_size] += num_msdu;
+
+ rx_stats->rx_duration += ppdu_info->rx_duration;
+ arsta->rx_duration = rx_stats->rx_duration;
+
+ if (user_stats->nss > 0 && user_stats->nss <= HAL_RX_MAX_NSS) {
+ rx_stats->pkt_stats.nss_count[user_stats->nss - 1] += num_msdu;
+ rx_stats->byte_stats.nss_count[user_stats->nss - 1] += user_stats->mpdu_ok_byte_count;
+ }
+
+ if (user_stats->preamble_type == HAL_RX_PREAMBLE_11AX &&
+ user_stats->mcs <= HAL_RX_MAX_MCS_HE) {
+ rx_stats->pkt_stats.he_mcs_count[user_stats->mcs] += num_msdu;
+ rx_stats->byte_stats.he_mcs_count[user_stats->mcs] += user_stats->mpdu_ok_byte_count;
+ }
+
+ if (ppdu_info->gi < HAL_RX_GI_MAX) {
+ rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu;
+ rx_stats->byte_stats.gi_count[ppdu_info->gi] += user_stats->mpdu_ok_byte_count;
+ }
+
+ if (ppdu_info->bw < HAL_RX_BW_MAX) {
+ rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu;
+ rx_stats->byte_stats.bw_count[ppdu_info->bw] += user_stats->mpdu_ok_byte_count;
+ }
+
+ ath11k_dp_rx_update_peer_rate_table_stats(rx_stats, ppdu_info, user_stats, num_msdu);
+}
+
+static void ath11k_dp_rx_update_peer_mu_stats(struct ath11k *ar,
+ struct hal_rx_mon_ppdu_info *ppdu_info)
+{
+ u32 num_users, i;
+
+ if (!ath11k_debugfs_is_extd_rx_stats_enabled(ar))
+ return;
+
+ num_users = ppdu_info->num_users;
+ if (num_users > HAL_MAX_UL_MU_USERS)
+ num_users = HAL_MAX_UL_MU_USERS;
+
+ for (i = 0; i < num_users; i++) {
+ ath11k_dp_rx_update_user_stats(ar, ppdu_info, i);
+ }
}
@@ -5381,6 +5497,55 @@ static void ath11k_dp_rx_mon_dest_proces
}
}
+void ath11k_dp_rx_mon_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info)
+{
+ struct hal_rx_user_status *rx_user_status;
+ u32 num_users;
+ uint32_t i;
+ uint32_t mu_ul_user_v0_word0;
+ uint32_t mu_ul_user_v0_word1;
+ uint32_t ru_size;
+
+ if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA ||
+ ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO))
+ return;
+
+ num_users = ppdu_info->num_users;
+ if (num_users > HAL_MAX_UL_MU_USERS)
+ num_users = HAL_MAX_UL_MU_USERS;
+
+ for (i = 0; i < num_users; i++) {
+ rx_user_status = &ppdu_info->userstats[i];
+ mu_ul_user_v0_word0 =
+ rx_user_status->ul_ofdma_user_v0_word0;
+ mu_ul_user_v0_word1 =
+ rx_user_status->ul_ofdma_user_v0_word1;
+
+ if (FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID,
+ mu_ul_user_v0_word0) &&
+ !FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER,
+ mu_ul_user_v0_word0)) {
+ rx_user_status->mcs =
+ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS,
+ mu_ul_user_v0_word1);
+ rx_user_status->nss =
+ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS,
+ mu_ul_user_v0_word1) + 1;
+
+ rx_user_status->ofdma_info_valid = 1;
+ rx_user_status->ul_ofdma_ru_start_index =
+ FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START,
+ mu_ul_user_v0_word1);
+
+ ru_size = FIELD_GET(HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE,
+ mu_ul_user_v0_word1);
+ rx_user_status->ul_ofdma_ru_width = ru_size;
+ rx_user_status->ul_ofdma_ru_size = ru_size;
+ }
+ }
+
+}
+
int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,
struct napi_struct *napi, int budget)
{
@@ -5454,8 +5619,13 @@ int ath11k_dp_rx_process_mon_status(stru
if ((ppdu_info->fc_valid) &&
(ppdu_info->ast_index != HAL_AST_IDX_INVALID)) {
- arsta = (struct ath11k_sta *)peer->sta->drv_priv;
- ath11k_dp_rx_update_peer_stats(arsta, ppdu_info);
+ if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) {
+ arsta = (struct ath11k_sta *)peer->sta->drv_priv;
+ ath11k_dp_rx_update_peer_su_stats(arsta, ppdu_info);
+ } else {
+ ath11k_dp_rx_mon_process_ulofdma(ppdu_info);
+ ath11k_dp_rx_update_peer_mu_stats(ar, ppdu_info);
+ }
}
if (ath11k_debugfs_is_pktlog_peer_valid(ar, peer->addr))
--- a/drivers/net/wireless/ath/ath11k/hal_rx.c
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
@@ -805,7 +805,6 @@ void ath11k_hal_reo_init_cmd_ring(struct
}
}
-#define HAL_MAX_UL_MU_USERS 37
static inline void
ath11k_hal_rx_handle_ofdma_info(void *rx_tlv,
struct hal_rx_user_status *rx_user_status)
@@ -837,6 +836,8 @@ ath11k_hal_rx_populate_mu_user_info(void
{
rx_user_status->ast_index = ppdu_info->ast_index;
rx_user_status->tid = ppdu_info->tid;
+ rx_user_status->tcp_ack_msdu_count =
+ ppdu_info->tcp_ack_msdu_count;
rx_user_status->tcp_msdu_count =
ppdu_info->tcp_msdu_count;
rx_user_status->udp_msdu_count =
@@ -860,6 +861,9 @@ ath11k_hal_rx_populate_mu_user_info(void
ppdu_info->num_mpdu_fcs_ok;
rx_user_status->mpdu_cnt_fcs_err =
ppdu_info->num_mpdu_fcs_err;
+ memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0],
+ HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *
+ sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0]));
ath11k_hal_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status);
}
@@ -889,6 +893,14 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
__le32_to_cpu(ppdu_start->info0));
ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num);
ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts);
+
+ if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) {
+ ppdu_info->last_ppdu_id = ppdu_info->ppdu_id;
+ ppdu_info->num_users = 0;
+ memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0,
+ HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *
+ sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0]));
+ }
break;
}
case HAL_RX_PPDU_END_USER_STATS: {
@@ -943,15 +955,16 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
if (userid < HAL_MAX_UL_MU_USERS) {
struct hal_rx_user_status *rxuser_stats =
- &ppdu_info->userstats;
+ &ppdu_info->userstats[userid];
+ ppdu_info->num_users += 1;
ath11k_hal_rx_handle_ofdma_info(tlv_data, rxuser_stats);
ath11k_hal_rx_populate_mu_user_info(tlv_data, ppdu_info,
rxuser_stats);
}
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[0] =
+ ppdu_info->mpdu_fcs_ok_bitmap[0] =
__le32_to_cpu(eu_stats->rsvd1[0]);
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[1] =
+ ppdu_info->mpdu_fcs_ok_bitmap[1] =
__le32_to_cpu(eu_stats->rsvd1[1]);
break;
@@ -959,12 +972,12 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
case HAL_RX_PPDU_END_USER_STATS_EXT: {
struct hal_rx_ppdu_end_user_stats_ext *eu_stats =
(struct hal_rx_ppdu_end_user_stats_ext *)tlv_data;
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[2] = eu_stats->info1;
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[3] = eu_stats->info2;
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[4] = eu_stats->info3;
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[5] = eu_stats->info4;
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[6] = eu_stats->info5;
- ppdu_info->userstats.mpdu_fcs_ok_bitmap[7] = eu_stats->info6;
+ ppdu_info->mpdu_fcs_ok_bitmap[2] = eu_stats->info1;
+ ppdu_info->mpdu_fcs_ok_bitmap[3] = eu_stats->info2;
+ ppdu_info->mpdu_fcs_ok_bitmap[4] = eu_stats->info3;
+ ppdu_info->mpdu_fcs_ok_bitmap[5] = eu_stats->info4;
+ ppdu_info->mpdu_fcs_ok_bitmap[6] = eu_stats->info5;
+ ppdu_info->mpdu_fcs_ok_bitmap[7] = eu_stats->info6;
break;
}
case HAL_PHYRX_HT_SIG: {
--- a/drivers/net/wireless/ath/ath11k/hal_rx.h
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.h
@@ -73,6 +73,10 @@ enum hal_rx_reception_type {
#define HAL_RX_FCS_LEN 4
#define HAL_AST_IDX_INVALID 0xFFFF
+#define HAL_MAX_UL_MU_USERS 37
+#define HAL_RX_MAX_MPDU 256
+#define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5)
+
enum hal_rx_mon_status {
HAL_RX_MON_STATUS_PPDU_NOT_DONE,
HAL_RX_MON_STATUS_PPDU_DONE,
@@ -83,14 +87,15 @@ struct hal_rx_user_status {
u32 mcs:4,
nss:3,
ofdma_info_valid:1,
- dl_ofdma_ru_start_index:7,
- dl_ofdma_ru_width:7,
- dl_ofdma_ru_size:8;
+ ul_ofdma_ru_start_index:7,
+ ul_ofdma_ru_width:7,
+ ul_ofdma_ru_size:8;
u32 ul_ofdma_user_v0_word0;
u32 ul_ofdma_user_v0_word1;
u32 ast_index;
u32 tid;
u16 tcp_msdu_count;
+ u16 tcp_ack_msdu_count;
u16 udp_msdu_count;
u16 other_msdu_count;
u16 frame_control;
@@ -104,7 +109,7 @@ struct hal_rx_user_status {
u8 rs_flags;
u32 mpdu_cnt_fcs_ok;
u32 mpdu_cnt_fcs_err;
- u32 mpdu_fcs_ok_bitmap[8];
+ u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP];
u32 mpdu_ok_byte_count;
u32 mpdu_err_byte_count;
};
@@ -145,6 +150,7 @@ struct hal_sw_mon_ring_entries {
struct hal_rx_mon_ppdu_info {
u32 ppdu_id;
+ u32 last_ppdu_id;
u32 ppdu_ts;
u32 num_mpdu_fcs_ok;
u32 num_mpdu_fcs_err;
@@ -213,9 +219,20 @@ struct hal_rx_mon_ppdu_info {
u8 ltf_size;
u8 rxpcu_filter_pass;
char rssi_chain[8][8];
- struct hal_rx_user_status userstats;
+ u32 num_users;
+ u32 mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP];
+ struct hal_rx_user_status userstats[HAL_MAX_UL_MU_USERS];
};
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID BIT(30)
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER BIT(31)
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS GENMASK(2, 0)
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS GENMASK(6, 3)
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC BIT(7)
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_DCM BIT(8)
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START GENMASK(15, 9)
+#define HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE GENMASK(18, 16)
+
#define HAL_RX_PPDU_START_INFO0_PPDU_ID GENMASK(15, 0)
struct hal_rx_ppdu_start {
--- a/drivers/net/wireless/ath/ath11k/peer.c
+++ b/drivers/net/wireless/ath/ath11k/peer.c
@@ -93,6 +93,20 @@ struct ath11k_peer *ath11k_peer_find_by_
return NULL;
}
+struct ath11k_peer *ath11k_peer_find_by_ast(struct ath11k_base *ab,
+ int ast_hash)
+{
+ struct ath11k_peer *peer;
+
+ lockdep_assert_held(&ab->base_lock);
+
+ list_for_each_entry(peer, &ab->peers, list)
+ if (ast_hash == peer->ast_hash)
+ return peer;
+
+ return NULL;
+}
+
void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id)
{
struct ath11k_peer *peer;
--- a/drivers/net/wireless/ath/ath11k/peer.h
+++ b/drivers/net/wireless/ath/ath11k/peer.h
@@ -59,6 +59,7 @@ struct ath11k_peer *ath11k_peer_find(str
struct ath11k_peer *ath11k_peer_find_by_addr(struct ath11k_base *ab,
const u8 *addr);
struct ath11k_peer *ath11k_peer_find_by_id(struct ath11k_base *ab, int peer_id);
+struct ath11k_peer *ath11k_peer_find_by_ast(struct ath11k_base *ab, int ast_hash);
void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id);
int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr);
int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,