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

qca-wifi: Free ppdu when wbm completion comes out of order

In TX packet capture, we expect wbm to comes in order
but sometimes we see it comes out of order. During that case we
free msdu and mpdu that we recreate for ppdu.

Change-Id: Id8e6082ade4e3d24937af490014c0fe4152906d8
nobelj 6 жил өмнө
parent
commit
68866584a3

+ 39 - 9
dp/wifi3.0/dp_tx_capture.c

@@ -283,8 +283,7 @@ QDF_STATUS dp_tx_add_to_comp_queue(struct dp_soc *soc,
 	int ret = QDF_STATUS_E_FAILURE;
 	int ret = QDF_STATUS_E_FAILURE;
 
 
 	if (desc->pdev->tx_capture_enabled == 1 &&
 	if (desc->pdev->tx_capture_enabled == 1 &&
-	    (ts->status == HAL_TX_TQM_RR_REM_CMD_TX ||
-	    ts->status == HAL_TX_TQM_RR_FRAME_ACKED)) {
+	    ts->status == HAL_TX_TQM_RR_FRAME_ACKED) {
 		ret = dp_update_msdu_to_list(soc, desc->pdev,
 		ret = dp_update_msdu_to_list(soc, desc->pdev,
 					     peer, ts, desc->nbuf);
 					     peer, ts, desc->nbuf);
 	}
 	}
@@ -681,7 +680,7 @@ dp_tx_mon_restitch_mpdu_from_msdus(struct dp_pdev *pdev,
 				QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE,
 				QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE,
 					  QDF_TRACE_LEVEL_FATAL,
 					  QDF_TRACE_LEVEL_FATAL,
 					  "MPDU head allocation failed !!!");
 					  "MPDU head allocation failed !!!");
-				QDF_BUG(0);
+				goto free_ppdu_desc_mpdu_q;
 			}
 			}
 
 
 			dp_tx_update_80211_hdr(pdev, peer,
 			dp_tx_update_80211_hdr(pdev, peer,
@@ -699,8 +698,11 @@ dp_tx_mon_restitch_mpdu_from_msdus(struct dp_pdev *pdev,
 			 * handle this case
 			 * handle this case
 			 */
 			 */
 			qdf_nbuf_free(curr_nbuf);
 			qdf_nbuf_free(curr_nbuf);
-			/* assert here if no last msdu found */
-			QDF_BUG(0);
+			/*
+			 * No last msdu found because WBM comes out
+			 * of order, free the pkt
+			 */
+			goto free_ppdu_desc_mpdu_q;
 		} else if (!first_msdu && first_msdu_not_seen) {
 		} else if (!first_msdu && first_msdu_not_seen) {
 			QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE,
 			QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE,
 				  QDF_TRACE_LEVEL_FATAL,
 				  QDF_TRACE_LEVEL_FATAL,
@@ -710,8 +712,11 @@ dp_tx_mon_restitch_mpdu_from_msdus(struct dp_pdev *pdev,
 			 * handle this case
 			 * handle this case
 			 */
 			 */
 			qdf_nbuf_free(curr_nbuf);
 			qdf_nbuf_free(curr_nbuf);
-			/* assert here if no first msdu found */
-			QDF_BUG(0);
+			/*
+			 * no first msdu found beacuse WBM comes out
+			 * of order, free the pkt
+			 */
+			goto free_ppdu_desc_mpdu_q;
 		} else {
 		} else {
 			/* update current buffer to previous buffer next */
 			/* update current buffer to previous buffer next */
 			prev_nbuf->next = curr_nbuf;
 			prev_nbuf->next = curr_nbuf;
@@ -733,6 +738,7 @@ dp_tx_mon_restitch_mpdu_from_msdus(struct dp_pdev *pdev,
 			/* add mpdu to mpdu queue */
 			/* add mpdu to mpdu queue */
 			qdf_nbuf_queue_add(mpdu, mpdu_nbuf);
 			qdf_nbuf_queue_add(mpdu, mpdu_nbuf);
 			first_nbuf = NULL;
 			first_nbuf = NULL;
+			mpdu_nbuf = NULL;
 
 
 			/* next msdu will start with first msdu */
 			/* next msdu will start with first msdu */
 			first_msdu_not_seen = 1;
 			first_msdu_not_seen = 1;
@@ -758,6 +764,23 @@ check_for_next_msdu:
 	}
 	}
 
 
 	return 0;
 	return 0;
+
+free_ppdu_desc_mpdu_q:
+	/* free already chained msdu pkt */
+	while (first_nbuf) {
+		curr_nbuf = first_nbuf;
+		first_nbuf = first_nbuf->next;
+		qdf_nbuf_free(curr_nbuf);
+	}
+
+	/* free allocated mpdu hdr */
+	if (mpdu_nbuf)
+		qdf_nbuf_free(mpdu_nbuf);
+	/* free queued remaining msdu pkt per ppdu */
+	qdf_nbuf_queue_free(head_msdu);
+	/* free queued mpdu per ppdu */
+	qdf_nbuf_queue_free(mpdu);
+	return 0;
 }
 }
 
 
 /**
 /**
@@ -1387,7 +1410,7 @@ dequeue_msdu_again:
 
 
 				if (!ret && (++retries < 3)) {
 				if (!ret && (++retries < 3)) {
 					/* wait for wbm to complete */
 					/* wait for wbm to complete */
-					qdf_sleep(100);
+					qdf_sleep(20);
 					goto dequeue_msdu_again;
 					goto dequeue_msdu_again;
 				}
 				}
 
 
@@ -1417,8 +1440,15 @@ dequeue_msdu_again:
 				 */
 				 */
 				qdf_nbuf_queue_free(&head_msdu);
 				qdf_nbuf_queue_free(&head_msdu);
 
 
-				nbuf_ppdu_desc_list[ppdu_desc_cnt++] = nbuf;
 				qlen = qdf_nbuf_queue_len(&ppdu_desc->mpdu_q);
 				qlen = qdf_nbuf_queue_len(&ppdu_desc->mpdu_q);
+
+				if (!qlen) {
+					qdf_nbuf_free(nbuf);
+					dp_peer_unref_del_find_by_id(peer);
+					continue;
+				}
+				nbuf_ppdu_desc_list[ppdu_desc_cnt++] = nbuf;
+
 				/* print ppdu_desc info for debugging purpose */
 				/* print ppdu_desc info for debugging purpose */
 				QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE,
 				QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE,
 					  QDF_TRACE_LEVEL_INFO,
 					  QDF_TRACE_LEVEL_INFO,