Bläddra i källkod

qcacmn: Add full monitor mode changes

	Add following changes:
	a. Add CDP API to config full monitor mode
	b. HTT configuration changes
	c. Init/Deinit changes for full monitor mode resources

CRs-Fixed: 2632442
Change-Id: I06db5194031b3ea0f0c1e5deda20df4bc0faa0b9
Amir Patel 5 år sedan
förälder
incheckning
925a7d389c

+ 27 - 0
dp/inc/cdp_txrx_cmn.h

@@ -2545,4 +2545,31 @@ cdp_vdev_get_peer_mac_list(ol_txrx_soc_handle soc,
 			(soc, vdev_id, newmac, mac_cnt);
 }
 
+/*
+ * cdp_soc_config_full_mon_mode () - Configure Full monitor mode
+ *
+ *@soc: dp soc handle
+ *@val: value to be configured val should be 0 or 1
+ *
+ * This API is used to enable/disable support for Full monitor mode feature
+ *
+ * Return: QDF_STATUS_SUCCESS if value set successfully
+ *         QDF_STATUS_E_INVAL false if error
+ */
+static inline QDF_STATUS
+cdp_soc_config_full_mon_mode(ol_txrx_soc_handle soc, uint8_t val)
+{
+	if (!soc || !soc->ops) {
+		QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: Invalid Instance", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (!soc->ops->mon_ops ||
+	    !soc->ops->mon_ops->config_full_mon_mode)
+		return QDF_STATUS_E_INVAL;
+
+	return soc->ops->mon_ops->config_full_mon_mode(soc, val);
+}
+
 #endif /* _CDP_TXRX_CMN_H_ */

+ 8 - 1
dp/inc/cdp_txrx_mon_struct.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020 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
@@ -219,6 +219,10 @@ enum {
  * @dup_mon_linkdesc_cnt: duplicate link descriptor indications from HW
  * @dup_mon_buf_cnt: duplicate buffer indications from HW
  * @tlv_tag_status_err: status not correct in the tlv tag
+ * @mon_rx_bufs_replenished_dest: Rx buffers replenish count
+ * @mon_rx_bufs_reaped_dest: Rx buffer reap count
+ * @ppdu_id_mismatch: counter to track ppdu id mismatch in
+ *  mointor status and monitor destination ring
  */
 struct cdp_pdev_mon_stats {
 #ifndef REMOVE_MON_DBG_STATS
@@ -240,5 +244,8 @@ struct cdp_pdev_mon_stats {
 	uint32_t ppdu_id_hist_idx;
 	uint32_t mon_rx_dest_stuck;
 	uint32_t tlv_tag_status_err;
+	uint32_t mon_rx_bufs_replenished_dest;
+	uint32_t mon_rx_bufs_reaped_dest;
+	uint32_t ppdu_id_mismatch;
 };
 #endif

+ 4 - 0
dp/inc/cdp_txrx_ops.h

@@ -761,6 +761,10 @@ struct cdp_mon_ops {
 	QDF_STATUS (*txrx_set_advance_monitor_filter)
 		(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 		 struct cdp_monitor_filter *filter_val);
+
+	/* Configure full monitor mode */
+	QDF_STATUS
+		(*config_full_mon_mode)(struct cdp_soc_t *soc, uint8_t val);
 };
 
 #ifdef WLAN_FEATURE_PKT_CAPTURE

+ 105 - 0
dp/wifi3.0/dp_htt.c

@@ -1032,6 +1032,111 @@ fail0:
 	return QDF_STATUS_E_FAILURE;
 }
 
+#ifdef QCA_SUPPORT_FULL_MON
+/**
+ * htt_h2t_full_mon_cfg() - Send full monitor configuarion msg to FW
+ *
+ * @htt_soc: HTT Soc handle
+ * @pdev_id: Radio id
+ * @dp_full_mon_config: enabled/disable configuration
+ *
+ * Return: Success when HTT message is sent, error on failure
+ */
+int htt_h2t_full_mon_cfg(struct htt_soc *htt_soc,
+			 uint8_t pdev_id,
+			 enum dp_full_mon_config config)
+{
+	struct htt_soc *soc = (struct htt_soc *)htt_soc;
+	struct dp_htt_htc_pkt *pkt;
+	qdf_nbuf_t htt_msg;
+	uint32_t *msg_word;
+	uint8_t *htt_logger_bufp;
+
+	htt_msg = qdf_nbuf_alloc(soc->osdev,
+				 HTT_MSG_BUF_SIZE(
+				 HTT_RX_FULL_MONITOR_MODE_SETUP_SZ),
+				 /* reserve room for the HTC header */
+				 HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING,
+				 4,
+				 TRUE);
+	if (!htt_msg)
+		return QDF_STATUS_E_FAILURE;
+
+	/*
+	 * Set the length of the message.
+	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
+	 * separately during the below call to qdf_nbuf_push_head.
+	 * The contribution from the HTC header is added separately inside HTC.
+	 */
+	if (!qdf_nbuf_put_tail(htt_msg, HTT_RX_RING_SELECTION_CFG_SZ)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			  "%s: Failed to expand head for RX Ring Cfg msg",
+			  __func__);
+		goto fail1;
+	}
+
+	msg_word = (uint32_t *)qdf_nbuf_data(htt_msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(htt_msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	/* word 0 */
+	*msg_word = 0;
+	htt_logger_bufp = (uint8_t *)msg_word;
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE);
+	HTT_RX_FULL_MONITOR_MODE_OPERATION_PDEV_ID_SET(
+			*msg_word, DP_SW2HW_MACID(pdev_id));
+
+	msg_word++;
+	*msg_word = 0;
+	/* word 1 */
+	if (config == DP_FULL_MON_ENABLE) {
+		HTT_RX_FULL_MONITOR_MODE_ENABLE_SET(*msg_word, true);
+		HTT_RX_FULL_MONITOR_MODE_ZERO_MPDU_SET(*msg_word, true);
+		HTT_RX_FULL_MONITOR_MODE_NON_ZERO_MPDU_SET(*msg_word, true);
+		HTT_RX_FULL_MONITOR_MODE_RELEASE_RINGS_SET(*msg_word, 0x2);
+	} else if (config == DP_FULL_MON_DISABLE) {
+		HTT_RX_FULL_MONITOR_MODE_ENABLE_SET(*msg_word, false);
+		HTT_RX_FULL_MONITOR_MODE_ZERO_MPDU_SET(*msg_word, false);
+		HTT_RX_FULL_MONITOR_MODE_NON_ZERO_MPDU_SET(*msg_word, false);
+		HTT_RX_FULL_MONITOR_MODE_RELEASE_RINGS_SET(*msg_word, 0x2);
+	}
+
+	pkt = htt_htc_pkt_alloc(soc);
+	if (!pkt) {
+		qdf_err("HTC packet allocation failed");
+		goto fail1;
+	}
+
+	pkt->soc_ctxt = NULL; /* not used during send-done callback */
+
+	SET_HTC_PACKET_INFO_TX(
+		&pkt->htc_pkt,
+		dp_htt_h2t_send_complete_free_netbuf,
+		qdf_nbuf_data(htt_msg),
+		qdf_nbuf_len(htt_msg),
+		soc->htc_endpoint,
+		1); /* tag for no FW response msg */
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, htt_msg);
+	qdf_info("config: %d", config);
+	DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_SRING_SETUP,
+			    htt_logger_bufp);
+	return QDF_STATUS_SUCCESS;
+fail1:
+	qdf_nbuf_free(htt_msg);
+	return QDF_STATUS_E_FAILURE;
+}
+#else
+int htt_h2t_full_mon_cfg(struct htt_soc *htt_soc,
+			 uint8_t pdev_id,
+			 enum dp_full_mon_config config)
+{
+	return 0;
+}
+
+#endif
+
 /*
  * htt_h2t_rx_ring_cfg() - Send SRNG packet and TLV filter
  * config message to target

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

@@ -129,6 +129,17 @@ int htt_wbm_event_record(struct htt_logger *h, uint8_t tx_status,
 #define HTT_GET_STATS_CMN_INDEX(index) \
 	HTT_PPDU_STATS_COMMON_TLV_##index##_OFFSET
 
+/**
+ * enum dp_full_mon_config - enum to enable/disable full monitor mode
+ *
+ * @DP_FULL_MON_DISABLE: Disable full monitor mode
+ * @DP_FULL_MON_ENABLE: Enable full monitor mode
+ */
+enum dp_full_mon_config {
+	DP_FULL_MON_DISABLE,
+	DP_FULL_MON_ENABLE,
+};
+
 struct dp_htt_htc_pkt {
 	void *soc_ctxt;
 	qdf_dma_addr_t nbuf_paddr;
@@ -447,4 +458,17 @@ dp_htt_rx_flow_fst_setup(struct dp_pdev *pdev,
 QDF_STATUS
 dp_htt_rx_flow_fse_operation(struct dp_pdev *pdev,
 			     struct dp_htt_rx_flow_fst_operation *op_info);
+
+/**
+ * htt_h2t_full_mon_cfg() - Send full monitor configuarion msg to FW
+ *
+ * @htt_soc: HTT Soc handle
+ * @pdev_id: Radio id
+ * @dp_full_mon_config: enabled/disable configuration
+ *
+ * Return: Success when HTT message is sent, error on failure
+ */
+int htt_h2t_full_mon_cfg(struct htt_soc *htt_soc,
+			 uint8_t pdev_id,
+			 enum dp_full_mon_config);
 #endif /* _DP_HTT_H_ */

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

@@ -2097,4 +2097,16 @@ void dp_set_max_page_size(struct qdf_mem_multi_page_t *pages,
  * Return: None
  */
 void dp_rx_skip_tlvs(qdf_nbuf_t nbuf, uint32_t l3_padding);
+
+/**
+ * dp_soc_is_full_mon_enable () - Return if full monitor mode is enabled
+ * @soc: DP soc handle
+ *
+ * Return: Full monitor mode status
+ */
+static inline bool dp_soc_is_full_mon_enable(struct dp_pdev *pdev)
+{
+	return (pdev->soc->full_mon_mode && pdev->monitor_configured) ?
+			true : false;
+}
 #endif /* #ifndef _DP_INTERNAL_H_ */

+ 51 - 0
dp/wifi3.0/dp_main.c

@@ -5109,6 +5109,32 @@ dp_soc_attach_target_wifi3(struct cdp_soc_t *cdp_soc)
 	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef QCA_SUPPORT_FULL_MON
+static inline QDF_STATUS
+dp_soc_config_full_mon_mode(struct dp_pdev *pdev, enum dp_full_mon_config val)
+{
+	struct dp_soc *soc = pdev->soc;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!soc->full_mon_mode)
+		return QDF_STATUS_SUCCESS;
+
+	if ((htt_h2t_full_mon_cfg(soc->htt_handle,
+				  pdev->pdev_id,
+				  val)) != QDF_STATUS_SUCCESS) {
+		status = QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+#else
+static inline QDF_STATUS
+dp_soc_config_full_mon_mode(struct dp_pdev *pdev, enum dp_full_mon_config val)
+{
+	return 0;
+}
+#endif
+
 /*
 * dp_vdev_attach_wifi3() - attach txrx vdev
 * @txrx_pdev: Datapath PDEV handle
@@ -6833,6 +6859,7 @@ QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl,
 
 	qdf_spin_lock_bh(&pdev->mon_lock);
 
+	dp_soc_config_full_mon_mode(pdev, DP_FULL_MON_DISABLE);
 	pdev->monitor_vdev = NULL;
 	pdev->monitor_configured = false;
 
@@ -6950,6 +6977,8 @@ static QDF_STATUS dp_vdev_set_monitor_mode(struct cdp_soc_t *soc,
 	pdev->monitor_configured = true;
 	dp_mon_buf_delayed_replenish(pdev);
 
+	dp_soc_config_full_mon_mode(pdev, DP_FULL_MON_ENABLE);
+
 	dp_mon_filter_setup_mon_mode(pdev);
 	status = dp_mon_filter_update(pdev);
 	if (status != QDF_STATUS_SUCCESS) {
@@ -10055,6 +10084,27 @@ static QDF_STATUS dp_set_vdev_pcp_tid_map_wifi3(struct cdp_soc_t *soc,
 	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef QCA_SUPPORT_FULL_MON
+static inline QDF_STATUS
+dp_config_full_mon_mode(struct cdp_soc_t *soc_handle,
+			uint8_t val)
+{
+	struct dp_soc *soc = (struct dp_soc *)soc_handle;
+
+	soc->full_mon_mode = val;
+	qdf_alert("Configure full monitor mode val: %d ", val);
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS
+dp_config_full_mon_mode(struct cdp_soc_t *soc_handle,
+			uint8_t val)
+{
+	return 0;
+}
+#endif
+
 static struct cdp_cmn_ops dp_ops_cmn = {
 	.txrx_soc_attach_target = dp_soc_attach_target_wifi3,
 	.txrx_vdev_attach = dp_vdev_attach_wifi3,
@@ -10220,6 +10270,7 @@ static struct cdp_mon_ops dp_ops_mon = {
 	/* Added support for HK advance filter */
 	.txrx_set_advance_monitor_filter = dp_pdev_set_advance_monitor_filter,
 	.txrx_deliver_tx_mgmt = dp_deliver_tx_mgmt,
+	.config_full_mon_mode = dp_config_full_mon_mode,
 };
 
 static struct cdp_host_stats_ops dp_ops_host_stats = {

+ 58 - 0
dp/wifi3.0/dp_rx_mon.h

@@ -39,6 +39,64 @@ QDF_STATUS dp_rx_pdev_mon_detach(struct dp_pdev *pdev);
 QDF_STATUS dp_rx_pdev_mon_status_attach(struct dp_pdev *pdev, int mac_id);
 QDF_STATUS dp_rx_pdev_mon_status_detach(struct dp_pdev *pdev, int mac_id);
 
+#ifdef QCA_SUPPORT_FULL_MON
+
+/**
+ * dp_full_mon_attach() - Full monitor mode attach
+ * This API initilises full monitor mode resources
+ *
+ * @pdev: dp pdev object
+ *
+ * Return: void
+ *
+ */
+void dp_full_mon_attach(struct dp_pdev *pdev);
+
+/**
+ * dp_full_mon_detach() - Full monitor mode attach
+ * This API deinitilises full monitor mode resources
+ *
+ * @pdev: dp pdev object
+ *
+ * Return: void
+ *
+ */
+void dp_full_mon_detach(struct dp_pdev *pdev);
+
+/**
+ * dp_rx_mon_process ()- API to process monitor destination ring for
+ * full monitor mode
+ *
+ * @soc: dp soc handle
+ * @mac_id: lmac id
+ * @quota: No. of ring entry that can be serviced in one shot.
+ */
+
+uint32_t dp_rx_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota);
+
+#else
+/**
+ * dp_full_mon_attach() - attach full monitor mode resources
+ * @pdev: Datapath PDEV handle
+ *
+ * Return: void
+ */
+static inline void dp_full_mon_attach(struct dp_pdev *pdev)
+{
+}
+
+/**
+ * dp_full_mon_detach() - detach full monitor mode resources
+ * @pdev: Datapath PDEV handle
+ *
+ * Return: void
+ *
+ */
+static inline void dp_full_mon_detach(struct dp_pdev *pdev)
+{
+}
+#endif
+
 /**
  * dp_reset_monitor_mode() - Disable monitor mode
  * @pdev_handle: Datapath PDEV handle

+ 5 - 0
dp/wifi3.0/dp_rx_mon_dest.c

@@ -1601,6 +1601,9 @@ dp_rx_pdev_mon_attach(struct dp_pdev *pdev) {
 	pdev->mon_last_linkdesc_paddr = 0;
 	pdev->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1;
 	qdf_spinlock_create(&pdev->mon_lock);
+
+	/* Attach full monitor mode resources */
+	dp_full_mon_attach(pdev);
 	return QDF_STATUS_SUCCESS;
 
 fail:
@@ -1649,6 +1652,8 @@ dp_rx_pdev_mon_detach(struct dp_pdev *pdev) {
 		dp_rx_pdev_mon_status_detach(pdev, mac_for_pdev);
 		dp_rx_pdev_mon_buf_detach(pdev, mac_for_pdev);
 	}
+	/* Detach full monitor mode resources */
+	dp_full_mon_detach(pdev);
 
 	return QDF_STATUS_SUCCESS;
 }

+ 25 - 1
dp/wifi3.0/dp_rx_mon_status.c

@@ -39,6 +39,26 @@ dp_rx_populate_cfr_non_assoc_sta(struct dp_pdev *pdev,
 				 struct hal_rx_ppdu_info *ppdu_info,
 				 struct cdp_rx_indication_ppdu *cdp_rx_ppdu);
 
+#ifndef QCA_SUPPORT_FULL_MON
+/**
+ * dp_rx_mon_process () - Core brain processing for monitor mode
+ *
+ * This API processes monitor destination ring followed by monitor status ring
+ * Called from bottom half (tasklet/NET_RX_SOFTIRQ)
+ *
+ * @soc: datapath soc context
+ * @mac_id: mac_id on which interrupt is received
+ * @quota: Number of status ring entry that can be serviced in one shot.
+ *
+ * @Return: Number of reaped status ring entries
+ */
+static inline uint32_t
+dp_rx_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota)
+{
+	return quota;
+}
+#endif
+
 #ifdef WLAN_RX_PKT_CAPTURE_ENH
 #include "dp_rx_mon_feature.h"
 #else
@@ -1595,7 +1615,11 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id,
 					pdev->mon_chan_freq;
 			}
 
-			dp_rx_mon_dest_process(soc, mac_id, quota);
+			if (qdf_unlikely(soc->full_mon_mode))
+				dp_rx_mon_process(soc, mac_id, quota);
+			else
+				dp_rx_mon_dest_process(soc, mac_id, quota);
+
 			pdev->mon_ppdu_status = DP_PPDU_STATUS_START;
 		}
 	}

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

@@ -5877,6 +5877,12 @@ dp_print_pdev_rx_mon_stats(struct dp_pdev *pdev)
 		       rx_mon_stats->dup_mon_linkdesc_cnt);
 	DP_PRINT_STATS("dup_mon_buf_cnt = %d",
 		       rx_mon_stats->dup_mon_buf_cnt);
+	DP_PRINT_STATS("ppdu_id_mismatch = %u",
+		       rx_mon_stats->ppdu_id_mismatch);
+	DP_PRINT_STATS("mon_rx_buf_reaped = %u",
+		       rx_mon_stats->mon_rx_bufs_reaped_dest);
+	DP_PRINT_STATS("mon_rx_buf_replenished = %u",
+		       rx_mon_stats->mon_rx_bufs_replenished_dest);
 	stat_ring_ppdu_ids =
 		(uint32_t *)qdf_mem_malloc(sizeof(uint32_t) * MAX_PPDU_ID_HIST);
 	dest_ring_ppdu_ids =

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

@@ -134,6 +134,7 @@ struct cdp_peer_rate_stats_ctx;
 struct cdp_soc_rate_stats_ctx;
 struct dp_rx_fst;
 struct dp_mon_filter;
+struct dp_mon_mpdu;
 
 #define DP_PDEV_ITERATE_VDEV_LIST(_pdev, _vdev) \
 	TAILQ_FOREACH((_vdev), &(_pdev)->vdev_list, vdev_list_elem)
@@ -1251,6 +1252,9 @@ struct dp_soc {
 	uint8_t fisa_enable;
 #endif
 #endif /* WLAN_SUPPORT_RX_FLOW_TAG || WLAN_SUPPORT_RX_FISA */
+
+	/* Full monitor mode support */
+	bool full_mon_mode;
 };
 
 #ifdef IPA_OFFLOAD
@@ -1796,6 +1800,16 @@ struct dp_pdev {
 #endif /* WLAN_SUPPORT_DATA_STALL */
 
 	struct dp_mon_filter **filter;	/* Monitor Filter pointer */
+
+#ifdef QCA_SUPPORT_FULL_MON
+	/* List to maintain all MPDUs for a PPDU in monitor mode */
+	TAILQ_HEAD(, dp_mon_mpdu) mon_mpdu_q;
+
+	/* TODO: define per-user mpdu list
+	 * struct dp_mon_mpdu_list mpdu_list[MAX_MU_USERS];
+	 */
+	struct hal_rx_mon_desc_info *mon_desc;
+#endif
 };
 
 struct dp_peer;

+ 6 - 1
wlan_cfg/cfg_dp.h

@@ -788,6 +788,10 @@
 		WLAN_CFG_PKTLOG_BUFFER_SIZE, \
 		CFG_VALUE_OR_DEFAULT, "Packet Log buffer size")
 
+#define CFG_DP_FULL_MON_MODE \
+		CFG_INI_BOOL("full_mon_mode", \
+		false, "Full Monitor mode support")
+
 #define CFG_DP \
 		CFG(CFG_DP_HTT_PACKET_TYPE) \
 		CFG(CFG_DP_INT_BATCH_THRESHOLD_OTHER) \
@@ -860,6 +864,7 @@
 		CFG(CFG_DP_RX_MON_PROTOCOL_FLOW_TAG_ENABLE) \
 		CFG(CFG_DP_RXDMA_MONITOR_RX_DROP_THRESHOLD) \
 		CFG(CFG_DP_PKTLOG_BUFFER_SIZE) \
-		CFG(CFG_DP_RX_FISA_ENABLE)
+		CFG(CFG_DP_RX_FISA_ENABLE) \
+		CFG(CFG_DP_FULL_MON_MODE)
 
 #endif /* _CFG_DP_H_ */