From 154f9b8298f5c85351f1e3c7007ba3912f120f6b Mon Sep 17 00:00:00 2001 From: nobelj Date: Wed, 22 Sep 2021 04:30:18 -0700 Subject: [PATCH] qcacmn: Add support for multi user stats to populate radiotap Add support to populate radiotap for multi users. Change-Id: Ied4fe85fc2b456542c9cf4ea969106cdde86265f --- qdf/inc/qdf_nbuf.h | 51 ++++++- qdf/linux/src/qdf_nbuf.c | 300 ++++++++++++++++++++++++++++----------- 2 files changed, 271 insertions(+), 80 deletions(-) diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index c24736a20f..62494339bb 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -312,6 +312,8 @@ * @add_rtap_ext2: add radiotap extension2 * @mpdu_retry_cnt: Rx mpdu retry count * @punctured_bw: puntured bw + * @rx_user_status: pointer to mon_rx_user_status, when set update + * radiotap header will use userinfo from this structure. */ struct mon_rx_status { uint64_t tsft; @@ -403,6 +405,7 @@ struct mon_rx_status { #ifdef WLAN_FEATURE_11BE uint8_t punctured_bw; #endif + struct mon_rx_user_status *rx_user_status; }; /** @@ -414,6 +417,7 @@ struct mon_rx_status { * @ofdma_ru_start_index: OFDMA RU start index * @ofdma_ru_width: OFDMA total RU width * @ofdma_ru_size: OFDMA RU size index + * @is_ampdu: AMPDU flag * @mu_ul_user_v0_word0: MU UL user info word 0 * @mu_ul_user_v0_word1: MU UL user info word 1 * @ast_index: AST table hash index @@ -426,9 +430,24 @@ struct mon_rx_status { * @data_sequence_control_info_valid: field to indicate validity of seq control * @first_data_seq_ctrl: Sequence ctrl field of first data frame * @preamble_type: Preamble type in radio header + * @duration: 802.11 Duration * @ht_flags: HT flags, only present for HT frames. * @vht_flags: VHT flags, only present for VHT frames. + * @vht_flag_values1-5: Contains corresponding data for flags field * @he_flags: HE (11ax) flags, only present in HE frames + * @he_flags1: HE flags + * @he_flags2: HE flags + * @he_RU[4]: HE RU assignment index + * @he_data1: HE property of received frame + * @he_data2: HE property of received frame + * @he_data3: HE property of received frame + * @he_data4: HE property of received frame + * @he_data5: HE property of received frame + * @he_data6: HE property of received frame + * @he_per_user_1: HE per user info1 + * @he_per_user_2: HE per user info2 + * @he_per_user_position: HE per user position info + * @he_per_user_known: HE per user known info * @rtap_flags: Bit map of available fields in the radiotap * @rs_flags: Flags to indicate AMPDU or AMSDU aggregation * @mpdu_cnt_fcs_ok: mpdu count received with fcs ok @@ -438,6 +457,10 @@ struct mon_rx_status { * @mpdu_err_byte_count: mpdu byte count with fcs err * @sw_peer_id: software peer id * @retry_mpdu: mpdu retry count + * @start_seq: starting sequence number + * @ba_control: Block ack control + * @ba_bitmap: 256 bit block ack bitmap + * @tid: QoS traffic tid number */ struct mon_rx_user_status { uint32_t mcs:4, @@ -445,7 +468,8 @@ struct mon_rx_user_status { mu_ul_info_valid:1, ofdma_ru_start_index:7, ofdma_ru_width:7, - ofdma_ru_size:8; + ofdma_ru_size:8, + is_ampdu:1; uint32_t mu_ul_user_v0_word0; uint32_t mu_ul_user_v0_word1; uint32_t ast_index; @@ -458,9 +482,29 @@ struct mon_rx_user_status { uint8_t data_sequence_control_info_valid; uint16_t first_data_seq_ctrl; uint32_t preamble_type; + uint16_t duration; uint16_t ht_flags; uint16_t vht_flags; + uint8_t vht_flag_values1; + uint8_t vht_flag_values2; + uint8_t vht_flag_values3[4]; + uint8_t vht_flag_values4; + uint8_t vht_flag_values5; + uint16_t vht_flag_values6; uint16_t he_flags; + uint16_t he_flags1; + uint16_t he_flags2; + uint8_t he_RU[4]; + uint16_t he_data1; + uint16_t he_data2; + uint16_t he_data3; + uint16_t he_data4; + uint16_t he_data5; + uint16_t he_data6; + uint16_t he_per_user_1; + uint16_t he_per_user_2; + uint8_t he_per_user_position; + uint8_t he_per_user_known; uint8_t rtap_flags; uint8_t rs_flags; uint32_t mpdu_cnt_fcs_ok; @@ -470,6 +514,11 @@ struct mon_rx_user_status { uint32_t mpdu_err_byte_count; uint16_t sw_peer_id; uint32_t retry_mpdu; + uint16_t start_seq; + uint16_t ba_control; + uint32_t ba_bitmap[32]; + uint32_t ba_bitmap_sz; + uint16_t aid; }; /** diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index 2e11d46c48..3fb7647551 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/qdf/linux/src/qdf_nbuf.c @@ -4501,6 +4501,7 @@ static unsigned int qdf_nbuf_update_radiotap_vht_flags( uint32_t rtap_len) { uint16_t vht_flags = 0; + struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status; rtap_len = qdf_align(rtap_len, 2); @@ -4523,36 +4524,70 @@ static unsigned int qdf_nbuf_update_radiotap_vht_flags( (rx_status->beamformed ? IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED : 0); rtap_len += 1; - switch (rx_status->vht_flag_values2) { - case IEEE80211_RADIOTAP_VHT_BW_20: - rtap_buf[rtap_len] = RADIOTAP_VHT_BW_20; - break; - case IEEE80211_RADIOTAP_VHT_BW_40: - rtap_buf[rtap_len] = RADIOTAP_VHT_BW_40; - break; - case IEEE80211_RADIOTAP_VHT_BW_80: - rtap_buf[rtap_len] = RADIOTAP_VHT_BW_80; - break; - case IEEE80211_RADIOTAP_VHT_BW_160: - rtap_buf[rtap_len] = RADIOTAP_VHT_BW_160; - break; + + if (!rx_user_status) { + switch (rx_status->vht_flag_values2) { + case IEEE80211_RADIOTAP_VHT_BW_20: + rtap_buf[rtap_len] = RADIOTAP_VHT_BW_20; + break; + case IEEE80211_RADIOTAP_VHT_BW_40: + rtap_buf[rtap_len] = RADIOTAP_VHT_BW_40; + break; + case IEEE80211_RADIOTAP_VHT_BW_80: + rtap_buf[rtap_len] = RADIOTAP_VHT_BW_80; + break; + case IEEE80211_RADIOTAP_VHT_BW_160: + rtap_buf[rtap_len] = RADIOTAP_VHT_BW_160; + break; + } + rtap_len += 1; + rtap_buf[rtap_len] = (rx_status->vht_flag_values3[0]); + rtap_len += 1; + rtap_buf[rtap_len] = (rx_status->vht_flag_values3[1]); + rtap_len += 1; + rtap_buf[rtap_len] = (rx_status->vht_flag_values3[2]); + rtap_len += 1; + rtap_buf[rtap_len] = (rx_status->vht_flag_values3[3]); + rtap_len += 1; + rtap_buf[rtap_len] = (rx_status->vht_flag_values4); + rtap_len += 1; + rtap_buf[rtap_len] = (rx_status->vht_flag_values5); + rtap_len += 1; + put_unaligned_le16(rx_status->vht_flag_values6, + &rtap_buf[rtap_len]); + rtap_len += 2; + } else { + switch (rx_user_status->vht_flag_values2) { + case IEEE80211_RADIOTAP_VHT_BW_20: + rtap_buf[rtap_len] = RADIOTAP_VHT_BW_20; + break; + case IEEE80211_RADIOTAP_VHT_BW_40: + rtap_buf[rtap_len] = RADIOTAP_VHT_BW_40; + break; + case IEEE80211_RADIOTAP_VHT_BW_80: + rtap_buf[rtap_len] = RADIOTAP_VHT_BW_80; + break; + case IEEE80211_RADIOTAP_VHT_BW_160: + rtap_buf[rtap_len] = RADIOTAP_VHT_BW_160; + break; + } + rtap_len += 1; + rtap_buf[rtap_len] = (rx_user_status->vht_flag_values3[0]); + rtap_len += 1; + rtap_buf[rtap_len] = (rx_user_status->vht_flag_values3[1]); + rtap_len += 1; + rtap_buf[rtap_len] = (rx_user_status->vht_flag_values3[2]); + rtap_len += 1; + rtap_buf[rtap_len] = (rx_user_status->vht_flag_values3[3]); + rtap_len += 1; + rtap_buf[rtap_len] = (rx_user_status->vht_flag_values4); + rtap_len += 1; + rtap_buf[rtap_len] = (rx_user_status->vht_flag_values5); + rtap_len += 1; + put_unaligned_le16(rx_user_status->vht_flag_values6, + &rtap_buf[rtap_len]); + rtap_len += 2; } - rtap_len += 1; - rtap_buf[rtap_len] = (rx_status->vht_flag_values3[0]); - rtap_len += 1; - rtap_buf[rtap_len] = (rx_status->vht_flag_values3[1]); - rtap_len += 1; - rtap_buf[rtap_len] = (rx_status->vht_flag_values3[2]); - rtap_len += 1; - rtap_buf[rtap_len] = (rx_status->vht_flag_values3[3]); - rtap_len += 1; - rtap_buf[rtap_len] = (rx_status->vht_flag_values4); - rtap_len += 1; - rtap_buf[rtap_len] = (rx_status->vht_flag_values5); - rtap_len += 1; - put_unaligned_le16(rx_status->vht_flag_values6, - &rtap_buf[rtap_len]); - rtap_len += 2; return rtap_len; } @@ -4575,30 +4610,64 @@ qdf_nbuf_update_radiotap_he_flags(struct mon_rx_status *rx_status, * IEEE80211_RADIOTAP_HE u16, u16, u16, u16, u16, u16 * Enable all "known" HE radiotap flags for now */ + struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status; + rtap_len = qdf_align(rtap_len, 2); - put_unaligned_le16(rx_status->he_data1, &rtap_buf[rtap_len]); - rtap_len += 2; + if (!rx_user_status) { + put_unaligned_le16(rx_status->he_data1, &rtap_buf[rtap_len]); + rtap_len += 2; - put_unaligned_le16(rx_status->he_data2, &rtap_buf[rtap_len]); - rtap_len += 2; + put_unaligned_le16(rx_status->he_data2, &rtap_buf[rtap_len]); + rtap_len += 2; - put_unaligned_le16(rx_status->he_data3, &rtap_buf[rtap_len]); - rtap_len += 2; + put_unaligned_le16(rx_status->he_data3, &rtap_buf[rtap_len]); + rtap_len += 2; - put_unaligned_le16(rx_status->he_data4, &rtap_buf[rtap_len]); - rtap_len += 2; + put_unaligned_le16(rx_status->he_data4, &rtap_buf[rtap_len]); + rtap_len += 2; - put_unaligned_le16(rx_status->he_data5, &rtap_buf[rtap_len]); - rtap_len += 2; + put_unaligned_le16(rx_status->he_data5, &rtap_buf[rtap_len]); + rtap_len += 2; + + put_unaligned_le16(rx_status->he_data6, &rtap_buf[rtap_len]); + rtap_len += 2; + qdf_rl_debug("he data %x %x %x %x %x %x", + rx_status->he_data1, + rx_status->he_data2, rx_status->he_data3, + rx_status->he_data4, rx_status->he_data5, + rx_status->he_data6); + } else { + put_unaligned_le16(rx_user_status->he_data1, + &rtap_buf[rtap_len]); + rtap_len += 2; + + put_unaligned_le16(rx_user_status->he_data2, + &rtap_buf[rtap_len]); + rtap_len += 2; + + put_unaligned_le16(rx_user_status->he_data3, + &rtap_buf[rtap_len]); + rtap_len += 2; + + put_unaligned_le16(rx_user_status->he_data4, + &rtap_buf[rtap_len]); + rtap_len += 2; + + put_unaligned_le16(rx_user_status->he_data5, + &rtap_buf[rtap_len]); + rtap_len += 2; + + put_unaligned_le16(rx_user_status->he_data6, + &rtap_buf[rtap_len]); + rtap_len += 2; + qdf_rl_debug("he data %x %x %x %x %x %x", + rx_user_status->he_data1, + rx_user_status->he_data2, rx_user_status->he_data3, + rx_user_status->he_data4, rx_user_status->he_data5, + rx_user_status->he_data6); + } - put_unaligned_le16(rx_status->he_data6, &rtap_buf[rtap_len]); - rtap_len += 2; - qdf_rl_debug("he data %x %x %x %x %x %x", - rx_status->he_data1, - rx_status->he_data2, rx_status->he_data3, - rx_status->he_data4, rx_status->he_data5, - rx_status->he_data6); return rtap_len; } @@ -4617,34 +4686,64 @@ static unsigned int qdf_nbuf_update_radiotap_he_mu_flags(struct mon_rx_status *rx_status, int8_t *rtap_buf, uint32_t rtap_len) { + struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status; + rtap_len = qdf_align(rtap_len, 2); /* * IEEE80211_RADIOTAP_HE_MU u16, u16, u8[4] * Enable all "known" he-mu radiotap flags for now */ - put_unaligned_le16(rx_status->he_flags1, &rtap_buf[rtap_len]); - rtap_len += 2; - put_unaligned_le16(rx_status->he_flags2, &rtap_buf[rtap_len]); - rtap_len += 2; + if (!rx_user_status) { + put_unaligned_le16(rx_status->he_flags1, &rtap_buf[rtap_len]); + rtap_len += 2; - rtap_buf[rtap_len] = rx_status->he_RU[0]; - rtap_len += 1; + put_unaligned_le16(rx_status->he_flags2, &rtap_buf[rtap_len]); + rtap_len += 2; - rtap_buf[rtap_len] = rx_status->he_RU[1]; - rtap_len += 1; + rtap_buf[rtap_len] = rx_status->he_RU[0]; + rtap_len += 1; - rtap_buf[rtap_len] = rx_status->he_RU[2]; - rtap_len += 1; + rtap_buf[rtap_len] = rx_status->he_RU[1]; + rtap_len += 1; - rtap_buf[rtap_len] = rx_status->he_RU[3]; - rtap_len += 1; - qdf_debug("he_flags %x %x he-RU %x %x %x %x", - rx_status->he_flags1, - rx_status->he_flags2, rx_status->he_RU[0], - rx_status->he_RU[1], rx_status->he_RU[2], - rx_status->he_RU[3]); + rtap_buf[rtap_len] = rx_status->he_RU[2]; + rtap_len += 1; + + rtap_buf[rtap_len] = rx_status->he_RU[3]; + rtap_len += 1; + qdf_debug("he_flags %x %x he-RU %x %x %x %x", + rx_status->he_flags1, + rx_status->he_flags2, rx_status->he_RU[0], + rx_status->he_RU[1], rx_status->he_RU[2], + rx_status->he_RU[3]); + } else { + put_unaligned_le16(rx_user_status->he_flags1, + &rtap_buf[rtap_len]); + rtap_len += 2; + + put_unaligned_le16(rx_user_status->he_flags2, + &rtap_buf[rtap_len]); + rtap_len += 2; + + rtap_buf[rtap_len] = rx_user_status->he_RU[0]; + rtap_len += 1; + + rtap_buf[rtap_len] = rx_user_status->he_RU[1]; + rtap_len += 1; + + rtap_buf[rtap_len] = rx_user_status->he_RU[2]; + rtap_len += 1; + + rtap_buf[rtap_len] = rx_user_status->he_RU[3]; + rtap_len += 1; + qdf_debug("he_flags %x %x he-RU %x %x %x %x", + rx_user_status->he_flags1, + rx_user_status->he_flags2, rx_user_status->he_RU[0], + rx_user_status->he_RU[1], rx_user_status->he_RU[2], + rx_user_status->he_RU[3]); + } return rtap_len; } @@ -4663,27 +4762,54 @@ static unsigned int qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status *rx_status, int8_t *rtap_buf, uint32_t rtap_len) { + struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status; + rtap_len = qdf_align(rtap_len, 2); /* * IEEE80211_RADIOTAP_HE-MU-OTHER u16, u16, u8, u8 * Enable all "known" he-mu-other radiotap flags for now */ - put_unaligned_le16(rx_status->he_per_user_1, &rtap_buf[rtap_len]); - rtap_len += 2; + if (!rx_user_status) { + put_unaligned_le16(rx_status->he_per_user_1, + &rtap_buf[rtap_len]); + rtap_len += 2; - put_unaligned_le16(rx_status->he_per_user_2, &rtap_buf[rtap_len]); - rtap_len += 2; + put_unaligned_le16(rx_status->he_per_user_2, + &rtap_buf[rtap_len]); + rtap_len += 2; - rtap_buf[rtap_len] = rx_status->he_per_user_position; - rtap_len += 1; + rtap_buf[rtap_len] = rx_status->he_per_user_position; + rtap_len += 1; + + rtap_buf[rtap_len] = rx_status->he_per_user_known; + rtap_len += 1; + qdf_debug("he_per_user %x %x pos %x knwn %x", + rx_status->he_per_user_1, + rx_status->he_per_user_2, + rx_status->he_per_user_position, + rx_status->he_per_user_known); + } else { + put_unaligned_le16(rx_user_status->he_per_user_1, + &rtap_buf[rtap_len]); + rtap_len += 2; + + put_unaligned_le16(rx_user_status->he_per_user_2, + &rtap_buf[rtap_len]); + rtap_len += 2; + + rtap_buf[rtap_len] = rx_user_status->he_per_user_position; + rtap_len += 1; + + rtap_buf[rtap_len] = rx_user_status->he_per_user_known; + rtap_len += 1; + qdf_debug("he_per_user %x %x pos %x knwn %x", + rx_user_status->he_per_user_1, + rx_user_status->he_per_user_2, + rx_user_status->he_per_user_position, + rx_user_status->he_per_user_known); + } - rtap_buf[rtap_len] = rx_status->he_per_user_known; - rtap_len += 1; - qdf_debug("he_per_user %x %x pos %x knwn %x", - rx_status->he_per_user_1, - rx_status->he_per_user_2, rx_status->he_per_user_position, - rx_status->he_per_user_known); return rtap_len; } @@ -4754,6 +4880,9 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status, struct qdf_radiotap_vendor_ns_ath *radiotap_vendor_ns_ath; struct qdf_radiotap_ext2 *rtap_ext2; uint32_t *rtap_ext = NULL; + struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status; + + /* per user info */ /* Adding Extended Header space */ if (rx_status->add_rtap_ext) { @@ -4968,10 +5097,23 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status, rtap_ext2 = (struct qdf_radiotap_ext2 *)(rtap_buf + rtap_len); rtap_ext2->ppdu_id = rx_status->ppdu_id; rtap_ext2->prev_ppdu_id = rx_status->prev_ppdu_id; - rtap_ext2->tid = rx_status->tid; - rtap_ext2->start_seq = rx_status->start_seq; - qdf_mem_copy(rtap_ext2->ba_bitmap, - rx_status->ba_bitmap, 8 * (sizeof(uint32_t))); + if (!rx_user_status) { + rtap_ext2->tid = rx_status->tid; + rtap_ext2->start_seq = rx_status->start_seq; + qdf_mem_copy(rtap_ext2->ba_bitmap, + rx_status->ba_bitmap, + 8 * (sizeof(uint32_t))); + } else { + uint8_t ba_bitmap_sz = rx_user_status->ba_bitmap_sz; + + /* set default bitmap sz if not set */ + ba_bitmap_sz = ba_bitmap_sz ? ba_bitmap_sz : 8; + rtap_ext2->tid = rx_user_status->tid; + rtap_ext2->start_seq = rx_user_status->start_seq; + qdf_mem_copy(rtap_ext2->ba_bitmap, + rx_user_status->ba_bitmap, + ba_bitmap_sz * (sizeof(uint32_t))); + } rtap_len += sizeof(*rtap_ext2); }