Forráskód Böngészése

Merge "qca-wifi: Add frame types to TX Capture"

Linux Build Service Account 5 éve
szülő
commit
587c236f05
2 módosított fájl, 156 hozzáadás és 26 törlés
  1. 148 24
      dp/wifi3.0/dp_tx_capture.c
  2. 8 2
      dp/wifi3.0/dp_tx_capture.h

+ 148 - 24
dp/wifi3.0/dp_tx_capture.c

@@ -1265,6 +1265,120 @@ QDF_STATUS dp_tx_print_bitmap(struct dp_pdev *pdev,
 	return QDF_STATUS_SUCCESS;
 }
 
+/*
+ * dp_peer_tx_wds_addr_add() – Update WDS peer to include 4th address
+ * @peer: Datapath peer
+ * @addr4_mac_addr: Source MAC address for WDS TX
+ *
+ */
+static
+void dp_peer_tx_wds_addr_add(struct dp_peer *peer, uint8_t *addr4_mac_addr)
+{
+	struct ieee80211_frame_addr4 *ptr_wh;
+
+	if (!peer)
+		return;
+
+	ptr_wh = &peer->tx_capture.tx_wifi_addr4_hdr;
+	qdf_mem_copy(ptr_wh->i_addr4,
+		     addr4_mac_addr,
+		     QDF_MAC_ADDR_SIZE);
+}
+
+/*
+ * dp_peer_tx_update_80211_wds_hdr() – Update 80211 frame header to include a
+ * 4 address frame, and set QoS related information if necessary
+ * @pdev: Physical device reference
+ * @peer: Datapath peer
+ * @data: ppdu_descriptor
+ * @nbuf: 802.11 frame
+ * @ether_type: ethernet type
+ * @src_addr: ether shost address
+ *
+ */
+static uint32_t dp_tx_update_80211_wds_hdr(struct dp_pdev *pdev,
+					   struct dp_peer *peer,
+					   void *data,
+					   qdf_nbuf_t nbuf,
+					   uint16_t ether_type,
+					   uint8_t *src_addr)
+{
+	struct cdp_tx_completion_ppdu *ppdu_desc;
+	uint32_t mpdu_buf_len, frame_size;
+	uint8_t *ptr_hdr;
+	uint16_t eth_type = qdf_htons(ether_type);
+	struct ieee80211_qosframe_addr4 *ptr_wh;
+
+	ppdu_desc = (struct cdp_tx_completion_ppdu *)data;
+
+	ptr_wh = &peer->tx_capture.tx_wifi_addr4_qos_hdr;
+
+	/*
+	 * update framectrl only for first ppdu_id
+	 * rest of mpdu will have same frame ctrl
+	 * mac address and duration
+	 */
+	if (ppdu_desc->ppdu_id != peer->tx_capture.tx_wifi_ppdu_id) {
+		ptr_wh->i_fc[1] = (ppdu_desc->frame_ctrl & 0xFF00) >> 8;
+		ptr_wh->i_fc[0] = (ppdu_desc->frame_ctrl & 0xFF);
+
+		ptr_wh->i_dur[1] = (ppdu_desc->tx_duration & 0xFF00) >> 8;
+		ptr_wh->i_dur[0] = (ppdu_desc->tx_duration & 0xFF);
+
+		ptr_wh->i_qos[1] = (ppdu_desc->user[0].qos_ctrl & 0xFF00) >> 8;
+		ptr_wh->i_qos[0] = (ppdu_desc->user[0].qos_ctrl & 0xFF);
+		/* Update Addr 3 (SA) with SA derived from ether packet */
+		qdf_mem_copy(ptr_wh->i_addr3, src_addr, QDF_MAC_ADDR_SIZE);
+
+		peer->tx_capture.tx_wifi_ppdu_id = ppdu_desc->ppdu_id;
+	}
+
+	frame_size = (ppdu_desc->user[0].tid != DP_NON_QOS_TID) ?
+		      sizeof(struct ieee80211_qosframe_addr4) :
+		      sizeof(struct ieee80211_frame_addr4);
+
+	mpdu_buf_len = frame_size + LLC_SNAP_HDR_LEN;
+
+	nbuf->protocol = qdf_htons(ETH_P_802_2);
+
+	/* update ieee80211_frame header */
+	if (!qdf_nbuf_push_head(nbuf, mpdu_buf_len)) {
+		QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_ERROR,
+			  FL("No headroom"));
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	ptr_hdr = (void *)qdf_nbuf_data(nbuf);
+	qdf_mem_copy(ptr_hdr, ptr_wh, frame_size);
+
+	ptr_hdr = ptr_hdr + frame_size;
+
+	/* update LLC */
+	*ptr_hdr =  LLC_SNAP_LSAP;
+	*(ptr_hdr + 1) = LLC_SNAP_LSAP;
+	*(ptr_hdr + 2) = LLC_UI;
+	*(ptr_hdr + 3) = 0x00;
+	*(ptr_hdr + 4) = 0x00;
+	*(ptr_hdr + 5) = 0x00;
+	*(ptr_hdr + 6) = (eth_type & 0xFF00) >> 8;
+	*(ptr_hdr + 7) = (eth_type & 0xFF);
+
+	qdf_nbuf_trim_tail(nbuf, qdf_nbuf_len(nbuf) - mpdu_buf_len);
+	return 0;
+}
+
+/*
+ * dp_peer_tx_update_80211_hdr() – Update 80211 frame header to set QoS
+ * related information if necessary
+ * @pdev: Physical device reference
+ * @peer: Datapath peer
+ * @data: ppdu_descriptor
+ * @nbuf: 802.11 frame
+ * @ether_type: ethernet type
+ * @src_addr: ether shost address
+ *
+ */
+
 static uint32_t dp_tx_update_80211_hdr(struct dp_pdev *pdev,
 				       struct dp_peer *peer,
 				       void *data,
@@ -1273,15 +1387,15 @@ static uint32_t dp_tx_update_80211_hdr(struct dp_pdev *pdev,
 				       uint8_t *src_addr)
 {
 	struct cdp_tx_completion_ppdu *ppdu_desc;
-	struct ieee80211_frame *ptr_wh;
-	struct ieee80211_qoscntl *ptr_qoscntl;
-	uint32_t mpdu_buf_len;
+	uint32_t mpdu_buf_len, frame_size;
 	uint8_t *ptr_hdr;
 	uint16_t eth_type = qdf_htons(ether_type);
 
+	struct ieee80211_qosframe *ptr_wh;
+
 	ppdu_desc = (struct cdp_tx_completion_ppdu *)data;
-	ptr_wh = &peer->tx_capture.tx_wifi_hdr;
-	ptr_qoscntl = &peer->tx_capture.tx_qoscntl;
+
+	ptr_wh = &peer->tx_capture.tx_wifi_qos_hdr;
 
 	/*
 	 * update framectrl only for first ppdu_id
@@ -1295,18 +1409,19 @@ static uint32_t dp_tx_update_80211_hdr(struct dp_pdev *pdev,
 		ptr_wh->i_dur[1] = (ppdu_desc->tx_duration & 0xFF00) >> 8;
 		ptr_wh->i_dur[0] = (ppdu_desc->tx_duration & 0xFF);
 
-		ptr_qoscntl->i_qos[1] = (ppdu_desc->user[0].qos_ctrl &
-					 0xFF00) >> 8;
-		ptr_qoscntl->i_qos[0] = (ppdu_desc->user[0].qos_ctrl & 0xFF);
+		ptr_wh->i_qos[1] = (ppdu_desc->user[0].qos_ctrl & 0xFF00) >> 8;
+		ptr_wh->i_qos[0] = (ppdu_desc->user[0].qos_ctrl & 0xFF);
 		/* Update Addr 3 (SA) with SA derived from ether packet */
 		qdf_mem_copy(ptr_wh->i_addr3, src_addr, QDF_MAC_ADDR_SIZE);
 
 		peer->tx_capture.tx_wifi_ppdu_id = ppdu_desc->ppdu_id;
 	}
 
-	mpdu_buf_len = sizeof(struct ieee80211_frame) + LLC_SNAP_HDR_LEN;
-	if (qdf_likely(ppdu_desc->user[0].tid != DP_NON_QOS_TID))
-		mpdu_buf_len += sizeof(struct ieee80211_qoscntl);
+	frame_size = (ppdu_desc->user[0].tid != DP_NON_QOS_TID) ?
+		      sizeof(struct ieee80211_qosframe) :
+		      sizeof(struct ieee80211_frame);
+
+	mpdu_buf_len = frame_size + LLC_SNAP_HDR_LEN;
 
 	nbuf->protocol = qdf_htons(ETH_P_802_2);
 
@@ -1318,16 +1433,9 @@ static uint32_t dp_tx_update_80211_hdr(struct dp_pdev *pdev,
 	}
 
 	ptr_hdr = (void *)qdf_nbuf_data(nbuf);
-	qdf_mem_copy(ptr_hdr, ptr_wh, sizeof(struct ieee80211_frame));
-
-	ptr_hdr = ptr_hdr + (sizeof(struct ieee80211_frame));
+	qdf_mem_copy(ptr_hdr, ptr_wh, frame_size);
 
-	/* update qoscntl header */
-	if (qdf_likely(ppdu_desc->user[0].tid != DP_NON_QOS_TID)) {
-		qdf_mem_copy(ptr_hdr, ptr_qoscntl,
-			     sizeof(struct ieee80211_qoscntl));
-		ptr_hdr = ptr_hdr + sizeof(struct ieee80211_qoscntl);
-	}
+	ptr_hdr = ptr_hdr + frame_size;
 
 	/* update LLC */
 	*ptr_hdr =  LLC_SNAP_LSAP;
@@ -1389,6 +1497,12 @@ dp_tx_mon_restitch_mpdu(struct dp_pdev *pdev, struct dp_peer *peer,
 		qdf_nbuf_pull_head(curr_nbuf,
 			sizeof(struct msdu_completion_info));
 
+		if ((qdf_likely((peer->vdev->tx_encap_type !=
+				 htt_cmn_pkt_type_raw))) &&
+		    ((ppdu_desc->frame_ctrl & IEEE80211_FC1_DIR_MASK) &&
+		     (IEEE80211_FC1_DIR_TODS | IEEE80211_FC1_DIR_FROMDS)))
+			dp_peer_tx_wds_addr_add(peer, eh->ether_shost);
+
 		if (first_msdu && first_msdu_not_seen) {
 			first_nbuf = curr_nbuf;
 			frag_list_sum_len = 0;
@@ -1445,16 +1559,26 @@ dp_tx_mon_restitch_mpdu(struct dp_pdev *pdev, struct dp_peer *peer,
 						   MAX_MONITOR_HEADER,
 						   4, FALSE);
 
+
 			if (!mpdu_nbuf) {
 				QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE,
 					  QDF_TRACE_LEVEL_FATAL,
 					  "MPDU head allocation failed !!!");
 				goto free_ppdu_desc_mpdu_q;
 			}
-
-			dp_tx_update_80211_hdr(pdev, peer,
-					       ppdu_desc, mpdu_nbuf,
-					       ether_type, eh->ether_shost);
+			if (((ppdu_desc->frame_ctrl & IEEE80211_FC1_DIR_MASK) &&
+			     (IEEE80211_FC1_DIR_TODS |
+			      IEEE80211_FC1_DIR_FROMDS))) {
+				dp_tx_update_80211_wds_hdr(pdev, peer,
+							   ppdu_desc, mpdu_nbuf,
+							   ether_type,
+							   eh->ether_shost);
+			} else {
+				dp_tx_update_80211_hdr(pdev, peer,
+						       ppdu_desc, mpdu_nbuf,
+						       ether_type,
+						       eh->ether_shost);
+			}
 
 			/*
 			 * first nbuf will hold list of msdu

+ 8 - 2
dp/wifi3.0/dp_tx_capture.h

@@ -100,8 +100,14 @@ struct dp_peer_tx_capture {
 	 * for each ppdu, we update and used on rest of mpdu
 	 */
 	uint32_t tx_wifi_ppdu_id;
-	struct ieee80211_frame tx_wifi_hdr;
-	struct ieee80211_qoscntl tx_qoscntl;
+	union {
+		struct ieee80211_frame tx_wifi_hdr;
+		struct ieee80211_qosframe tx_wifi_qos_hdr;
+	};
+	union {
+		struct ieee80211_frame_addr4 tx_wifi_addr4_hdr;
+		struct ieee80211_qosframe_addr4 tx_wifi_addr4_qos_hdr;
+	};
 };
 
 /*