Browse Source

qcacmn: Add stats for new TQM release reason on BE

Add Tx completion stats for TQM release reason added
for BE

Change-Id: I7d28cbfacd1378982c5cf9a3f2cf3cffa070ee87
Chaithanya Garrepalli 3 years ago
parent
commit
be02a2d44f
6 changed files with 214 additions and 92 deletions
  1. 14 0
      dp/inc/cdp_txrx_stats_struct.h
  2. 21 0
      dp/wifi3.0/dp_internal.h
  3. 88 39
      dp/wifi3.0/dp_stats.c
  4. 66 53
      dp/wifi3.0/dp_tx.c
  5. 13 0
      dp/wifi3.0/dp_types.h
  6. 12 0
      hal/wifi3.0/hal_tx.h

+ 14 - 0
dp/inc/cdp_txrx_stats_struct.h

@@ -1300,6 +1300,13 @@ struct protocol_trace_count {
  * @fw_reason1: discarded by firmware reason 1
  * @fw_reason2: discarded by firmware reason 2
  * @fw_reason3: discarded by firmware reason 3
+ * @fw_rem_queue_disable: dropped due to queue disable
+ * @fw_rem_no_match: dropped due to fw no match command
+ * @drop_threshold: dropped due to HW threshold
+ * @drop_link_desc_na: dropped due resource not available in HW
+ * @invalid_drop: Invalid msdu drop
+ * @mcast_vdev_drop: MCAST drop configured for VDEV in HW
+ * @invalid_rr: Invalid TQM release reason
  * @mcs_count: MCS Count
  * @an_tx_cnt: ald tx count
  * @an_tx_rates_used: ald rx rate used
@@ -1409,6 +1416,13 @@ struct cdp_tx_stats {
 		uint32_t fw_reason1;
 		uint32_t fw_reason2;
 		uint32_t fw_reason3;
+		uint32_t fw_rem_queue_disable;
+		uint32_t fw_rem_no_match;
+		uint32_t drop_threshold;
+		uint32_t drop_link_desc_na;
+		uint32_t invalid_drop;
+		uint32_t mcast_vdev_drop;
+		uint32_t invalid_rr;
 	} dropped;
 
 

+ 21 - 0
dp/wifi3.0/dp_internal.h

@@ -1409,6 +1409,13 @@ void dp_update_vdev_stats_on_peer_unmap(struct dp_vdev *vdev,
 		DP_STATS_AGGR(_tgtobj, _srcobj, tx.dropped.fw_reason1); \
 		DP_STATS_AGGR(_tgtobj, _srcobj, tx.dropped.fw_reason2); \
 		DP_STATS_AGGR(_tgtobj, _srcobj, tx.dropped.fw_reason3); \
+		DP_STATS_AGGR(_tgtobj, _srcobj, tx.dropped.fw_rem_queue_disable); \
+		DP_STATS_AGGR(_tgtobj, _srcobj, tx.dropped.fw_rem_no_match); \
+		DP_STATS_AGGR(_tgtobj, _srcobj, tx.dropped.drop_threshold); \
+		DP_STATS_AGGR(_tgtobj, _srcobj, tx.dropped.drop_link_desc_na); \
+		DP_STATS_AGGR(_tgtobj, _srcobj, tx.dropped.invalid_drop); \
+		DP_STATS_AGGR(_tgtobj, _srcobj, tx.dropped.mcast_vdev_drop); \
+		DP_STATS_AGGR(_tgtobj, _srcobj, tx.dropped.invalid_rr); \
 		DP_STATS_AGGR(_tgtobj, _srcobj, tx.dropped.age_out); \
 								\
 		DP_STATS_AGGR(_tgtobj, _srcobj, rx.err.mic_err); \
@@ -1527,6 +1534,20 @@ void dp_update_vdev_stats_on_peer_unmap(struct dp_vdev *vdev,
 					_srcobj->tx.dropped.fw_reason2; \
 		_tgtobj->tx.dropped.fw_reason3 += \
 					_srcobj->tx.dropped.fw_reason3; \
+		_tgtobj->tx.dropped.fw_rem_queue_disable += \
+					_srcobj->tx.dropped.fw_rem_queue_disable; \
+		_tgtobj->tx.dropped.fw_rem_no_match += \
+					_srcobj->tx.dropped.fw_rem_no_match; \
+		_tgtobj->tx.dropped.drop_threshold += \
+					_srcobj->tx.dropped.drop_threshold; \
+		_tgtobj->tx.dropped.drop_link_desc_na += \
+					_srcobj->tx.dropped.drop_link_desc_na; \
+		_tgtobj->tx.dropped.invalid_drop += \
+					_srcobj->tx.dropped.invalid_drop; \
+		_tgtobj->tx.dropped.mcast_vdev_drop += \
+					_srcobj->tx.dropped.mcast_vdev_drop; \
+		_tgtobj->tx.dropped.invalid_rr += \
+					_srcobj->tx.dropped.invalid_rr; \
 		_tgtobj->tx.failed_retry_count += \
 					_srcobj->tx.failed_retry_count; \
 		_tgtobj->tx.retry_count += _srcobj->tx.retry_count; \

+ 88 - 39
dp/wifi3.0/dp_stats.c

@@ -6026,6 +6026,24 @@ void dp_print_peer_stats(struct dp_peer *peer,
 		       peer_stats->tx.dropped.fw_rem_tx);
 	DP_PRINT_STATS("Dropped At FW: Removed Untransmitted = %d",
 		       peer_stats->tx.dropped.fw_rem_notx);
+	DP_PRINT_STATS("Dropped At FW: removed untransmitted fw_reason1 = %u",
+		       peer_stats->tx.dropped.fw_reason1);
+	DP_PRINT_STATS("Dropped At FW: removed untransmitted fw_reason2 = %u",
+		       peer_stats->tx.dropped.fw_reason2);
+	DP_PRINT_STATS("Dropped At FW: removed untransmitted fw_reason3 = %u",
+		       peer_stats->tx.dropped.fw_reason3);
+	DP_PRINT_STATS("Dropped At FW:removed untransmitted disable queue = %u",
+		       peer_stats->tx.dropped.fw_rem_queue_disable);
+	DP_PRINT_STATS("Dropped At FW: removed untransmitted no match = %u",
+		       peer_stats->tx.dropped.fw_rem_no_match);
+	DP_PRINT_STATS("Dropped due to HW threshold criteria = %u",
+		       peer_stats->tx.dropped.drop_threshold);
+	DP_PRINT_STATS("Dropped due Link desc not available drop in HW = %u",
+		       peer_stats->tx.dropped.drop_link_desc_na);
+	DP_PRINT_STATS("Drop bit set or invalid flow = %u",
+		       peer_stats->tx.dropped.invalid_drop);
+	DP_PRINT_STATS("MCAST vdev drop in HW = %u",
+		       peer_stats->tx.dropped.mcast_vdev_drop);
 	DP_PRINT_STATS("Dropped : Age Out = %d",
 		       peer_stats->tx.dropped.age_out);
 	DP_PRINT_STATS("NAWDS : ");
@@ -6523,12 +6541,12 @@ dp_print_pdev_tx_stats(struct dp_pdev *pdev)
 
 	DP_PRINT_STATS("PDEV Tx Stats:\n");
 	DP_PRINT_STATS("Received From Stack:");
-	DP_PRINT_STATS("	Packets = %d",
+	DP_PRINT_STATS("	Packets = %u",
 		       pdev->stats.tx_i.rcvd.num);
 	DP_PRINT_STATS("	Bytes = %llu",
 		       pdev->stats.tx_i.rcvd.bytes);
 	DP_PRINT_STATS("Processed:");
-	DP_PRINT_STATS("	Packets = %d",
+	DP_PRINT_STATS("	Packets = %u",
 		       pdev->stats.tx_i.processed.num);
 	DP_PRINT_STATS("	Bytes = %llu",
 		       pdev->stats.tx_i.processed.bytes);
@@ -6543,41 +6561,57 @@ dp_print_pdev_tx_stats(struct dp_pdev *pdev)
 	DP_PRINT_STATS("	Bytes = %llu",
 		       pdev->stats.tx.tx_success.bytes);
 	DP_PRINT_STATS("Dropped:");
-	DP_PRINT_STATS("	Total = %d",
+	DP_PRINT_STATS("	Total = %u",
 		       pdev->stats.tx_i.dropped.dropped_pkt.num);
-	DP_PRINT_STATS("	Dma_map_error = %d",
+	DP_PRINT_STATS("	Dma_map_error = %u",
 		       pdev->stats.tx_i.dropped.dma_error);
-	DP_PRINT_STATS("	Ring Full = %d",
+	DP_PRINT_STATS("	Ring Full = %u",
 		       pdev->stats.tx_i.dropped.ring_full);
-	DP_PRINT_STATS("	Descriptor Not available = %d",
+	DP_PRINT_STATS("	Descriptor Not available = %u",
 		       pdev->stats.tx_i.dropped.desc_na.num);
-	DP_PRINT_STATS("	HW enqueue failed= %d",
+	DP_PRINT_STATS("	HW enqueue failed= %u",
 		       pdev->stats.tx_i.dropped.enqueue_fail);
-	DP_PRINT_STATS("        Descriptor alloc fail = %d",
+	DP_PRINT_STATS("        Descriptor alloc fail = %u",
 		       pdev->stats.tx_i.dropped.desc_na_exc_alloc_fail.num);
-	DP_PRINT_STATS("        Tx outstanding too many = %d",
+	DP_PRINT_STATS("        Tx outstanding too many = %u",
 		       pdev->stats.tx_i.dropped.desc_na_exc_outstand.num);
-	DP_PRINT_STATS("	Pkt dropped in vdev-id check= %d",
+	DP_PRINT_STATS("	Pkt dropped in vdev-id check= %u",
 		       pdev->stats.tx_i.dropped.fail_per_pkt_vdev_id_check);
-	DP_PRINT_STATS("	Resources Full = %d",
+	DP_PRINT_STATS("	Resources Full = %u",
 		       pdev->stats.tx_i.dropped.res_full);
+	DP_PRINT_STATS("Tx failed = %u",
+		       pdev->stats.tx.tx_failed);
 	DP_PRINT_STATS("	FW removed Pkts = %u",
 		       pdev->stats.tx.dropped.fw_rem.num);
 	DP_PRINT_STATS("	FW removed bytes= %llu",
 		       pdev->stats.tx.dropped.fw_rem.bytes);
-	DP_PRINT_STATS("	FW removed transmitted = %d",
+	DP_PRINT_STATS("	FW removed transmitted = %u",
 		       pdev->stats.tx.dropped.fw_rem_tx);
-	DP_PRINT_STATS("	FW removed untransmitted = %d",
+	DP_PRINT_STATS("	FW removed untransmitted = %u",
 		       pdev->stats.tx.dropped.fw_rem_notx);
-	DP_PRINT_STATS("	FW removed untransmitted fw_reason1 = %d",
+	DP_PRINT_STATS("	FW removed untransmitted fw_reason1 = %u",
 		       pdev->stats.tx.dropped.fw_reason1);
-	DP_PRINT_STATS("	FW removed untransmitted fw_reason2 = %d",
+	DP_PRINT_STATS("	FW removed untransmitted fw_reason2 = %u",
 		       pdev->stats.tx.dropped.fw_reason2);
-	DP_PRINT_STATS("	FW removed untransmitted fw_reason3 = %d",
+	DP_PRINT_STATS("	FW removed untransmitted fw_reason3 = %u",
 		       pdev->stats.tx.dropped.fw_reason3);
-	DP_PRINT_STATS("	Aged Out from msdu/mpdu queues = %d",
+	DP_PRINT_STATS("	FW removed untransmitted disable queue = %u",
+		       pdev->stats.tx.dropped.fw_rem_queue_disable);
+	DP_PRINT_STATS("	FW removed untransmitted no match = %u",
+		       pdev->stats.tx.dropped.fw_rem_no_match);
+	DP_PRINT_STATS("	Dropped due to HW threshold criteria = %u",
+		       pdev->stats.tx.dropped.drop_threshold);
+	DP_PRINT_STATS("	Link desc not available drop = %u",
+		       pdev->stats.tx.dropped.drop_link_desc_na);
+	DP_PRINT_STATS("	Drop bit set or invalid flow = %u",
+		       pdev->stats.tx.dropped.invalid_drop);
+	DP_PRINT_STATS("	MCAST vdev drop in HW = %u",
+		       pdev->stats.tx.dropped.mcast_vdev_drop);
+	DP_PRINT_STATS("	Dropped with invalid reason = %u",
+		       pdev->stats.tx.dropped.invalid_rr);
+	DP_PRINT_STATS("	Aged Out from msdu/mpdu queues = %u",
 		       pdev->stats.tx.dropped.age_out);
-	DP_PRINT_STATS("	headroom insufficient = %d",
+	DP_PRINT_STATS("	headroom insufficient = %u",
 		       pdev->stats.tx_i.dropped.headroom_insufficient);
 	DP_PRINT_STATS("Multicast:");
 	DP_PRINT_STATS("	Packets: %u",
@@ -6589,41 +6623,41 @@ dp_print_pdev_tx_stats(struct dp_pdev *pdev)
 		       pdev->stats.tx_i.sg.sg_pkt.num);
 	DP_PRINT_STATS("	Bytes = %llu",
 		       pdev->stats.tx_i.sg.sg_pkt.bytes);
-	DP_PRINT_STATS("	Dropped By Host = %d",
+	DP_PRINT_STATS("	Dropped By Host = %u",
 		       pdev->stats.tx_i.sg.dropped_host.num);
-	DP_PRINT_STATS("	Dropped By Target = %d",
+	DP_PRINT_STATS("	Dropped By Target = %u",
 		       pdev->stats.tx_i.sg.dropped_target);
 	DP_PRINT_STATS("Mcast Enhancement:");
-	DP_PRINT_STATS("	Packets = %d",
+	DP_PRINT_STATS("	Packets = %u",
 		       pdev->stats.tx_i.mcast_en.mcast_pkt.num);
 	DP_PRINT_STATS("	Bytes = %llu",
 		       pdev->stats.tx_i.mcast_en.mcast_pkt.bytes);
-	DP_PRINT_STATS("	Dropped: Map Errors = %d",
+	DP_PRINT_STATS("	Dropped: Map Errors = %u",
 		       pdev->stats.tx_i.mcast_en.dropped_map_error);
-	DP_PRINT_STATS("	Dropped: Self Mac = %d",
+	DP_PRINT_STATS("	Dropped: Self Mac = %u",
 		       pdev->stats.tx_i.mcast_en.dropped_self_mac);
-	DP_PRINT_STATS("	Dropped: Send Fail = %d",
+	DP_PRINT_STATS("	Dropped: Send Fail = %u",
 		       pdev->stats.tx_i.mcast_en.dropped_send_fail);
-	DP_PRINT_STATS("	Unicast sent = %d",
+	DP_PRINT_STATS("	Unicast sent = %u",
 		       pdev->stats.tx_i.mcast_en.ucast);
 	DP_PRINT_STATS("IGMP Mcast Enhancement:");
-	DP_PRINT_STATS("	IGMP packets received = %d",
+	DP_PRINT_STATS("	IGMP packets received = %u",
 		       pdev->stats.tx_i.igmp_mcast_en.igmp_rcvd);
-	DP_PRINT_STATS("	Converted to uncast = %d",
+	DP_PRINT_STATS("	Converted to uncast = %u",
 		       pdev->stats.tx_i.igmp_mcast_en.igmp_ucast_converted);
 	DP_PRINT_STATS("Raw:");
-	DP_PRINT_STATS("	Packets = %d",
+	DP_PRINT_STATS("	Packets = %u",
 		       pdev->stats.tx_i.raw.raw_pkt.num);
 	DP_PRINT_STATS("	Bytes = %llu",
 		       pdev->stats.tx_i.raw.raw_pkt.bytes);
-	DP_PRINT_STATS("	DMA map error = %d",
+	DP_PRINT_STATS("	DMA map error = %u",
 		       pdev->stats.tx_i.raw.dma_map_error);
-	DP_PRINT_STATS("        RAW pkt type[!data] error = %d",
+	DP_PRINT_STATS("        RAW pkt type[!data] error = %u",
 		       pdev->stats.tx_i.raw.invalid_raw_pkt_datatype);
-	DP_PRINT_STATS("        Frags count overflow  error = %d",
+	DP_PRINT_STATS("        Frags count overflow  error = %u",
 		       pdev->stats.tx_i.raw.num_frags_overflow_err);
 	DP_PRINT_STATS("Reinjected:");
-	DP_PRINT_STATS("	Packets = %d",
+	DP_PRINT_STATS("	Packets = %u",
 		       pdev->stats.tx_i.reinject_pkts.num);
 	DP_PRINT_STATS("	Bytes = %llu\n",
 		       pdev->stats.tx_i.reinject_pkts.bytes);
@@ -6633,7 +6667,7 @@ dp_print_pdev_tx_stats(struct dp_pdev *pdev)
 	DP_PRINT_STATS("	Bytes = %llu",
 		       pdev->stats.tx_i.inspect_pkts.bytes);
 	DP_PRINT_STATS("Nawds Multicast:");
-	DP_PRINT_STATS("	Packets = %d",
+	DP_PRINT_STATS("	Packets = %u",
 		       pdev->stats.tx_i.nawds_mcast.num);
 	DP_PRINT_STATS("	Bytes = %llu",
 		       pdev->stats.tx_i.nawds_mcast.bytes);
@@ -6652,7 +6686,7 @@ dp_print_pdev_tx_stats(struct dp_pdev *pdev)
 		DP_PRINT_STATS("	Tag[%d] = %llu", index,
 			       pdev->stats.ppdu_stats_counter[index]);
 	}
-	DP_PRINT_STATS("BA not received for delayed_ba: %d",
+	DP_PRINT_STATS("BA not received for delayed_ba: %u",
 		       pdev->stats.cdp_delayed_ba_not_recev);
 
 	dp_monitor_print_tx_stats(pdev);
@@ -6768,18 +6802,19 @@ dp_print_soc_tx_stats(struct dp_soc *soc)
 		soc->stats.tx.desc_in_use +=
 			soc->tx_desc[desc_pool_id].num_allocated;
 
-	DP_PRINT_STATS("Tx Descriptors In Use = %d",
+	DP_PRINT_STATS("Tx Descriptors In Use = %u",
 		       soc->stats.tx.desc_in_use);
 	DP_PRINT_STATS("Tx Invalid peer:");
-	DP_PRINT_STATS("	Packets = %d",
+	DP_PRINT_STATS("	Packets = %u",
 		       soc->stats.tx.tx_invalid_peer.num);
 	DP_PRINT_STATS("	Bytes = %llu",
 		       soc->stats.tx.tx_invalid_peer.bytes);
-	DP_PRINT_STATS("Packets dropped due to TCL ring full = %d %d %d",
+	DP_PRINT_STATS("Packets dropped due to TCL ring full = %u %u %u %u",
 		       soc->stats.tx.tcl_ring_full[0],
 		       soc->stats.tx.tcl_ring_full[1],
-		       soc->stats.tx.tcl_ring_full[2]);
-	DP_PRINT_STATS("Tx invalid completion release = %d",
+		       soc->stats.tx.tcl_ring_full[2],
+		       soc->stats.tx.tcl_ring_full[3]);
+	DP_PRINT_STATS("Tx invalid completion release = %u",
 		       soc->stats.tx.invalid_release_source);
 	DP_PRINT_STATS("Tx comp wbm internal error = %d : [%d %d %d %d]",
 		       soc->stats.tx.wbm_internal_error[WBM_INT_ERROR_ALL],
@@ -7597,6 +7632,20 @@ void dp_update_pdev_stats(struct dp_pdev *tgtobj,
 			srcobj->tx.dropped.fw_reason2;
 	tgtobj->stats.tx.dropped.fw_reason3 +=
 			srcobj->tx.dropped.fw_reason3;
+	tgtobj->stats.tx.dropped.fw_rem_queue_disable +=
+				srcobj->tx.dropped.fw_rem_queue_disable;
+	tgtobj->stats.tx.dropped.fw_rem_no_match +=
+				srcobj->tx.dropped.fw_rem_no_match;
+	tgtobj->stats.tx.dropped.drop_threshold +=
+				srcobj->tx.dropped.drop_threshold;
+	tgtobj->stats.tx.dropped.drop_link_desc_na +=
+				srcobj->tx.dropped.drop_link_desc_na;
+	tgtobj->stats.tx.dropped.invalid_drop +=
+				srcobj->tx.dropped.invalid_drop;
+	tgtobj->stats.tx.dropped.mcast_vdev_drop +=
+					srcobj->tx.dropped.mcast_vdev_drop;
+	tgtobj->stats.tx.dropped.invalid_rr +=
+				srcobj->tx.dropped.invalid_rr;
 	tgtobj->stats.tx.dropped.age_out += srcobj->tx.dropped.age_out;
 	tgtobj->stats.rx.err.mic_err += srcobj->rx.err.mic_err;
 	tgtobj->stats.rx.err.decrypt_err += srcobj->rx.err.decrypt_err;

+ 66 - 53
dp/wifi3.0/dp_tx.c

@@ -3899,7 +3899,6 @@ dp_tx_update_peer_stats(struct dp_tx_desc_s *tx_desc,
 			struct dp_txrx_peer *txrx_peer, uint8_t ring_id)
 {
 	struct dp_pdev *pdev = txrx_peer->vdev->pdev;
-	struct dp_soc *soc = NULL;
 	uint8_t tid = ts->tid;
 	uint32_t length;
 	struct cdp_tid_tx_stats *tid_stats;
@@ -3911,7 +3910,6 @@ dp_tx_update_peer_stats(struct dp_tx_desc_s *tx_desc,
 		tid = CDP_MAX_DATA_TIDS - 1;
 
 	tid_stats = &pdev->stats.tid_stats.tid_tx_stats[ring_id][tid];
-	soc = pdev->soc;
 
 	if (ts->release_src != HAL_TX_COMP_RELEASE_SOURCE_TQM) {
 		dp_err("Release source is not from TQM");
@@ -3923,68 +3921,83 @@ dp_tx_update_peer_stats(struct dp_tx_desc_s *tx_desc,
 
 	if (qdf_unlikely(pdev->delay_stats_flag))
 		dp_tx_compute_delay(txrx_peer->vdev, tx_desc, tid, ring_id);
-	DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.dropped.age_out, 1,
-			  (ts->status == HAL_TX_TQM_RR_REM_CMD_AGED));
-
-	DP_PEER_PER_PKT_STATS_INCC_PKT(txrx_peer, tx.dropped.fw_rem, 1, length,
-			  (ts->status == HAL_TX_TQM_RR_REM_CMD_REM));
-
-	DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.dropped.fw_rem_notx, 1,
-		     (ts->status == HAL_TX_TQM_RR_REM_CMD_NOTX));
-
-	DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.dropped.fw_rem_tx, 1,
-		     (ts->status == HAL_TX_TQM_RR_REM_CMD_TX));
 
-	DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.dropped.fw_reason1, 1,
-		     (ts->status == HAL_TX_TQM_RR_FW_REASON1));
-
-	DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.dropped.fw_reason2, 1,
-		     (ts->status == HAL_TX_TQM_RR_FW_REASON2));
-
-	DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.dropped.fw_reason3, 1,
-		     (ts->status == HAL_TX_TQM_RR_FW_REASON3));
-	/*
-	 * tx_failed is ideally supposed to be updated from HTT ppdu completion
-	 * stats. But in IPQ807X/IPQ6018 chipsets owing to hw limitation there
-	 * are no completions for failed cases. Hence updating tx_failed from
-	 * data path. Please note that if tx_failed is fixed to be from ppdu,
-	 * then this has to be removed
-	 */
-	txrx_peer->tx_failed =
-			txrx_peer->stats.per_pkt_stats.tx.dropped.fw_rem.num +
-			txrx_peer->stats.per_pkt_stats.tx.dropped.fw_rem_notx +
-			txrx_peer->stats.per_pkt_stats.tx.dropped.fw_rem_tx +
-			txrx_peer->stats.per_pkt_stats.tx.dropped.age_out +
-			txrx_peer->stats.per_pkt_stats.tx.dropped.fw_reason1 +
-			txrx_peer->stats.per_pkt_stats.tx.dropped.fw_reason2 +
-			txrx_peer->stats.per_pkt_stats.tx.dropped.fw_reason3;
 	if (ts->status < CDP_MAX_TX_TQM_STATUS) {
 		tid_stats->tqm_status_cnt[ts->status]++;
 	}
 
-	if (ts->status != HAL_TX_TQM_RR_FRAME_ACKED) {
-		DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.failed_retry_count, 1,
-					   ts->transmit_cnt > DP_RETRY_COUNT);
-		dp_update_no_ack_stats(tx_desc->nbuf, txrx_peer);
-		return;
-	}
+	if (qdf_likely(ts->status == HAL_TX_TQM_RR_FRAME_ACKED)) {
+		DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.retry_count, 1,
+					   ts->transmit_cnt > 1);
+
+		DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.multiple_retry_count,
+					   1, ts->transmit_cnt > 2);
 
-	DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.retry_count, 1,
-				   ts->transmit_cnt > 1);
+		DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.ofdma, 1, ts->ofdma);
 
-	DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.multiple_retry_count, 1,
-				   ts->transmit_cnt > 2);
+		DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.amsdu_cnt, 1,
+					   ts->msdu_part_of_amsdu);
+		DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.non_amsdu_cnt, 1,
+					   !ts->msdu_part_of_amsdu);
 
-	DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.ofdma, 1, ts->ofdma);
+		txrx_peer->stats.per_pkt_stats.tx.last_tx_ts =
+							qdf_system_ticks();
 
-	DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.amsdu_cnt, 1,
-				   ts->msdu_part_of_amsdu);
-	DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.non_amsdu_cnt, 1,
-				   !ts->msdu_part_of_amsdu);
+		dp_tx_update_peer_extd_stats(ts, txrx_peer);
 
-	txrx_peer->stats.per_pkt_stats.tx.last_tx_ts = qdf_system_ticks();
+		return;
+	}
 
-	dp_tx_update_peer_extd_stats(ts, txrx_peer);
+	/*
+	 * tx_failed is ideally supposed to be updated from HTT ppdu
+	 * completion stats. But in IPQ807X/IPQ6018 chipsets owing to
+	 * hw limitation there are no completions for failed cases.
+	 * Hence updating tx_failed from data path. Please note that
+	 * if tx_failed is fixed to be from ppdu, then this has to be
+	 * removed
+	 */
+	DP_PEER_STATS_FLAT_INC(txrx_peer, tx_failed, 1);
+
+	DP_PEER_PER_PKT_STATS_INCC(txrx_peer, tx.failed_retry_count, 1,
+				   ts->transmit_cnt > DP_RETRY_COUNT);
+	dp_update_no_ack_stats(tx_desc->nbuf, txrx_peer);
+
+	if (ts->status == HAL_TX_TQM_RR_REM_CMD_AGED) {
+		DP_PEER_PER_PKT_STATS_INC(txrx_peer, tx.dropped.age_out, 1);
+	} else if (ts->status == HAL_TX_TQM_RR_REM_CMD_REM) {
+		DP_PEER_PER_PKT_STATS_INC_PKT(txrx_peer, tx.dropped.fw_rem, 1,
+					      length);
+	} else if (ts->status == HAL_TX_TQM_RR_REM_CMD_NOTX) {
+		DP_PEER_PER_PKT_STATS_INC(txrx_peer, tx.dropped.fw_rem_notx, 1);
+	} else if (ts->status == HAL_TX_TQM_RR_REM_CMD_TX) {
+		DP_PEER_PER_PKT_STATS_INC(txrx_peer, tx.dropped.fw_rem_tx, 1);
+	} else if (ts->status == HAL_TX_TQM_RR_FW_REASON1) {
+		DP_PEER_PER_PKT_STATS_INC(txrx_peer, tx.dropped.fw_reason1, 1);
+	} else if (ts->status == HAL_TX_TQM_RR_FW_REASON2) {
+		DP_PEER_PER_PKT_STATS_INC(txrx_peer, tx.dropped.fw_reason2, 1);
+	} else if (ts->status == HAL_TX_TQM_RR_FW_REASON3) {
+		DP_PEER_PER_PKT_STATS_INC(txrx_peer, tx.dropped.fw_reason3, 1);
+	} else if (ts->status == HAL_TX_TQM_RR_REM_CMD_DISABLE_QUEUE) {
+		DP_PEER_PER_PKT_STATS_INC(txrx_peer,
+					  tx.dropped.fw_rem_queue_disable, 1);
+	} else if (ts->status == HAL_TX_TQM_RR_REM_CMD_TILL_NONMATCHING) {
+		DP_PEER_PER_PKT_STATS_INC(txrx_peer,
+					  tx.dropped.fw_rem_no_match, 1);
+	} else if (ts->status == HAL_TX_TQM_RR_DROP_THRESHOLD) {
+		DP_PEER_PER_PKT_STATS_INC(txrx_peer,
+					  tx.dropped.drop_threshold, 1);
+	} else if (ts->status == HAL_TX_TQM_RR_LINK_DESC_UNAVAILABLE) {
+		DP_PEER_PER_PKT_STATS_INC(txrx_peer,
+					  tx.dropped.drop_link_desc_na, 1);
+	} else if (ts->status == HAL_TX_TQM_RR_DROP_OR_INVALID_MSDU) {
+		DP_PEER_PER_PKT_STATS_INC(txrx_peer,
+					  tx.dropped.invalid_drop, 1);
+	} else if (ts->status == HAL_TX_TQM_RR_MULTICAST_DROP) {
+		DP_PEER_PER_PKT_STATS_INC(txrx_peer,
+					  tx.dropped.mcast_vdev_drop, 1);
+	} else {
+		DP_PEER_PER_PKT_STATS_INC(txrx_peer, tx.dropped.invalid_rr, 1);
+	}
 }
 
 #ifdef QCA_LL_TX_FLOW_CONTROL_V2

+ 13 - 0
dp/wifi3.0/dp_types.h

@@ -3371,6 +3371,12 @@ typedef void *dp_txrx_ref_handle;
  * @fw_reason1: discarded by firmware reason 1
  * @fw_reason2: discarded by firmware reason 2
  * @fw_reason3: discarded by firmware reason  3
+ * @fw_rem_no_match: dropped due to fw no match command
+ * @drop_threshold: dropped due to HW threshold
+ * @drop_link_desc_na: dropped due resource not available in HW
+ * @invalid_drop: Invalid msdu drop
+ * @mcast_vdev_drop: MCAST drop configured for VDEV in HW
+ * @invalid_rr: Invalid TQM release reason
  * @failed_retry_count: packets failed due to retry above 802.11 retry limit
  * @retry_count: packets successfully send after one or more retry
  * @multiple_retry_count: packets successfully sent after more than one retry
@@ -3398,6 +3404,13 @@ struct dp_peer_per_pkt_tx_stats {
 		uint32_t fw_reason1;
 		uint32_t fw_reason2;
 		uint32_t fw_reason3;
+		uint32_t fw_rem_queue_disable;
+		uint32_t fw_rem_no_match;
+		uint32_t drop_threshold;
+		uint32_t drop_link_desc_na;
+		uint32_t invalid_drop;
+		uint32_t mcast_vdev_drop;
+		uint32_t invalid_rr;
 	} dropped;
 	uint32_t failed_retry_count;
 	uint32_t retry_count;

+ 12 - 0
hal/wifi3.0/hal_tx.h

@@ -290,6 +290,13 @@ enum hal_tx_encap_type {
  *				remove reason is fw_reason3
  * @HAL_TX_TQM_RR_REM_CMD_DISABLE_QUEUE : Remove command where fw indicated that
  *				remove reason is remove disable queue
+ * @HAL_TX_TQM_RR_REM_CMD_TILL_NONMATCHING: Remove command from fw to remove
+ *				all mpdu until 1st non-match
+ * @HAL_TX_TQM_RR_DROP_THRESHOLD: Dropped due to drop threshold criteria
+ * @HAL_TX_TQM_RR_LINK_DESC_UNAVAILABLE: Dropped due to link desc not available
+ * @HAL_TX_TQM_RR_DROP_OR_INVALID_MSDU: Dropped due drop bit set or null flow
+ * @HAL_TX_TQM_RR_MULTICAST_DROP: Dropped due mcast drop set for VDEV
+ *
  */
 enum hal_tx_tqm_release_reason {
 	HAL_TX_TQM_RR_FRAME_ACKED,
@@ -301,6 +308,11 @@ enum hal_tx_tqm_release_reason {
 	HAL_TX_TQM_RR_FW_REASON2,
 	HAL_TX_TQM_RR_FW_REASON3,
 	HAL_TX_TQM_RR_REM_CMD_DISABLE_QUEUE,
+	HAL_TX_TQM_RR_REM_CMD_TILL_NONMATCHING,
+	HAL_TX_TQM_RR_DROP_THRESHOLD,
+	HAL_TX_TQM_RR_LINK_DESC_UNAVAILABLE,
+	HAL_TX_TQM_RR_DROP_OR_INVALID_MSDU,
+	HAL_TX_TQM_RR_MULTICAST_DROP,
 };
 
 /* enum - Table IDs for 2 DSCP-TID mapping Tables that TCL H/W supports