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

qcacmn: Use monitor direct for smart monitor

Set monitor direct filter when smart monitor is
enabled. Deliver header from NAC if md bit is set
and smart mesh feature is used.

Change-Id: If1ef865e013c21bbb58bcb89a87856b12d6c7278
Crs-fixed: 2246660
sumedh baikady 6 жил өмнө
parent
commit
59a2d33a2d

+ 132 - 55
dp/wifi3.0/dp_htt.c

@@ -928,26 +928,48 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng,
 	}
 
 	if (htt_tlv_filter->enable_md) {
+			/* TYPE: MGMT */
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MD, MGMT, 0000,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_ASSOC_REQ) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MD, MGMT, 0001,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_ASSOC_RES) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MD, MGMT, 0010,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_REASSOC_REQ) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MD, MGMT, 0011,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_REASSOC_RES) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MD, MGMT, 0100,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_PROBE_REQ) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MD, MGMT, 0101,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_PROBE_RES) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MD, MGMT, 0110,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_TIM_ADVT) ? 1 : 0);
+		/* reserved */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
-				MGMT, 0000, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
-				MGMT, 0001, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
-				MGMT, 0010, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
-				MGMT, 0011, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
-				MGMT, 0100, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
-				MGMT, 0101, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
-				MGMT, 0110, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
-				MGMT, 0111, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
-				MGMT, 1000, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
-				MGMT, 1001, 1);
+			MGMT, 0111,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_RESERVED_7) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MD, MGMT, 1000,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_BEACON) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
+			MD, MGMT, 1001,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_ATIM) ? 1 : 0);
 	}
 
 	if (htt_tlv_filter->enable_mo) {
@@ -1029,16 +1051,27 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng,
 	}
 
 	if (htt_tlv_filter->enable_md) {
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD,
-				MGMT, 1010, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD,
-				MGMT, 1011, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD,
-				MGMT, 1100, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD,
-				MGMT, 1101, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MD,
-				MGMT, 1110, 1);
+			/* TYPE: MGMT */
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			MD, MGMT, 1010,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_DISASSOC) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			MD, MGMT, 1011,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_AUTH) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			MD, MGMT, 1100,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_DEAUTH) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			MD, MGMT, 1101,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_ACTION) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
+			MD, MGMT, 1110,
+			(htt_tlv_filter->md_mgmt_filter &
+			FILTER_MGMT_ACT_NO_ACK) ? 1 : 0);
 	}
 
 	if (htt_tlv_filter->enable_mo) {
@@ -1122,26 +1155,50 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng,
 	}
 
 	if (htt_tlv_filter->enable_md) {
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0000, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0001, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0010, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0011, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0100, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0101, 1);
-		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
-				CTRL, 0110, 1);
+		/* TYPE: CTRL */
+		/* reserved */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
-				CTRL, 0111, 1);
+			CTRL, 0000,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_RESERVED_1) ? 1 : 0);
+		/* reserved */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
-				CTRL, 1000, 1);
+			CTRL, 0001,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_RESERVED_2) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
-				CTRL, 1001, 1);
+			CTRL, 0010,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_TRIGGER) ? 1 : 0);
+		/* reserved */
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
+			CTRL, 0011,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_RESERVED_4) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
+			CTRL, 0100,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_BF_REP_POLL) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
+			CTRL, 0101,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_VHT_NDP) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
+			CTRL, 0110,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_FRAME_EXT) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
+			CTRL, 0111,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_CTRLWRAP) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
+			CTRL, 1000,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_BA_REQ) ? 1 : 0);
+		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
+			CTRL, 1001,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_BA) ? 1 : 0);
 	}
 
 	if (htt_tlv_filter->enable_mo) {
@@ -1236,24 +1293,44 @@ int htt_h2t_rx_ring_cfg(void *htt_soc, int pdev_id, void *hal_srng,
 	}
 
 	if (htt_tlv_filter->enable_md) {
+		/* TYPE: CTRL */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
-				CTRL, 1010, 1);
+			CTRL, 1010,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_PSPOLL) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
-				CTRL, 1011, 1);
+			CTRL, 1011,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_RTS) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
-				CTRL, 1100, 1);
+			CTRL, 1100,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_CTS) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
-				CTRL, 1101, 1);
+			CTRL, 1101,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_ACK) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
-				CTRL, 1110, 1);
+			CTRL, 1110,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_CFEND) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
-				CTRL, 1111, 1);
+			CTRL, 1111,
+			(htt_tlv_filter->md_ctrl_filter &
+			FILTER_CTRL_CFEND_CFACK) ? 1 : 0);
+		/* TYPE: DATA */
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
-				DATA, MCAST, 1);
+			DATA, MCAST,
+			(htt_tlv_filter->md_data_filter &
+			FILTER_DATA_MCAST) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
-				DATA, UCAST, 1);
+			DATA, UCAST,
+			(htt_tlv_filter->md_data_filter &
+			FILTER_DATA_UCAST) ? 1 : 0);
 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
-				DATA, NULL, 1);
+			DATA, NULL,
+			(htt_tlv_filter->md_data_filter &
+			FILTER_DATA_NULL) ? 1 : 0);
 	}
 
 	if (htt_tlv_filter->enable_mo) {

+ 3 - 0
dp/wifi3.0/dp_htt.h

@@ -132,6 +132,9 @@ struct htt_rx_ring_tlv_filter {
 		mo_ctrl_filter:16;
 	u_int32_t fp_data_filter:16,
 		mo_data_filter:16;
+	u_int16_t md_data_filter;
+	u_int16_t md_mgmt_filter;
+	u_int16_t md_ctrl_filter;
 };
 
 void *

+ 11 - 2
dp/wifi3.0/dp_main.c

@@ -4250,9 +4250,8 @@ static int dp_update_filter_neighbour_peers(struct cdp_vdev *vdev_handle,
 
 		/* first neighbour */
 		if (!pdev->neighbour_peers_added) {
-			if (!pdev->mcopy_mode && !pdev->enhanced_stats_en)
-				dp_ppdu_ring_cfg(pdev);
 			pdev->neighbour_peers_added = true;
+			dp_ppdu_ring_cfg(pdev);
 		}
 		return 1;
 
@@ -6468,6 +6467,11 @@ dp_ppdu_ring_cfg(struct dp_pdev *pdev)
 	htt_tlv_filter.ppdu_end_status_done = 1;
 	htt_tlv_filter.enable_fp = 1;
 	htt_tlv_filter.enable_md = 0;
+	if (pdev->neighbour_peers_added &&
+	    pdev->soc->hw_nac_monitor_support) {
+		htt_tlv_filter.enable_md = 1;
+		htt_tlv_filter.packet_header = 1;
+	}
 	if (pdev->mcopy_mode) {
 		htt_tlv_filter.packet_header = 1;
 		htt_tlv_filter.enable_mo = 1;
@@ -6478,6 +6482,9 @@ dp_ppdu_ring_cfg(struct dp_pdev *pdev)
 	htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL;
 	htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL;
 	htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL;
+	if (pdev->neighbour_peers_added &&
+	    pdev->soc->hw_nac_monitor_support)
+		htt_tlv_filter.md_data_filter = FILTER_DATA_ALL;
 
 	for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
 		int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id,
@@ -8124,11 +8131,13 @@ void *dp_soc_attach_wifi3(void *ctrl_psoc, void *hif_handle,
 		wlan_cfg_set_reo_dst_ring_size(soc->wlan_cfg_ctx,
 					       REO_DST_RING_SIZE_QCA8074);
 		wlan_cfg_set_raw_mode_war(soc->wlan_cfg_ctx, true);
+		soc->hw_nac_monitor_support = 1;
 		break;
 	case TARGET_TYPE_QCA8074V2:
 		wlan_cfg_set_reo_dst_ring_size(soc->wlan_cfg_ctx,
 					       REO_DST_RING_SIZE_QCA8074);
 		wlan_cfg_set_raw_mode_war(soc->wlan_cfg_ctx, false);
+		soc->hw_nac_monitor_support = 1;
 		break;
 	default:
 		qdf_print("%s: Unknown tgt type %d\n", __func__, target_type);

+ 62 - 3
dp/wifi3.0/dp_rx_mon_status.c

@@ -296,6 +296,57 @@ dp_rx_handle_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev,
 }
 #endif
 
+/**
+ * dp_rx_handle_smart_mesh_mode() - Deliver header for smart mesh
+ * @soc: Datapath SOC handle
+ * @pdev: Datapath PDEV handle
+ * @ppdu_info: Structure for rx ppdu info
+ * @nbuf: Qdf nbuf abstraction for linux skb
+ *
+ * Return: 0 on success, 1 on failure
+ */
+static inline int
+dp_rx_handle_smart_mesh_mode(struct dp_soc *soc, struct dp_pdev *pdev,
+			      struct hal_rx_ppdu_info *ppdu_info,
+			      qdf_nbuf_t nbuf)
+{
+	uint8_t size = 0;
+
+	if (!pdev->monitor_vdev) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "[%s]:[%d] Monitor vdev is NULL !!",
+			  __func__, __LINE__);
+		return 1;
+	}
+	if (ppdu_info->msdu_info.first_msdu_payload == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "[%s]:[%d] First msdu payload not present",
+			  __func__, __LINE__);
+		return 1;
+	}
+
+	/* Include 2 bytes of reserved space appended to the msdu payload */
+	size = (ppdu_info->msdu_info.first_msdu_payload -
+		qdf_nbuf_data(nbuf)) + 2;
+	ppdu_info->msdu_info.first_msdu_payload = NULL;
+
+	if (qdf_nbuf_pull_head(nbuf, size) == NULL) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "[%s]:[%d] No header present",
+			__func__, __LINE__);
+		return 1;
+	}
+
+	/* only retain RX MSDU payload in the skb */
+	qdf_nbuf_trim_tail(nbuf, qdf_nbuf_len(nbuf) -
+			   ppdu_info->msdu_info.payload_len);
+	qdf_nbuf_update_radiotap(&(pdev->ppdu_info.rx_status),
+				 nbuf, sizeof(struct rx_pkt_tlvs));
+	pdev->monitor_vdev->osif_rx_mon(pdev->monitor_vdev->osif_vdev,
+					nbuf, NULL);
+
+	return 0;
+}
 
 /**
 * dp_rx_handle_ppdu_stats() - Allocate and deliver ppdu stats to cdp layer
@@ -400,6 +451,7 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id,
 	uint32_t tlv_status = HAL_TLV_STATUS_BUF_DONE;
 	QDF_STATUS m_copy_status = QDF_STATUS_SUCCESS;
 	struct cdp_pdev_mon_stats *rx_mon_stats;
+	int smart_mesh_status;
 
 	ppdu_info = &pdev->ppdu_info;
 	rx_mon_stats = &pdev->rx_mon_stats;
@@ -437,21 +489,28 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id,
 			} while (tlv_status == HAL_TLV_STATUS_PPDU_NOT_DONE);
 		}
 
+		if (ppdu_info->rx_status.monitor_direct_used && pdev->neighbour_peers_added
+		    && pdev->monitor_vdev) {
+			smart_mesh_status = dp_rx_handle_smart_mesh_mode(soc,
+						pdev, ppdu_info, status_nbuf);
+			if (smart_mesh_status)
+				qdf_nbuf_free(status_nbuf);
+		}
 		if (pdev->mcopy_mode) {
 			m_copy_status = dp_rx_handle_mcopy_mode(soc,
 						pdev, ppdu_info, status_nbuf);
 			if (m_copy_status == QDF_STATUS_SUCCESS)
 				qdf_nbuf_free(status_nbuf);
-		} else {
-			qdf_nbuf_free(status_nbuf);
 		}
+		if (!pdev->neighbour_peers_added && !pdev->mcopy_mode)
+			qdf_nbuf_free(status_nbuf);
 
 		if (tlv_status == HAL_TLV_STATUS_PPDU_NON_STD_DONE) {
 			dp_rx_mon_deliver_non_std(soc, mac_id);
 		} else if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) {
 			rx_mon_stats->status_ppdu_done++;
 			if (pdev->enhanced_stats_en ||
-					pdev->mcopy_mode)
+			    pdev->mcopy_mode || pdev->neighbour_peers_added)
 				dp_rx_handle_ppdu_stats(soc, pdev, ppdu_info);
 
 			pdev->mon_ppdu_status = DP_PPDU_STATUS_DONE;

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

@@ -915,6 +915,9 @@ struct dp_soc {
 #endif
 	/* Device ID coming from Bus sub-system */
 	uint32_t device_id;
+
+	/* Smart monitor capability for HKv2 */
+	uint8_t hw_nac_monitor_support;
 };
 
 #ifdef IPA_OFFLOAD
@@ -1128,6 +1131,7 @@ struct dp_pdev {
 	uint16_t mo_mgmt_filter;
 	uint16_t mo_ctrl_filter;
 	uint16_t mo_data_filter;
+	uint16_t md_data_filter;
 
 	qdf_atomic_t num_tx_outstanding;
 

+ 6 - 0
hal/wifi3.0/hal_generic_api.h

@@ -997,6 +997,7 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo,
 					RX_MPDU_INFO_RX_MPDU_INFO_DETAILS);
 		uint32_t ppdu_id = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0,
 					      PHY_PPDU_ID);
+		uint8_t filter_category = 0;
 
 		ppdu_info->nac_info.fc_valid =
 			HAL_RX_GET(rx_mpdu_start,
@@ -1033,6 +1034,11 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo,
 				HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_13,
 				MPDU_LENGTH);
 		}
+
+		filter_category = HAL_RX_GET(rx_mpdu_start, RX_MPDU_INFO_0,
+							RXPCU_MPDU_FILTER_IN_CATEGORY);
+		if (filter_category == 1)
+			ppdu_info->rx_status.monitor_direct_used = 1;
 		break;
 	}
 	case 0:

+ 1 - 0
qdf/inc/qdf_nbuf.h

@@ -289,6 +289,7 @@ struct mon_rx_status {
 	uint32_t ppdu_id;
 	uint32_t device_id;
 	int16_t chan_noise_floor;
+	uint8_t monitor_direct_used;
 };
 
 /**