Browse Source

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
Shaakir Mohamed 7 years ago
parent
commit
19f4f63c35
3 changed files with 57 additions and 1 deletions
  1. 2 0
      dp/wifi3.0/dp_rx_mon_dest.c
  2. 2 1
      qdf/inc/qdf_nbuf.h
  3. 53 0
      qdf/linux/src/qdf_nbuf.c

+ 2 - 0
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(

+ 2 - 1
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 */

+ 53 - 0
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)
 {