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

qcacmn: Implement SWLM support for multi TX queue

Update SWLM data structures and API's to support
multi TX queue based traffic.

Change-Id: I67921a749b61b3c717f33f770095fbb4d3062e2f
CRs-Fixed: 3161165
Karthik Kantamneni 3 жил өмнө
parent
commit
d98299184b

+ 3 - 2
dp/wifi3.0/be/dp_be_tx.c

@@ -647,11 +647,12 @@ dp_tx_hw_enqueue_be(struct dp_soc *soc, struct dp_vdev *vdev,
 	/* Sync cached descriptor with HW */
 	hal_tx_desc_sync(hal_tx_desc_cached, hal_tx_desc);
 
-	coalesce = dp_tx_attempt_coalescing(soc, vdev, tx_desc, tid, msdu_info);
+	coalesce = dp_tx_attempt_coalescing(soc, vdev, tx_desc, tid,
+					    msdu_info, ring_id);
 
 	DP_STATS_INC_PKT(vdev, tx_i.processed, 1, tx_desc->length);
 	DP_STATS_INC(soc, tx.tcl_enq[ring_id], 1);
-	dp_tx_update_stats(soc, tx_desc->nbuf);
+	dp_tx_update_stats(soc, tx_desc, ring_id);
 	status = QDF_STATUS_SUCCESS;
 
 	dp_tx_hw_desc_update_evt((uint8_t *)hal_tx_desc_cached,

+ 1 - 1
dp/wifi3.0/dp_stats.c

@@ -7983,7 +7983,7 @@ QDF_STATUS dp_txrx_get_soc_stats(struct cdp_soc_t *soc_hdl,
 	uint8_t cpus;
 
 	/* soc tx stats */
-	soc_stats->tx.egress = soc->stats.tx.egress;
+	soc_stats->tx.egress = soc->stats.tx.egress[0];
 	soc_stats->tx.tx_invalid_peer = soc->stats.tx.tx_invalid_peer;
 	for (inx = 0; inx < CDP_MAX_TX_DATA_RINGS; inx++) {
 		soc_stats->tx.tx_hw_enq[inx] = soc->stats.tx.tcl_enq[inx];

+ 25 - 8
dp/wifi3.0/dp_tx.c

@@ -1396,21 +1396,31 @@ void dp_vdev_peer_stats_update_protocol_cnt_tx(struct dp_vdev *vdev_hdl,
 /**
  * dp_tx_update_stats() - Update soc level tx stats
  * @soc: DP soc handle
- * @nbuf: packet being transmitted
+ * @tx_desc: TX descriptor reference
+ * @ring_id: TCL ring id
  *
  * Returns: none
  */
 void dp_tx_update_stats(struct dp_soc *soc,
-			qdf_nbuf_t nbuf)
+			struct dp_tx_desc_s *tx_desc,
+			uint8_t ring_id)
 {
-	DP_STATS_INC_PKT(soc, tx.egress, 1, qdf_nbuf_len(nbuf));
+	uint32_t stats_len = 0;
+
+	if (tx_desc->frm_type == dp_tx_frm_tso)
+		stats_len  = tx_desc->msdu_ext_desc->tso_desc->seg.total_len;
+	else
+		stats_len = qdf_nbuf_len(tx_desc->nbuf);
+
+	DP_STATS_INC_PKT(soc, tx.egress[ring_id], 1, stats_len);
 }
 
 int
 dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
 			 struct dp_tx_desc_s *tx_desc,
 			 uint8_t tid,
-			 struct dp_tx_msdu_info_s *msdu_info)
+			 struct dp_tx_msdu_info_s *msdu_info,
+			 uint8_t ring_id)
 {
 	struct dp_swlm *swlm = &soc->swlm;
 	union swlm_data swlm_query_data;
@@ -1423,21 +1433,28 @@ dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
 
 	tcl_data.nbuf = tx_desc->nbuf;
 	tcl_data.tid = tid;
+	tcl_data.ring_id = ring_id;
+	if (tx_desc->frm_type == dp_tx_frm_tso) {
+		tcl_data.pkt_len  =
+			tx_desc->msdu_ext_desc->tso_desc->seg.total_len;
+	} else {
+		tcl_data.pkt_len = qdf_nbuf_len(tx_desc->nbuf);
+	}
 	tcl_data.num_ll_connections = vdev->num_latency_critical_conn;
 	swlm_query_data.tcl_data = &tcl_data;
 
 	status = dp_swlm_tcl_pre_check(soc, &tcl_data);
 	if (QDF_IS_STATUS_ERROR(status)) {
-		dp_swlm_tcl_reset_session_data(soc);
-		DP_STATS_INC(swlm, tcl.coalesce_fail, 1);
+		dp_swlm_tcl_reset_session_data(soc, ring_id);
+		DP_STATS_INC(swlm, tcl[ring_id].coalesce_fail, 1);
 		return 0;
 	}
 
 	ret = dp_swlm_query_policy(soc, TCL_DATA, swlm_query_data);
 	if (ret) {
-		DP_STATS_INC(swlm, tcl.coalesce_success, 1);
+		DP_STATS_INC(swlm, tcl[ring_id].coalesce_success, 1);
 	} else {
-		DP_STATS_INC(swlm, tcl.coalesce_fail, 1);
+		DP_STATS_INC(swlm, tcl[ring_id].coalesce_fail, 1);
 	}
 
 	return ret;

+ 15 - 6
dp/wifi3.0/dp_tx.h

@@ -771,12 +771,14 @@ dp_send_completion_to_pkt_capture(struct dp_soc *soc,
 /**
  * dp_tx_update_stats() - Update soc level tx stats
  * @soc: DP soc handle
- * @nbuf: packet being transmitted
+ * @tx_desc: TX descriptor reference
+ * @ring_id: TCL ring id
  *
  * Returns: none
  */
 void dp_tx_update_stats(struct dp_soc *soc,
-			qdf_nbuf_t nbuf);
+			struct dp_tx_desc_s *tx_desc,
+			uint8_t ring_id);
 
 /**
  * dp_tx_attempt_coalescing() - Check and attempt TCL register write coalescing
@@ -784,6 +786,7 @@ void dp_tx_update_stats(struct dp_soc *soc,
  * @tx_desc: tx packet descriptor
  * @tid: TID for pkt transmission
  * @msdu_info: MSDU info of tx packet
+ * @ring_id: TCL ring id
  *
  * Returns: 1, if coalescing is to be done
  *	    0, if coalescing is not to be done
@@ -791,7 +794,9 @@ void dp_tx_update_stats(struct dp_soc *soc,
 int
 dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
 			 struct dp_tx_desc_s *tx_desc,
-			 uint8_t tid, struct dp_tx_msdu_info_s *msdu_info);
+			 uint8_t tid,
+			 struct dp_tx_msdu_info_s *msdu_info,
+			 uint8_t ring_id);
 
 /**
  * dp_tx_ring_access_end() - HAL ring access end for data transmission
@@ -808,12 +813,15 @@ dp_tx_ring_access_end(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl,
 /**
  * dp_tx_update_stats() - Update soc level tx stats
  * @soc: DP soc handle
- * @nbuf: packet being transmitted
+ * @tx_desc: TX descriptor reference
+ * @ring_id: TCL ring id
  *
  * Returns: none
  */
 static inline void dp_tx_update_stats(struct dp_soc *soc,
-				      qdf_nbuf_t nbuf) { }
+				      struct dp_tx_desc_s *tx_desc,
+				      uint8_t ring_id){ }
+
 static inline void
 dp_tx_ring_access_end(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl,
 		      int coalesce)
@@ -825,7 +833,8 @@ static inline int
 dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
 			 struct dp_tx_desc_s *tx_desc,
 			 uint8_t tid,
-			 struct dp_tx_msdu_info_s *msdu_info)
+			 struct dp_tx_msdu_info_s *msdu_info,
+			 uint8_t ring_id)
 {
 	return 0;
 }

+ 52 - 26
dp/wifi3.0/dp_types.h

@@ -1020,7 +1020,7 @@ struct dp_soc_stats {
 	/* SOC level TX stats */
 	struct {
 		/* Total packets transmitted */
-		struct cdp_pkt_info egress;
+		struct cdp_pkt_info egress[MAX_TCL_DATA_RINGS];
 		/* Enqueues per tcl ring */
 		uint32_t tcl_enq[MAX_TCL_DATA_RINGS];
 		/* packets dropped on tx because of no peer */
@@ -1489,6 +1489,8 @@ struct dp_last_op_info {
  * @nbuf: TX packet
  * @tid: tid for transmitting the current packet
  * @num_ll_connections: Number of low latency connections on this vdev
+ * @ring_id: TCL ring id
+ * @pkt_len: Packet length
  *
  * This structure contains the information required by the software
  * latency manager to decide on whether to coalesce the current TCL
@@ -1498,6 +1500,8 @@ struct dp_swlm_tcl_data {
 	qdf_nbuf_t nbuf;
 	uint8_t tid;
 	uint8_t num_ll_connections;
+	uint8_t ring_id;
+	uint32_t pkt_len;
 };
 
 /**
@@ -1549,43 +1553,65 @@ struct dp_swlm_stats {
 		uint32_t tput_criteria_fail;
 		uint32_t coalesce_success;
 		uint32_t coalesce_fail;
-	} tcl;
+	} tcl[MAX_TCL_DATA_RINGS];
+};
+
+/**
+ * struct dp_swlm_tcl_params: Parameters based on TCL for different modules
+ *			      in the Software latency manager.
+ * @soc: DP soc reference
+ * @ring_id: TCL ring id
+ * @flush_timer: Timer for flushing the coalesced TCL HP writes
+ * @sampling_session_tx_bytes: Num bytes transmitted in the sampling time
+ * @bytes_flush_thresh: Bytes threshold to flush the TCL HP register write
+ * @coalesce_end_time: End timestamp for current coalescing session
+ * @bytes_coalesced: Num bytes coalesced in the current session
+ * @prev_tx_packets: Previous TX packets accounted
+ * @prev_tx_bytes: Previous TX bytes accounted
+ * @prev_rx_bytes: Previous RX bytes accounted
+ * @expire_time: expiry time for sample
+ * @tput_pass_cnt: threshold throughput pass counter
+ */
+struct dp_swlm_tcl_params {
+	struct dp_soc *soc;
+	uint32_t ring_id;
+	qdf_timer_t flush_timer;
+	uint32_t sampling_session_tx_bytes;
+	uint32_t bytes_flush_thresh;
+	uint64_t coalesce_end_time;
+	uint32_t bytes_coalesced;
+	uint32_t prev_tx_packets;
+	uint32_t prev_tx_bytes;
+	uint32_t prev_rx_bytes;
+	uint64_t expire_time;
+	uint32_t tput_pass_cnt;
 };
 
 /**
  * struct dp_swlm_params: Parameters for different modules in the
  *			  Software latency manager.
- * @tcl.flush_timer: Timer for flushing the coalesced TCL HP writes
- * @tcl.rx_traffic_thresh: Threshold for RX traffic, to begin TCL register
+ * @rx_traffic_thresh: Threshold for RX traffic, to begin TCL register
  *			   write coalescing
- * @tcl.tx_traffic_thresh: Threshold for TX traffic, to begin TCL register
+ * @tx_traffic_thresh: Threshold for TX traffic, to begin TCL register
  *			   write coalescing
- * @tcl.sampling_time: Sampling time to test the throughput threshold
- * @tcl.sampling_session_tx_bytes: Num bytes transmitted in the sampling time
- * @tcl.bytes_flush_thresh: Bytes threshold to flush the TCL HP register write
- * @tcl.time_flush_thresh: Time threshold to flush the TCL HP register write
- * @tcl.tx_thresh_multiplier: Multiplier to deduce the bytes threshold after
+ * @sampling_time: Sampling time to test the throughput threshold
+ * @time_flush_thresh: Time threshold to flush the TCL HP register write
+ * @tx_thresh_multiplier: Multiplier to deduce the bytes threshold after
  *			      which the TCL HP register is written, thereby
  *			      ending the coalescing.
- * @tcl.coalesce_end_time: End timestamp for current coalescing session
- * @tcl.bytes_coalesced: Num bytes coalesced in the current session
- * @tcl.tx_pkt_thresh: Threshold for TX packet count, to begin TCL register
+ * @tx_pkt_thresh: Threshold for TX packet count, to begin TCL register
  *		       write coalescing
+ * @tcl: TCL ring specific params
  */
+
 struct dp_swlm_params {
-	struct {
-		qdf_timer_t flush_timer;
-		uint32_t rx_traffic_thresh;
-		uint32_t tx_traffic_thresh;
-		uint32_t sampling_time;
-		uint32_t sampling_session_tx_bytes;
-		uint32_t bytes_flush_thresh;
-		uint32_t time_flush_thresh;
-		uint32_t tx_thresh_multiplier;
-		uint64_t coalesce_end_time;
-		uint32_t bytes_coalesced;
-		uint32_t tx_pkt_thresh;
-	} tcl;
+	uint32_t rx_traffic_thresh;
+	uint32_t tx_traffic_thresh;
+	uint32_t sampling_time;
+	uint32_t time_flush_thresh;
+	uint32_t tx_thresh_multiplier;
+	uint32_t tx_pkt_thresh;
+	struct dp_swlm_tcl_params tcl[MAX_TCL_DATA_RINGS];
 };
 
 /**

+ 3 - 2
dp/wifi3.0/li/dp_li_tx.c

@@ -498,10 +498,11 @@ dp_tx_hw_enqueue_li(struct dp_soc *soc, struct dp_vdev *vdev,
 	tx_desc->flags |= DP_TX_DESC_FLAG_QUEUED_TX;
 	dp_vdev_peer_stats_update_protocol_cnt_tx(vdev, tx_desc->nbuf);
 	hal_tx_desc_sync(hal_tx_desc_cached, hal_tx_desc);
-	coalesce = dp_tx_attempt_coalescing(soc, vdev, tx_desc, tid, msdu_info);
+	coalesce = dp_tx_attempt_coalescing(soc, vdev, tx_desc, tid,
+					    msdu_info, ring_id);
 	DP_STATS_INC_PKT(vdev, tx_i.processed, 1, tx_desc->length);
 	DP_STATS_INC(soc, tx.tcl_enq[ring_id], 1);
-	dp_tx_update_stats(soc, tx_desc->nbuf);
+	dp_tx_update_stats(soc, tx_desc, ring_id);
 	status = QDF_STATUS_SUCCESS;
 
 	dp_tx_hw_desc_update_evt((uint8_t *)hal_tx_desc_cached,