Эх сурвалжийг харах

qcacmn: Add support for multi user stats to populate radiotap

Add support to populate radiotap for multi users.

Change-Id: Ied4fe85fc2b456542c9cf4ea969106cdde86265f
nobelj 3 жил өмнө
parent
commit
154f9b8298
2 өөрчлөгдсөн 271 нэмэгдсэн , 80 устгасан
  1. 50 1
      qdf/inc/qdf_nbuf.h
  2. 221 79
      qdf/linux/src/qdf_nbuf.c

+ 50 - 1
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;
 };
 
 /**

+ 221 - 79
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);
 	}