From fe453dfd1087698b090e90ba67474e7e0eab2483 Mon Sep 17 00:00:00 2001 From: Padma Raghunathan Date: Tue, 8 Oct 2019 10:35:06 +0530 Subject: [PATCH] qcacmn: CFR: Monitor/Data ring filter settings Channel Frequency Response(CFR) captures FFT bins corresponding to a PPDU received and this is relayed to user space application. Since FFT bins alone will not be meaningful, additional information about the PPDU such as Peer addr, BW, NSS, etc are extracted from multiple PPDU status TLVs and passed on to userspace along with CFR data. Host RX monitor status ring is configured during CFR enable and the host subscribes to relevant PPDU TLVs that provides all necessary information for CFR data correlation. Change-Id: Ia8080fe96c330db42d371634ba4363eb36c05402 CRs-Fixed: 2593416 --- dp/inc/cdp_txrx_ctrl.h | 30 ++++++++++++++- dp/inc/cdp_txrx_ops.h | 18 ++++++++- dp/wifi3.0/dp_main.c | 87 +++++++++++++++++++++++++++++++++++++++++- dp/wifi3.0/dp_types.h | 3 +- 4 files changed, 134 insertions(+), 4 deletions(-) diff --git a/dp/inc/cdp_txrx_ctrl.h b/dp/inc/cdp_txrx_ctrl.h index d79adc21ac..91742faf55 100644 --- a/dp/inc/cdp_txrx_ctrl.h +++ b/dp/inc/cdp_txrx_ctrl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-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 @@ -723,6 +723,34 @@ cdp_get_pldev(ol_txrx_soc_handle soc, return soc->ops->ctrl_ops->txrx_get_pldev(pdev); } +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) +/** + * cdp_cfr_filter() - Configure Host RX monitor status ring for CFR + * @soc: SOC TXRX handle + * @pdev_id: ID of the physical device object + * @enable: Enable or disable CFR + * @filter_val: Flag to select filter for monitor mode + */ +static inline void +cdp_cfr_filter(ol_txrx_soc_handle soc, + uint8_t pdev_id, + bool enable, + struct cdp_monitor_filter *filter_val) +{ + if (!soc || !soc->ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + QDF_BUG(0); + return; + } + + if (!soc->ops->cfr_ops || !soc->ops->cfr_ops->txrx_cfr_filter) + return; + + soc->ops->cfr_ops->txrx_cfr_filter(soc, pdev_id, enable, filter_val); +} +#endif + #if defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(WLAN_RX_PKT_CAPTURE_ENH) /** * cdp_update_peer_pkt_capture_params() - Sets Rx & Tx Capture params for a peer diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 005fc13440..372d5dcde4 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.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 @@ -1610,6 +1610,19 @@ struct cdp_rx_offld_ops { }; #endif +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) +/** + * struct cdp_cfr_ops - host cfr ops + * @txrx_cfr_filter: Handler to configure host rx monitor status ring + */ +struct cdp_cfr_ops { + void (*txrx_cfr_filter)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + bool enable, + struct cdp_monitor_filter *filter_val); +}; +#endif + struct cdp_ops { struct cdp_cmn_ops *cmn_drv_ops; struct cdp_ctrl_ops *ctrl_ops; @@ -1645,6 +1658,9 @@ struct cdp_ops { #ifdef WLAN_FEATURE_PKT_CAPTURE struct cdp_pktcapture_ops *pktcapture_ops; #endif +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) + struct cdp_cfr_ops *cfr_ops; +#endif }; #endif diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 2d505e3bb4..769c4f9546 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-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 @@ -151,6 +151,12 @@ static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle, bool is_dp_verbose_debug_enabled; #endif +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) +static void dp_cfr_filter(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + bool enable, + struct cdp_monitor_filter *filter_val); +#endif static uint8_t dp_soc_ring_if_nss_offloaded(struct dp_soc *soc, enum hal_ring_type ring_type, int ring_num); @@ -9749,6 +9755,12 @@ static struct cdp_pflow_ops dp_ops_pflow = { }; #endif /* CONFIG_WIN */ +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) +static struct cdp_cfr_ops dp_ops_cfr = { + .txrx_cfr_filter = dp_cfr_filter, +}; +#endif + #ifdef FEATURE_RUNTIME_PM /** * dp_runtime_suspend() - ensure DP is ready to runtime suspend @@ -10179,6 +10191,9 @@ static struct cdp_ops dp_txrx_ops = { #ifdef DP_POWER_SAVE .bus_ops = &dp_ops_bus, #endif +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) + .cfr_ops = &dp_ops_cfr, +#endif }; /* @@ -10506,6 +10521,76 @@ void dp_is_hw_dbs_enable(struct dp_soc *soc, *max_mac_rings = (dbs_enable)?(*max_mac_rings):1; } +#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) +/* + * dp_cfr_filter() - Configure HOST RX monitor status ring for CFR + * @soc_hdl: Datapath soc handle + * @pdev_id: id of data path pdev handle + * @enable: Enable/Disable CFR + * @filter_val: Flag to select Filter for monitor mode + */ +static void dp_cfr_filter(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id, + bool enable, + struct cdp_monitor_filter *filter_val) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + struct htt_rx_ring_tlv_filter htt_tlv_filter = {0}; + int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx); + uint8_t mac_id = 0; + + if (pdev->monitor_vdev) { + dp_info("No action is needed since monitor mode is enabled\n"); + return; + } + soc = pdev->soc; + pdev->cfr_rcc_mode = false; + dp_is_hw_dbs_enable(soc, &max_mac_rings); + + dp_debug("Max_mac_rings %d", max_mac_rings); + dp_info("enable : %d, mode: 0x%x", enable, filter_val->mode); + + if (enable) { + pdev->cfr_rcc_mode = true; + + htt_tlv_filter.ppdu_start = 1; + htt_tlv_filter.ppdu_end = 1; + htt_tlv_filter.ppdu_end_user_stats = 1; + htt_tlv_filter.ppdu_end_user_stats_ext = 1; + htt_tlv_filter.ppdu_end_status_done = 1; + htt_tlv_filter.mpdu_start = 1; + htt_tlv_filter.offset_valid = false; + + htt_tlv_filter.enable_fp = + (filter_val->mode & MON_FILTER_PASS) ? 1 : 0; + htt_tlv_filter.enable_md = 0; + htt_tlv_filter.enable_mo = + (filter_val->mode & MON_FILTER_OTHER) ? 1 : 0; + htt_tlv_filter.fp_mgmt_filter = filter_val->fp_mgmt; + htt_tlv_filter.fp_ctrl_filter = filter_val->fp_ctrl; + htt_tlv_filter.fp_data_filter = filter_val->fp_data; + htt_tlv_filter.mo_mgmt_filter = filter_val->mo_mgmt; + htt_tlv_filter.mo_ctrl_filter = filter_val->mo_ctrl; + htt_tlv_filter.mo_data_filter = filter_val->mo_data; + } + + for (mac_id = 0; mac_id < max_mac_rings; mac_id++) { + int mac_for_pdev = + dp_get_mac_id_for_pdev(mac_id, + pdev->pdev_id); + + htt_h2t_rx_ring_cfg(soc->htt_handle, + mac_for_pdev, + pdev->rxdma_mon_status_ring[mac_id] + .hal_srng, + RXDMA_MONITOR_STATUS, + RX_BUFFER_SIZE, + &htt_tlv_filter); + } +} +#endif + /* * dp_is_soc_reinit() - Check if soc reinit is true * @soc: DP SoC context diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 7a89cea5d9..9ec74261b3 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-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 @@ -1617,6 +1617,7 @@ struct dp_pdev { bool tx_sniffer_enable; /* mirror copy mode */ bool mcopy_mode; + bool cfr_rcc_mode; bool bpr_enable; /* enable time latency check for tx completion */