Przeglądaj źródła

qca-wifi: support dummy frame for rts success, mprot_type

before sending tx capture data frame to stack
rts_success flag is checked on set we send rts and cts dummy frames
before data frame.

Change-Id: Id3dccf5c03b05ff381eb595d7807385afb78d462
nobelj 5 lat temu
rodzic
commit
2726d39497
2 zmienionych plików z 108 dodań i 0 usunięć
  1. 107 0
      dp/wifi3.0/dp_tx_capture.c
  2. 1 0
      dp/wifi3.0/dp_tx_capture.h

+ 107 - 0
dp/wifi3.0/dp_tx_capture.c

@@ -36,6 +36,18 @@
 
 /* Macros to handle sequence number bitmaps */
 
+/* HW generated rts frame flag */
+#define SEND_WIFIRTS_LEGACY_E 1
+
+/* HW generated 11 AC static bw flag */
+#define SEND_WIFIRTS_11AC_STATIC_BW_E 2
+
+/* HW generated 11 AC dynamic bw flag */
+#define SEND_WIFIRTS_11AC_DYNAMIC_BW_E 3
+
+/* HW generated cts frame flag */
+#define SEND_WIFICTS2SELF_E 4
+
 /* Size (in bits) of a segment of sequence number bitmap */
 #define SEQ_SEG_SZ_BITS(_seqarr) (sizeof(_seqarr[0]) << 3)
 
@@ -295,6 +307,8 @@ void dp_tx_ppdu_stats_attach(struct dp_pdev *pdev)
 				&pdev->tx_capture.ctl_mgmt_lock[i][j]);
 		}
 	}
+	qdf_mem_zero(&pdev->tx_capture.dummy_ppdu_desc,
+		     sizeof(struct cdp_tx_completion_ppdu));
 }
 
 /**
@@ -1338,6 +1352,14 @@ void dp_update_frame_ctrl_from_frame_type(void *desc)
 	}
 }
 
+/**
+ * dp_send_dummy_mpdu_info_to_stack(): send dummy payload to stack
+ * to upper layer if complete
+ * @pdev: DP pdev handle
+ * @desc: cdp tx completion ppdu desc
+ *
+ * return: status
+ */
 static inline
 QDF_STATUS dp_send_dummy_mpdu_info_to_stack(struct dp_pdev *pdev,
 					  void *desc)
@@ -1455,6 +1477,87 @@ QDF_STATUS dp_send_dummy_mpdu_info_to_stack(struct dp_pdev *pdev,
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * dp_send_dummy_rts_cts_frame(): send dummy rts and cts frame out
+ * to upper layer if complete
+ * @pdev: DP pdev handle
+ * @cur_ppdu_desc: cdp tx completion ppdu desc
+ *
+ * return: void
+ */
+static
+void dp_send_dummy_rts_cts_frame(struct dp_pdev *pdev,
+				 struct cdp_tx_completion_ppdu *cur_ppdu_desc)
+{
+	struct cdp_tx_completion_ppdu *ppdu_desc;
+	struct dp_pdev_tx_capture *ptr_tx_cap;
+	struct dp_peer *peer;
+	uint8_t rts_send;
+
+	rts_send = 0;
+	ptr_tx_cap = &pdev->tx_capture;
+	ppdu_desc = &ptr_tx_cap->dummy_ppdu_desc;
+
+	ppdu_desc->channel = cur_ppdu_desc->channel;
+	ppdu_desc->num_mpdu = 1;
+	ppdu_desc->num_msdu = 1;
+	ppdu_desc->user[0].ppdu_type = HTT_PPDU_STATS_PPDU_TYPE_SU;
+	ppdu_desc->bar_num_users = 0;
+	ppdu_desc->num_users = 1;
+
+	if (cur_ppdu_desc->mprot_type == SEND_WIFIRTS_LEGACY_E ||
+	    cur_ppdu_desc->mprot_type == SEND_WIFIRTS_11AC_DYNAMIC_BW_E ||
+	    cur_ppdu_desc->mprot_type == SEND_WIFIRTS_11AC_STATIC_BW_E) {
+		rts_send = 1;
+		/*
+		 *  send dummy RTS frame followed by CTS
+		 *  update frame_ctrl and htt_frame_type
+		 */
+		ppdu_desc->htt_frame_type = HTT_STATS_FTYPE_SGEN_RTS;
+		ppdu_desc->frame_type = CDP_PPDU_FTYPE_CTRL;
+		ppdu_desc->ppdu_start_timestamp =
+				cur_ppdu_desc->ppdu_start_timestamp;
+		ppdu_desc->ppdu_end_timestamp =
+				cur_ppdu_desc->ppdu_end_timestamp;
+		ppdu_desc->user[0].peer_id = cur_ppdu_desc->user[0].peer_id;
+		ppdu_desc->frame_ctrl = (IEEE80211_FC0_SUBTYPE_RTS |
+					 IEEE80211_FC0_TYPE_CTL);
+		qdf_mem_copy(&ppdu_desc->user[0].mac_addr,
+			     &cur_ppdu_desc->user[0].mac_addr,
+			     QDF_MAC_ADDR_SIZE);
+
+		dp_send_dummy_mpdu_info_to_stack(pdev, ppdu_desc);
+	}
+
+	if ((rts_send && cur_ppdu_desc->rts_success) ||
+	    cur_ppdu_desc->mprot_type == SEND_WIFICTS2SELF_E) {
+		/* send dummy CTS frame */
+		ppdu_desc->htt_frame_type = HTT_STATS_FTYPE_SGEN_CTS;
+		ppdu_desc->frame_type = CDP_PPDU_FTYPE_CTRL;
+		ppdu_desc->frame_ctrl = (IEEE80211_FC0_SUBTYPE_CTS |
+					 IEEE80211_FC0_TYPE_CTL);
+		ppdu_desc->ppdu_start_timestamp =
+				cur_ppdu_desc->ppdu_start_timestamp;
+		ppdu_desc->ppdu_end_timestamp =
+				cur_ppdu_desc->ppdu_end_timestamp;
+		ppdu_desc->user[0].peer_id = cur_ppdu_desc->user[0].peer_id;
+		peer = dp_peer_find_by_id(pdev->soc,
+					  cur_ppdu_desc->user[0].peer_id);
+		if (peer) {
+			struct dp_vdev *vdev = NULL;
+
+			vdev = peer->vdev;
+			if (vdev)
+				qdf_mem_copy(&ppdu_desc->user[0].mac_addr,
+					     vdev->mac_addr.raw,
+					     QDF_MAC_ADDR_SIZE);
+			dp_peer_unref_del_find_by_id(peer);
+		}
+
+		dp_send_dummy_mpdu_info_to_stack(pdev, ppdu_desc);
+	}
+}
+
 /**
  * dp_send_data_to_stack(): Function to deliver mpdu info to stack
  * to upper layer
@@ -1503,6 +1606,9 @@ void dp_send_data_to_stack(struct dp_pdev *pdev,
 	tx_capture_info.mpdu_info.channel_num =
 		pdev->operating_channel;
 
+	if (ppdu_desc->mprot_type)
+		dp_send_dummy_rts_cts_frame(pdev, ppdu_desc);
+
 	start_seq = ppdu_desc->user[0].start_seq;
 	for (i = 0; i < ppdu_desc->user[0].ba_size; i++) {
 		if (qdf_likely(ppdu_desc->user[0].tid !=
@@ -2411,6 +2517,7 @@ dp_check_ppdu_and_deliver(struct dp_pdev *pdev,
 			nbuf_ppdu_desc_list[i]);
 		if (!cur_ppdu_desc)
 			continue;
+
 		peer = dp_peer_find_by_id(pdev->soc,
 					  cur_ppdu_desc->user[0].peer_id);
 		if (!peer) {

+ 1 - 0
dp/wifi3.0/dp_tx_capture.h

@@ -59,6 +59,7 @@ struct dp_pdev_tx_capture {
 	qdf_spinlock_t ctl_mgmt_lock[TXCAP_MAX_TYPE][TXCAP_MAX_SUBTYPE];
 	qdf_spinlock_t config_lock;
 	uint32_t htt_frame_type[TX_CAP_HTT_MAX_FTYPE];
+	struct cdp_tx_completion_ppdu dummy_ppdu_desc;
 };
 
 /* Tx TID */