From 19f4f63c35abfb30a40b5699a529a772fd62d978 Mon Sep 17 00:00:00 2001 From: Shaakir Mohamed Date: Mon, 19 Mar 2018 16:28:15 -0700 Subject: [PATCH] qcacmn: Fix AMPDU status info in radiotap header AMPDU flag check is not present when radiotap header is updated. This fix will check for rs_flags to check and set AMPDU present Change-Id: I9e0a703a46459b1013af092f8cb8b7cd35f1a3ce CRs-Fixed: 2204278 --- dp/wifi3.0/dp_rx_mon_dest.c | 2 ++ qdf/inc/qdf_nbuf.h | 3 ++- qdf/linux/src/qdf_nbuf.c | 53 +++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c index 68e65ef977f4..df4d7670ba43 100644 --- a/dp/wifi3.0/dp_rx_mon_dest.c +++ b/dp/wifi3.0/dp_rx_mon_dest.c @@ -690,6 +690,8 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id, tail_msdu, rs); if (mon_mpdu && pdev->monitor_vdev && pdev->monitor_vdev->osif_vdev) { + pdev->ppdu_info.rx_status.ppdu_id = + pdev->ppdu_info.com_info.ppdu_id; qdf_nbuf_update_radiotap(&(pdev->ppdu_info.rx_status), mon_mpdu, sizeof(struct rx_pkt_tlvs)); pdev->monitor_vdev->osif_rx_mon( diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index 401c681a89f6..adce1868ff68 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -218,7 +218,7 @@ * @he_data4: HE property of received frame * @he_data5: HE property of received frame * @prev_ppdu_id: ppdu_id in previously received message - * + * @ppdu_id: Id of the PLCP protocol data unit */ struct mon_rx_status { uint64_t tsft; @@ -288,6 +288,7 @@ struct mon_rx_status { uint16_t he_data6; uint32_t ppdu_len; uint32_t prev_ppdu_id; + uint32_t ppdu_id; }; /* Masks for HE SIG known fields in mon_rx_status structure */ diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index 7e3534a8ee22..a43b2386eecb 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/qdf/linux/src/qdf_nbuf.c @@ -3912,10 +3912,12 @@ qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status *rx_status, #define RADIOTAP_HE_MU_OTHER_FLAGS_LEN 18 #define RADIOTAP_FIXED_HEADER_LEN 16 #define RADIOTAP_HT_FLAGS_LEN 3 +#define RADIOTAP_AMPDU_STATUS_LEN 8 #define RADIOTAP_HEADER_LEN (sizeof(struct ieee80211_radiotap_header) + \ RADIOTAP_FIXED_HEADER_LEN + \ RADIOTAP_HT_FLAGS_LEN + \ RADIOTAP_VHT_FLAGS_LEN + \ + RADIOTAP_AMPDU_STATUS_LEN + \ RADIOTAP_HE_FLAGS_LEN + \ RADIOTAP_HE_MU_FLAGS_LEN + \ RADIOTAP_HE_MU_OTHER_FLAGS_LEN) @@ -3951,6 +3953,39 @@ static uint16_t radiotap_num_to_freq (uint16_t chan_num) return CHANNEL_FREQ_5000 + (chan_num * FREQ_MULTIPLIER_CONST_5MHZ); } + +/** + * qdf_nbuf_update_radiotap_ampdu_flags() - Update radiotap header ampdu flags + * @rx_status: Pointer to rx_status. + * @rtap_buf: Buf to which AMPDU info has to be updated. + * @rtap_len: Current length of radiotap buffer + * + * Return: Length of radiotap after AMPDU flags updated. + */ +static unsigned int qdf_nbuf_update_radiotap_ampdu_flags( + struct mon_rx_status *rx_status, + uint8_t *rtap_buf, + uint32_t rtap_len) +{ + /* + * IEEE80211_RADIOTAP_AMPDU_STATUS u32 u16 u8 u8 + * First 32 bits of AMPDU represents the reference number + */ + + uint32_t ampdu_reference_num = rx_status->ppdu_id; + uint16_t ampdu_flags = 0; + uint16_t ampdu_reserved_flags = 0; + + put_unaligned_le32(ampdu_reference_num, &rtap_buf[rtap_len]); + rtap_len += 4; + put_unaligned_le16(ampdu_flags, &rtap_buf[rtap_len]); + rtap_len += 2; + put_unaligned_le16(ampdu_reserved_flags, &rtap_buf[rtap_len]); + rtap_len += 2; + + return rtap_len; +} + /** * qdf_nbuf_update_radiotap() - Update radiotap header from rx_status * @rx_status: Pointer to rx_status. @@ -4041,6 +4076,15 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status, rtap_len += 1; } + if (rx_status->rs_flags & IEEE80211_AMPDU_FLAG) { + /* IEEE80211_RADIOTAP_AMPDU_STATUS u32 u16 u8 u8 */ + rthdr->it_present |= + cpu_to_le32(1 << IEEE80211_RADIOTAP_AMPDU_STATUS); + rtap_len = qdf_nbuf_update_radiotap_ampdu_flags(rx_status, + rtap_buf, + rtap_len); + } + if (rx_status->vht_flags) { /* IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16 */ rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT); @@ -4102,6 +4146,15 @@ unsigned int qdf_nbuf_update_radiotap_he_flags(struct mon_rx_status *rx_status, return 0; } +static unsigned int qdf_nbuf_update_radiotap_ampdu_flags( + struct mon_rx_status *rx_status, + uint8_t *rtap_buf, + uint32_t rtap_len) +{ + qdf_print("ERROR: struct ieee80211_radiotap_header not supported"); + return 0; +} + unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status, qdf_nbuf_t nbuf, uint32_t headroom_sz) {