Browse Source

qcacmn: Add CBF support for pktlog

Fix issue on enabling packet log.
Fix issue on logging CBF pkt in AP/STA mode.
Fix issue on setting data length 4 bytes aligned in pktlog header
, htt stats indication message header and Rx management TLV header.
Add CBF support for pktlog WMI enable command for firmware to enable
CBF receive.

Change-Id: Ib0067f32d7414be96503c4c67846c1312a59586e
Kai Chen 4 years ago
parent
commit
2667f112d8

+ 15 - 11
dp/wifi3.0/dp_htt.c

@@ -472,7 +472,7 @@ QDF_STATUS dp_rx_populate_cbf_hdr(struct dp_soc *soc,
 				  qdf_nbuf_t mpdu,
 				  uint32_t msdu_timestamp)
 {
-	uint32_t data_size, hdr_size, ppdu_id;
+	uint32_t data_size, hdr_size, ppdu_id, align4byte;
 	struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
 	uint32_t *msg_word;
 
@@ -482,7 +482,7 @@ QDF_STATUS dp_rx_populate_cbf_hdr(struct dp_soc *soc,
 	ppdu_id = pdev->ppdu_info.com_info.ppdu_id;
 
 	hdr_size = HTT_T2H_PPDU_STATS_IND_HDR_SIZE
-		+ sizeof(htt_ppdu_stats_tx_mgmtctrl_payload_tlv);
+		+ qdf_offsetof(htt_ppdu_stats_rx_mgmtctrl_payload_tlv, payload);
 
 	data_size = qdf_nbuf_len(mpdu);
 
@@ -495,27 +495,31 @@ QDF_STATUS dp_rx_populate_cbf_hdr(struct dp_soc *soc,
 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_T2H_MSG_TYPE_PPDU_STATS_IND);
 	HTT_T2H_PPDU_STATS_MAC_ID_SET(*msg_word, mac_id);
 	HTT_T2H_PPDU_STATS_PDEV_ID_SET(*msg_word, pdev->pdev_id);
-	HTT_T2H_PPDU_STATS_PAYLOAD_SIZE_SET(*msg_word, data_size +
-		qdf_offsetof(htt_ppdu_stats_tx_mgmtctrl_payload_tlv, payload));
+	align4byte = ((data_size +
+		qdf_offsetof(htt_ppdu_stats_rx_mgmtctrl_payload_tlv, payload)
+		+ 3) >> 2) << 2;
+	HTT_T2H_PPDU_STATS_PAYLOAD_SIZE_SET(*msg_word, align4byte);
 	msg_word++;
 	HTT_T2H_PPDU_STATS_PPDU_ID_SET(*msg_word, ppdu_id);
 	msg_word++;
 
 	*msg_word = msdu_timestamp;
 	msg_word++;
+	/* Skip reserved field */
+	msg_word++;
 	/*
 	 * Populate MGMT_CTRL Payload TLV first
 	 */
 	HTT_STATS_TLV_TAG_SET(*msg_word,
-			      HTT_PPDU_STATS_TX_MGMTCTRL_PAYLOAD_TLV);
-	HTT_STATS_TLV_LENGTH_SET(*msg_word,
-				 data_size - sizeof(htt_tlv_hdr_t) +
-				 qdf_offsetof(
-				 htt_ppdu_stats_tx_mgmtctrl_payload_tlv,
-				 payload));
+			      HTT_PPDU_STATS_RX_MGMTCTRL_PAYLOAD_TLV);
+
+	align4byte = ((data_size - sizeof(htt_tlv_hdr_t) +
+		qdf_offsetof(htt_ppdu_stats_rx_mgmtctrl_payload_tlv, payload)
+		+ 3) >> 2) << 2;
+	HTT_STATS_TLV_LENGTH_SET(*msg_word, align4byte);
 	msg_word++;
 
-	HTT_PPDU_STATS_TX_MGMTCTRL_TLV_FRAME_LENGTH_SET(
+	HTT_PPDU_STATS_RX_MGMTCTRL_TLV_FRAME_LENGTH_SET(
 		*msg_word, data_size);
 	msg_word++;
 

+ 7 - 1
dp/wifi3.0/dp_main.c

@@ -13054,12 +13054,13 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 			}
 			if (!pdev->rx_pktlog_cbf) {
 				pdev->rx_pktlog_cbf = true;
-
+				pdev->monitor_configured = true;
 				dp_vdev_set_monitor_mode_buf_rings(pdev);
 				/*
 				 * Set the packet log lite mode filter.
 				 */
 				qdf_info("Non monitor mode: Enable destination ring");
+
 				dp_mon_filter_setup_rx_pkt_log_cbf(pdev);
 				if (dp_mon_filter_update(pdev) !=
 				    QDF_STATUS_SUCCESS) {
@@ -13067,6 +13068,7 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 					dp_mon_filter_reset_rx_pktlog_cbf(pdev);
 					pdev->rx_pktlog_mode =
 						DP_RX_PKTLOG_DISABLED;
+					pdev->monitor_configured = false;
 					return 0;
 				}
 
@@ -13137,6 +13139,10 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 			}
 
 			break;
+		case WDI_EVENT_RX_CBF:
+			pdev->rx_pktlog_cbf = false;
+			break;
+
 		default:
 			/* Nothing needs to be done for other pktlog types */
 			break;

+ 7 - 2
dp/wifi3.0/dp_mon_filter.c

@@ -398,13 +398,13 @@ static QDF_STATUS dp_mon_filter_check_co_exist(struct dp_pdev *pdev)
 	 * the enable modes.
 	 */
 	if ((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) &&
-	    (pdev->monitor_vdev || pdev->monitor_configured)) {
+	     !pdev->rx_pktlog_cbf &&
+	     (pdev->monitor_vdev || pdev->monitor_configured)) {
 		dp_mon_filter_err("%pK: Rx pktlog full/lite can't exist with modes\n"
 				  "Monitor Mode:%d", pdev->soc,
 				  pdev->monitor_configured);
 		return QDF_STATUS_E_FAILURE;
 	}
-
 	return QDF_STATUS_SUCCESS;
 }
 #else
@@ -1055,6 +1055,11 @@ void dp_mon_filter_setup_rx_pkt_log_cbf(struct dp_pdev *pdev)
 	dp_mon_filter_show_filter(pdev, mode, &filter);
 	pdev->filter[mode][srng_type] = filter;
 
+	/* Clear the filter as the same filter will be used to set the
+	 * monitor status ring
+	 */
+	qdf_mem_zero(&(filter), sizeof(struct dp_mon_filter));
+
 	filter.valid = true;
 	dp_mon_filter_set_cbf_cmn(pdev, &filter);
 	dp_mon_filter_show_filter(pdev, mode, &filter);

+ 10 - 4
dp/wifi3.0/dp_rx_mon_dest.c

@@ -210,7 +210,9 @@ dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
 		if (qdf_unlikely((rxdma_err == HAL_RXDMA_ERR_FLUSH_REQUEST) ||
 		   (rxdma_err == HAL_RXDMA_ERR_MPDU_LENGTH) ||
 		   (rxdma_err == HAL_RXDMA_ERR_OVERFLOW) ||
-		   (rxdma_err == HAL_RXDMA_ERR_FCS && dp_pdev->mcopy_mode))) {
+		   (rxdma_err == HAL_RXDMA_ERR_FCS && dp_pdev->mcopy_mode) ||
+		   (rxdma_err == HAL_RXDMA_ERR_FCS &&
+		    dp_pdev->rx_pktlog_cbf))) {
 			drop_mpdu = true;
 			dp_pdev->rx_mon_stats.dest_mpdu_drop++;
 		}
@@ -1440,7 +1442,11 @@ static QDF_STATUS dp_rx_mon_process_dest_pktlog(struct dp_soc *soc,
 		return QDF_STATUS_E_INVAL;
 
 	if (pdev->rx_pktlog_cbf) {
-		data = qdf_nbuf_data(mpdu);
+		if (qdf_nbuf_get_nr_frags(mpdu))
+			data = qdf_nbuf_get_frag_addr(mpdu, 0);
+		else
+			data = qdf_nbuf_data(mpdu);
+
 		rx_tlv = data - SIZE_OF_MONITOR_TLV;
 
 		/* CBF logging required, doesn't matter if it is a full mode
@@ -1455,7 +1461,6 @@ static QDF_STATUS dp_rx_mon_process_dest_pktlog(struct dp_soc *soc,
 			msdu_start_tlv->rx_msdu_start.ppdu_start_timestamp;
 
 		wh = (struct ieee80211_frame *)data;
-
 		type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 		subtype = (wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
 		if (type == IEEE80211_FC0_TYPE_MGT &&
@@ -1485,7 +1490,8 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id,
 	qdf_nbuf_t mon_skb, skb_next;
 	qdf_nbuf_t mon_mpdu = NULL;
 
-	if (!pdev || (!pdev->monitor_vdev && !pdev->mcopy_mode))
+	if (!pdev || (!pdev->monitor_vdev && !pdev->mcopy_mode &&
+		      !pdev->rx_pktlog_cbf))
 		goto mon_deliver_fail;
 
 	/* restitch mon MPDU for delivery via monitor interface */

+ 2 - 1
dp/wifi3.0/dp_wdi_event.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -190,6 +190,7 @@ dp_wdi_event_sub(
 			"Invalid event in %s", __func__);
 		return -EINVAL;
 	}
+
 	dp_set_pktlog_wifi3(txrx_pdev, event, true);
 	event_index = event - WDI_EVENT_BASE;
 	wdi_sub = txrx_pdev->wdi_event_list[event_index];

+ 3 - 0
wmi/inc/wmi_unified_param.h

@@ -6081,6 +6081,7 @@ enum {
 	WMI_HOST_PKTLOG_EVENT_STEERING_BIT,
 	WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT,
 	WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT,
+	WMI_HOST_PKTLOG_EVENT_CBF_BIT,
 };
 
 typedef enum {
@@ -6105,6 +6106,8 @@ typedef enum {
 	/* To support PHY logging */
 	WMI_HOST_PKTLOG_EVENT_PHY_LOGGING =
 		BIT(WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT),
+	WMI_HOST_PKTLOG_EVENT_CBF =
+		BIT(WMI_HOST_PKTLOG_EVENT_CBF_BIT),
 } WMI_HOST_PKTLOG_EVENT;
 
 /**

+ 5 - 0
wmi/src/wmi_unified_tlv.c

@@ -521,6 +521,10 @@ static const uint32_t vdev_param_tlv[] = {
 };
 #endif
 
+#ifndef WMI_PKTLOG_EVENT_CBF
+#define WMI_PKTLOG_EVENT_CBF 0x100
+#endif
+
 /**
  * Populate the pktlog event tlv array, where
  * the values are the FW WMI events, which host
@@ -539,6 +543,7 @@ static const uint32_t pktlog_event_tlv[] =  {
 	[WMI_HOST_PKTLOG_EVENT_STEERING_BIT] = 0,
 	[WMI_HOST_PKTLOG_EVENT_TX_DATA_CAPTURE_BIT] = 0,
 	[WMI_HOST_PKTLOG_EVENT_PHY_LOGGING_BIT] = WMI_PKTLOG_EVENT_PHY,
+	[WMI_HOST_PKTLOG_EVENT_CBF_BIT] = WMI_PKTLOG_EVENT_CBF,
 };
 
 /**