From 8db4b4ac324c9595d475b43ac689ee600191335d Mon Sep 17 00:00:00 2001 From: Shwetha G K Date: Thu, 24 Oct 2019 11:58:01 +0530 Subject: [PATCH] qcacmn: Control path support for Spectral DMA debug All gen III chipsets use Direct-DMA mechanism to copy Spectral reports to the Host for further processing. This mechanism involves ring and buffer management in the Host, FW, and uCode, where improper/incomplete DMA and improper tail update issues are seen. DBR framework provides support to debug such issues. Add Spectral control path support to facilitate the configuration of these debug options. CRs-Fixed: 2478596 2478595 Change-Id: I094616c4137145389b6984ccab933e5ebd0aa1ab --- .../spectral/inc/wlan_cfg80211_spectral.h | 15 +- .../spectral/src/wlan_cfg80211_spectral.c | 62 +++- spectral/core/spectral_common.c | 8 + spectral/core/spectral_defs_i.h | 15 +- spectral/core/spectral_offload.c | 20 +- spectral/dispatcher/inc/spectral_ioctl.h | 1 + .../inc/wlan_spectral_public_structs.h | 24 ++ .../dispatcher/inc/wlan_spectral_tgt_api.h | 12 + .../dispatcher/src/wlan_spectral_tgt_api.c | 67 ++++- target_if/spectral/target_if_spectral.c | 277 +++++++++++++++++- target_if/spectral/target_if_spectral.h | 5 + .../lmac_if/inc/wlan_lmac_if_def.h | 18 +- 12 files changed, 502 insertions(+), 22 deletions(-) diff --git a/os_if/linux/spectral/inc/wlan_cfg80211_spectral.h b/os_if/linux/spectral/inc/wlan_cfg80211_spectral.h index 39bae6fae6..ec5081c1ea 100644 --- a/os_if/linux/spectral/inc/wlan_cfg80211_spectral.h +++ b/os_if/linux/spectral/inc/wlan_cfg80211_spectral.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017, 2019 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 @@ -135,4 +135,17 @@ int wlan_cfg80211_spectral_scan_get_status(struct wiphy *wiphy, struct wlan_objmgr_pdev *pdev, const void *data, int data_len); + +/** + * wlan_cfg80211_spectral_scan_dma_debug_config() - configure DMA debug + * @pdev: Pointer to pdev + * @tb: Pointer to Spectral Scan config attribute + * @sscan_mode: Spectral scan mode + * + * Return QDF_STATUS_SUCCESS on success, QDF_STATUS_E_FAILURE on failure + */ +QDF_STATUS wlan_cfg80211_spectral_scan_dma_debug_config( + struct wlan_objmgr_pdev *pdev, + struct nlattr **tb, + enum spectral_scan_mode sscan_mode); #endif diff --git a/os_if/linux/spectral/src/wlan_cfg80211_spectral.c b/os_if/linux/spectral/src/wlan_cfg80211_spectral.c index a5fefde940..8173cee6c9 100644 --- a/os_if/linux/spectral/src/wlan_cfg80211_spectral.c +++ b/os_if/linux/spectral/src/wlan_cfg80211_spectral.c @@ -84,7 +84,11 @@ static const struct nla_policy spectral_scan_policy[ [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY] = { .type = NLA_U32}, [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE] = { - .type = NLA_U32}, + .type = NLA_U32}, + [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_RING_DEBUG] = { + .type = NLA_U8}, + [QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_BUFFER_DEBUG] = { + .type = NLA_U8}, }; static void wlan_spectral_intit_config(struct spectral_config *config_req) @@ -182,6 +186,57 @@ convert_spectral_err_code_internal_to_nl return QDF_STATUS_SUCCESS; } +#ifdef DIRECT_BUF_RX_DEBUG +QDF_STATUS wlan_cfg80211_spectral_scan_dma_debug_config( + struct wlan_objmgr_pdev *pdev, + struct nlattr **tb, + enum spectral_scan_mode sscan_mode) +{ + struct spectral_cp_request sscan_req; + uint8_t dma_debug_enable; + QDF_STATUS status; + + if (!tb || !pdev) + return QDF_STATUS_E_FAILURE; + + if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_RING_DEBUG]) { + dma_debug_enable = nla_get_u8(tb[ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_RING_DEBUG]); + sscan_req.ss_mode = sscan_mode; + sscan_req.dma_debug_req.dma_debug_enable = !!dma_debug_enable; + sscan_req.dma_debug_req.dma_debug_type = + SPECTRAL_DMA_RING_DEBUG; + sscan_req.req_id = SPECTRAL_SET_DMA_DEBUG; + status = ucfg_spectral_control(pdev, &sscan_req); + if (status != QDF_STATUS_SUCCESS) { + osif_err("Could not configure dma ring debug"); + return QDF_STATUS_E_FAILURE; + } + } + + if (tb[QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_BUFFER_DEBUG]) { + dma_debug_enable = nla_get_u8(tb[ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_BUFFER_DEBUG]); + sscan_req.ss_mode = sscan_mode; + sscan_req.dma_debug_req.dma_debug_enable = !!dma_debug_enable; + sscan_req.dma_debug_req.dma_debug_type = + SPECTRAL_DMA_BUFFER_DEBUG; + sscan_req.req_id = SPECTRAL_SET_DMA_DEBUG; + return ucfg_spectral_control(pdev, &sscan_req); + } + + return QDF_STATUS_SUCCESS; +} +#else +QDF_STATUS wlan_cfg80211_spectral_scan_dma_debug_config( + struct wlan_objmgr_pdev *pdev, + struct nlattr **tb, + enum spectral_scan_mode sscan_mode) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* DIRECT_BUF_RX_DEBUG */ + int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy, struct wlan_objmgr_pdev *pdev, const void *data, @@ -328,6 +383,11 @@ int wlan_cfg80211_spectral_scan_config_and_start(struct wiphy *wiphy, return -ENOMEM; } + status = wlan_cfg80211_spectral_scan_dma_debug_config( + pdev, tb, sscan_mode); + if (QDF_IS_STATUS_ERROR(status)) + return -EINVAL; + if (CONFIG_REQUESTED(scan_req_type)) { sscan_req.ss_mode = sscan_mode; sscan_req.req_id = SPECTRAL_SET_CONFIG; diff --git a/spectral/core/spectral_common.c b/spectral/core/spectral_common.c index 4f02f2c1bd..a460635da4 100644 --- a/spectral/core/spectral_common.c +++ b/spectral/core/spectral_common.c @@ -471,6 +471,14 @@ spectral_control_cmn(struct wlan_objmgr_pdev *pdev, } break; + case SPECTRAL_SET_DMA_DEBUG: + if (sc->sptrlc_set_dma_debug) + sc->sptrlc_set_dma_debug( + pdev, + sscan_req->dma_debug_req.dma_debug_type, + sscan_req->dma_debug_req.dma_debug_enable); + break; + default: goto bad; break; diff --git a/spectral/core/spectral_defs_i.h b/spectral/core/spectral_defs_i.h index ad4944b824..716807d5af 100644 --- a/spectral/core/spectral_defs_i.h +++ b/spectral/core/spectral_defs_i.h @@ -118,6 +118,7 @@ struct wmi_spectral_cmd_ops; * @sptrlc_use_nl_bcast: Check whether to use Netlink broadcast/unicast * @sptrlc_deregister_netlink_cb: De-register Netlink callbacks * @sptrlc_process_spectral_report: Process spectral report + * @sptrlc_set_dma_debug: Set DMA debug */ struct spectral_context { struct wlan_objmgr_psoc *psoc_obj; @@ -163,13 +164,17 @@ struct spectral_context { struct wlan_objmgr_pdev *pdev, struct wmi_spectral_cmd_ops *cmd_ops); void (*sptrlc_register_netlink_cb)( - struct wlan_objmgr_pdev *pdev, - struct spectral_nl_cb *nl_cb); + struct wlan_objmgr_pdev *pdev, + struct spectral_nl_cb *nl_cb); bool (*sptrlc_use_nl_bcast)(struct wlan_objmgr_pdev *pdev); void (*sptrlc_deregister_netlink_cb)(struct wlan_objmgr_pdev *pdev); int (*sptrlc_process_spectral_report)( - struct wlan_objmgr_pdev *pdev, - void *payload); + struct wlan_objmgr_pdev *pdev, + void *payload); + QDF_STATUS (*sptrlc_set_dma_debug)( + struct wlan_objmgr_pdev *pdev, + enum spectral_dma_debug dma_debug_type, + bool dma_debug_enable); }; -#endif /* _SPECTRAL_DEFS_I_H_ */ +#endif /* _SPECTRAL_DEFS_I_H_ */ diff --git a/spectral/core/spectral_offload.c b/spectral/core/spectral_offload.c index b07c7a7fc2..7db9dd3861 100644 --- a/spectral/core/spectral_offload.c +++ b/spectral/core/spectral_offload.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -21,6 +21,23 @@ #include "spectral_ol_api_i.h" #include "../dispatcher/inc/wlan_spectral_tgt_api.h" +#ifdef DIRECT_BUF_RX_DEBUG +static void +spectral_ctx_init_ol_dma_debug(struct spectral_context *sc) +{ + if (!sc) { + spectral_err("spectral context is null!"); + return; + } + sc->sptrlc_set_dma_debug = tgt_set_spectral_dma_debug; +} +#else +static void +spectral_ctx_init_ol_dma_debug(struct spectral_context *sc) +{ +} +#endif + void spectral_ctx_init_ol(struct spectral_context *sc) { @@ -47,4 +64,5 @@ spectral_ctx_init_ol(struct spectral_context *sc) sc->sptrlc_use_nl_bcast = tgt_spectral_use_nl_bcast; sc->sptrlc_deregister_netlink_cb = tgt_spectral_deregister_nl_cb; sc->sptrlc_process_spectral_report = tgt_spectral_process_report; + spectral_ctx_init_ol_dma_debug(sc); } diff --git a/spectral/dispatcher/inc/spectral_ioctl.h b/spectral/dispatcher/inc/spectral_ioctl.h index e575a3f834..f81938bdbc 100644 --- a/spectral/dispatcher/inc/spectral_ioctl.h +++ b/spectral/dispatcher/inc/spectral_ioctl.h @@ -51,6 +51,7 @@ #define SPECTRAL_SET_ICM_ACTIVE (DFS_LAST_IOCTL + 21) #define SPECTRAL_GET_NOMINAL_NOISEFLOOR (DFS_LAST_IOCTL + 22) #define SPECTRAL_GET_DEBUG_LEVEL (DFS_LAST_IOCTL + 23) +#define SPECTRAL_SET_DMA_DEBUG (DFS_LAST_IOCTL + 24) /* * ioctl parameter types diff --git a/spectral/dispatcher/inc/wlan_spectral_public_structs.h b/spectral/dispatcher/inc/wlan_spectral_public_structs.h index 725e8aeb2b..34cc4b1bc8 100644 --- a/spectral/dispatcher/inc/wlan_spectral_public_structs.h +++ b/spectral/dispatcher/inc/wlan_spectral_public_structs.h @@ -232,6 +232,16 @@ enum spectral_cp_error_code { SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED, }; +/** + * enum spectral_dma_debug - Spectral DMA debug + * @SPECTRAL_DMA_RING_DEBUG: Spectral DMA ring debug + * @SPECTRAL_DMA_BUFFER_DEBUG: Spectral DMA buffer debug + */ +enum spectral_dma_debug { + SPECTRAL_DMA_RING_DEBUG, + SPECTRAL_DMA_BUFFER_DEBUG, +}; + /** * struct spectral_chan_stats - channel status info * @cycle_count: Cycle count @@ -378,12 +388,25 @@ struct spectral_scan_debug_request { enum spectral_cp_error_code sscan_err_code; }; +/** + * struct spectral_scan_dma_debug_request - DMA debug request + * @dma_debug_enable: Enable/disable @dma_debug_type + * @dma_debug_type: Type of Spectral DMA debug i.e., ring or buffer debug + * @sscan_err_code: Spectral scan error code + */ +struct spectral_scan_dma_debug_request { + bool dma_debug_enable; + enum spectral_dma_debug dma_debug_type; + enum spectral_cp_error_code sscan_err_code; +}; + /** * struct spectral_cp_request - Spectral control path request * Creating request and extracting response has to * be atomic. * @ss_mode: Spectral scan mode * @req_id: Request identifier + * @dma_debug_req: Spectral DMA debug request */ struct spectral_cp_request { enum spectral_scan_mode ss_mode; @@ -396,6 +419,7 @@ struct spectral_cp_request { struct spectral_scan_get_chan_width_request chan_width_req; struct spectral_scan_get_status_request status_req; struct spectral_scan_debug_request debug_req; + struct spectral_scan_dma_debug_request dma_debug_req; }; }; diff --git a/spectral/dispatcher/inc/wlan_spectral_tgt_api.h b/spectral/dispatcher/inc/wlan_spectral_tgt_api.h index eb917749cc..264ab28dc8 100644 --- a/spectral/dispatcher/inc/wlan_spectral_tgt_api.h +++ b/spectral/dispatcher/inc/wlan_spectral_tgt_api.h @@ -273,4 +273,16 @@ tgt_spectral_unregister_to_dbr(struct wlan_objmgr_pdev *pdev); */ uint32_t tgt_spectral_get_target_type(struct wlan_objmgr_psoc *psoc); + +/** + * tgt_set_spectral_dma_debug() - Set DMA debug for Spectral + * @pdev: Pointer to pdev object + * @dma_debug_type: Type of Spectral DMA debug i.e., ring or buffer debug + * @dma_debug_enable: Value to be set for @dma_debug_type + * + * Return: QDF_STATUS of operation + */ +QDF_STATUS tgt_set_spectral_dma_debug(struct wlan_objmgr_pdev *pdev, + enum spectral_dma_debug dma_debug_type, + bool dma_debug_enable); #endif /* _WLAN_SPECTRAL_TGT_API_H_ */ diff --git a/spectral/dispatcher/src/wlan_spectral_tgt_api.c b/spectral/dispatcher/src/wlan_spectral_tgt_api.c index 877aca1f16..f416b47e9c 100644 --- a/spectral/dispatcher/src/wlan_spectral_tgt_api.c +++ b/spectral/dispatcher/src/wlan_spectral_tgt_api.c @@ -298,23 +298,26 @@ tgt_spectral_register_to_dbr(struct wlan_objmgr_pdev *pdev) { struct wlan_objmgr_psoc *psoc; struct wlan_lmac_if_direct_buf_rx_tx_ops *dbr_tx_ops = NULL; + struct wlan_lmac_if_sptrl_tx_ops *sptrl_tx_ops = NULL; struct dbr_module_config dbr_config = {0}; - uint32_t target_type; psoc = wlan_pdev_get_psoc(pdev); dbr_tx_ops = &psoc->soc_cb.tx_ops.dbr_tx_ops; + sptrl_tx_ops = &psoc->soc_cb.tx_ops.sptrl_tx_ops; dbr_config.num_resp_per_event = DBR_NUM_RESP_PER_EVENT_SPECTRAL; dbr_config.event_timeout_in_ms = DBR_EVENT_TIMEOUT_IN_MS_SPECTRAL; - target_type = tgt_spectral_get_target_type(psoc); - if ((target_type == TARGET_TYPE_QCA8074) || - (target_type == TARGET_TYPE_QCA8074V2) || - (target_type == TARGET_TYPE_QCA6018) || - (target_type == TARGET_TYPE_QCA6390)) + if ((sptrl_tx_ops->sptrlto_direct_dma_support) && + (sptrl_tx_ops->sptrlto_direct_dma_support(pdev))) { + if (sptrl_tx_ops->sptrlto_check_and_do_dbr_buff_debug) + sptrl_tx_ops->sptrlto_check_and_do_dbr_buff_debug(pdev); if (dbr_tx_ops->direct_buf_rx_module_register) - return dbr_tx_ops->direct_buf_rx_module_register + dbr_tx_ops->direct_buf_rx_module_register (pdev, 0, &dbr_config, spectral_dbr_event_handler); + if (sptrl_tx_ops->sptrlto_check_and_do_dbr_ring_debug) + sptrl_tx_ops->sptrlto_check_and_do_dbr_ring_debug(pdev); + } return QDF_STATUS_SUCCESS; } @@ -324,16 +327,28 @@ tgt_spectral_unregister_to_dbr(struct wlan_objmgr_pdev *pdev) { struct wlan_objmgr_psoc *psoc; struct wlan_lmac_if_direct_buf_rx_tx_ops *dbr_tx_ops = NULL; + struct wlan_lmac_if_sptrl_tx_ops *sptrl_tx_ops = NULL; psoc = wlan_pdev_get_psoc(pdev); dbr_tx_ops = &psoc->soc_cb.tx_ops.dbr_tx_ops; + sptrl_tx_ops = &psoc->soc_cb.tx_ops.sptrl_tx_ops; - if ((tgt_spectral_get_target_type(psoc) == TARGET_TYPE_QCA8074) || - (tgt_spectral_get_target_type(psoc) == TARGET_TYPE_QCA8074V2) || - (tgt_spectral_get_target_type(psoc) == TARGET_TYPE_QCA6018)) - if (dbr_tx_ops->direct_buf_rx_module_unregister) - return dbr_tx_ops->direct_buf_rx_module_unregister + if ((sptrl_tx_ops->sptrlto_direct_dma_support) && + (sptrl_tx_ops->sptrlto_direct_dma_support(pdev))) { + /* Stop DBR debug as the buffers itself are freed now */ + if (dbr_tx_ops->direct_buf_rx_stop_ring_debug) + dbr_tx_ops->direct_buf_rx_stop_ring_debug(pdev, 0); + + /*No need to zero-out as buffers are anyway getting freed*/ + if (dbr_tx_ops->direct_buf_rx_stop_buffer_poisoning) + dbr_tx_ops->direct_buf_rx_stop_buffer_poisoning (pdev, 0); + if (dbr_tx_ops->direct_buf_rx_module_unregister) + dbr_tx_ops->direct_buf_rx_module_unregister + (pdev, 0); + + return QDF_STATUS_SUCCESS; + } return QDF_STATUS_E_FAILURE; } @@ -349,4 +364,32 @@ tgt_spectral_unregister_to_dbr(struct wlan_objmgr_pdev *pdev) { return QDF_STATUS_SUCCESS; } +#endif /* DIRECT_BUF_RX_ENABLE */ + +#ifdef DIRECT_BUF_RX_DEBUG +QDF_STATUS tgt_set_spectral_dma_debug(struct wlan_objmgr_pdev *pdev, + enum spectral_dma_debug dma_debug_type, + bool dma_debug_enable) +{ + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_pdev_get_psoc(pdev); + + if (!psoc) { + spectral_err("psoc is NULL!"); + return QDF_STATUS_E_FAILURE; + } + + return psoc->soc_cb.tx_ops.sptrl_tx_ops.sptrlto_set_dma_debug( + pdev, + dma_debug_type, + dma_debug_enable); +} +#else +QDF_STATUS tgt_set_spectral_dma_debug(struct wlan_objmgr_pdev *pdev, + enum spectral_dma_debug dma_debug_type, + bool dma_debug_enable) +{ + return QDF_STATUS_SUCCESS; +} #endif diff --git a/target_if/spectral/target_if_spectral.c b/target_if/spectral/target_if_spectral.c index 7dd53f4395..3cf103910d 100644 --- a/target_if/spectral/target_if_spectral.c +++ b/target_if/spectral/target_if_spectral.c @@ -2082,6 +2082,12 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev) qdf_spinlock_create(&spectral->noise_pwr_reports_lock); target_if_spectral_clear_stats(spectral); + if (target_type == TARGET_TYPE_QCA8074 || + target_type == TARGET_TYPE_QCA8074V2 || + target_type == TARGET_TYPE_QCA6018 || + target_type == TARGET_TYPE_QCA6390) + spectral->direct_dma_support = true; + if (target_type == TARGET_TYPE_QCA8074V2) spectral->fftbin_size_war = SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE; @@ -3734,6 +3740,251 @@ target_if_is_spectral_enabled(struct wlan_objmgr_pdev *pdev, return p_sops->is_spectral_enabled(spectral, smode); } +#ifdef DIRECT_BUF_RX_DEBUG +/** + * target_if_spectral_do_dbr_ring_debug() - Start/Stop Spectral DMA ring debug + * @pdev: Pointer to pdev object + * @enable: Enable/Disable Spectral DMA ring debug + * + * Start/stop Spectral DMA ring debug based on @enable. + * Also save the state for future use. + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +target_if_spectral_do_dbr_ring_debug(struct wlan_objmgr_pdev *pdev, bool enable) +{ + struct target_if_spectral *spectral; + struct wlan_lmac_if_tx_ops *tx_ops; + struct wlan_objmgr_psoc *psoc; + + if (!pdev) + return QDF_STATUS_E_FAILURE; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + spectral_err("psoc is null"); + return QDF_STATUS_E_INVAL; + } + tx_ops = &psoc->soc_cb.tx_ops; + + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectal LMAC object is NULL"); + return QDF_STATUS_E_INVAL; + } + + /* Save the state */ + spectral->dbr_ring_debug = enable; + + if (enable) + return tx_ops->dbr_tx_ops.direct_buf_rx_start_ring_debug( + pdev, 0, SPECTRAL_DBR_RING_DEBUG_SIZE); + else + return tx_ops->dbr_tx_ops.direct_buf_rx_stop_ring_debug( + pdev, 0); + + return QDF_STATUS_SUCCESS; +} + +/** + * target_if_spectral_do_dbr_buff_debug() - Start/Stop Spectral DMA buffer debug + * @pdev: Pointer to pdev object + * @enable: Enable/Disable Spectral DMA buffer debug + * + * Start/stop Spectral DMA buffer debug based on @enable. + * Also save the state for future use. + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +target_if_spectral_do_dbr_buff_debug(struct wlan_objmgr_pdev *pdev, bool enable) +{ + struct target_if_spectral *spectral; + struct wlan_lmac_if_tx_ops *tx_ops; + struct wlan_objmgr_psoc *psoc; + + if (!pdev) + return QDF_STATUS_E_FAILURE; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + spectral_err("psoc is null"); + return QDF_STATUS_E_INVAL; + } + tx_ops = &psoc->soc_cb.tx_ops; + + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectal LMAC object is NULL"); + return QDF_STATUS_E_INVAL; + } + + /* Save the state */ + spectral->dbr_buff_debug = enable; + + if (enable) + return tx_ops->dbr_tx_ops.direct_buf_rx_start_buffer_poisoning( + pdev, 0, MEM_POISON_SIGNATURE); + else + return tx_ops->dbr_tx_ops.direct_buf_rx_stop_buffer_poisoning( + pdev, 0); +} + +/** + * target_if_spectral_check_and_do_dbr_buff_debug() - Start/Stop Spectral buffer + * debug based on the previous state + * @pdev: Pointer to pdev object + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +target_if_spectral_check_and_do_dbr_buff_debug(struct wlan_objmgr_pdev *pdev) +{ + struct target_if_spectral *spectral; + + if (!pdev) { + spectral_err("pdev is NULL!"); + return QDF_STATUS_E_FAILURE; + } + + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectal LMAC object is NULL"); + return QDF_STATUS_E_INVAL; + } + + if (spectral->dbr_buff_debug) + return target_if_spectral_do_dbr_buff_debug(pdev, true); + else + return target_if_spectral_do_dbr_buff_debug(pdev, false); +} + +/** + * target_if_spectral_check_and_do_dbr_ring_debug() - Start/Stop Spectral ring + * debug based on the previous state + * @pdev: Pointer to pdev object + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +target_if_spectral_check_and_do_dbr_ring_debug(struct wlan_objmgr_pdev *pdev) +{ + struct target_if_spectral *spectral; + + if (!pdev) { + spectral_err("pdev is NULL!"); + return QDF_STATUS_E_FAILURE; + } + + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectal LMAC object is NULL"); + return QDF_STATUS_E_INVAL; + } + + if (spectral->dbr_ring_debug) + return target_if_spectral_do_dbr_ring_debug(pdev, true); + else + return target_if_spectral_do_dbr_ring_debug(pdev, false); +} + +/** + * target_if_spectral_set_dma_debug() - Set DMA debug for Spectral + * @pdev: Pointer to pdev object + * @dma_debug_type: Type of Spectral DMA debug i.e., ring or buffer debug + * @debug_value: Value to be set for @dma_debug_type + * + * Set DMA debug for Spectral and start/stop Spectral DMA debug function + * based on @debug_value + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +target_if_spectral_set_dma_debug( + struct wlan_objmgr_pdev *pdev, + enum spectral_dma_debug dma_debug_type, + bool debug_value) +{ + struct target_if_spectral_ops *p_sops; + struct wlan_objmgr_psoc *psoc; + struct wlan_lmac_if_tx_ops *tx_ops; + struct target_if_spectral *spectral; + + if (!pdev) + return QDF_STATUS_E_FAILURE; + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + spectral_err("psoc is null"); + return QDF_STATUS_E_INVAL; + } + tx_ops = &psoc->soc_cb.tx_ops; + + if (!tx_ops->target_tx_ops.tgt_get_tgt_type) { + spectral_err("Unable to fetch target type"); + return QDF_STATUS_E_FAILURE; + } + + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectal LMAC object is NULL"); + return QDF_STATUS_E_INVAL; + } + + if (spectral->direct_dma_support) { + p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); + if (p_sops->is_spectral_active(spectral, + SPECTRAL_SCAN_MODE_NORMAL) || + p_sops->is_spectral_active(spectral, + SPECTRAL_SCAN_MODE_AGILE)) { + spectral_err("Altering DBR debug config isn't allowed during an ongoing scan"); + return QDF_STATUS_E_FAILURE; + } + + switch (dma_debug_type) { + case SPECTRAL_DMA_RING_DEBUG: + target_if_spectral_do_dbr_ring_debug(pdev, debug_value); + break; + + case SPECTRAL_DMA_BUFFER_DEBUG: + target_if_spectral_do_dbr_buff_debug(pdev, debug_value); + break; + + default: + spectral_err("Unsupported DMA debug type : %d", + dma_debug_type); + return QDF_STATUS_E_FAILURE; + } + } + return QDF_STATUS_SUCCESS; +} +#endif /* DIRECT_BUF_RX_DEBUG */ + +/** + * target_if_spectral_direct_dma_support() - Get Direct-DMA support + * @pdev: Pointer to pdev object + * + * Return: Whether Direct-DMA is supported on this radio + */ +static bool +target_if_spectral_direct_dma_support(struct wlan_objmgr_pdev *pdev) +{ + struct target_if_spectral *spectral; + + if (!pdev) { + spectral_err("pdev is NULL!"); + return false; + } + + spectral = get_target_if_spectral_handle_from_pdev(pdev); + if (!spectral) { + spectral_err("Spectral LMAC object is NULL"); + return false; + } + return spectral->direct_dma_support; +} + /** * target_if_set_debug_level() - Set debug level for Spectral * @pdev: Pointer to pdev object @@ -3904,6 +4155,27 @@ target_if_process_spectral_report(struct wlan_objmgr_pdev *pdev, return p_sops->process_spectral_report(pdev, payload); } +#ifdef DIRECT_BUF_RX_DEBUG +static inline void +target_if_sptrl_debug_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) +{ + if (!tx_ops) + return; + + tx_ops->sptrl_tx_ops.sptrlto_set_dma_debug = + target_if_spectral_set_dma_debug; + tx_ops->sptrl_tx_ops.sptrlto_check_and_do_dbr_ring_debug = + target_if_spectral_check_and_do_dbr_ring_debug; + tx_ops->sptrl_tx_ops.sptrlto_check_and_do_dbr_buff_debug = + target_if_spectral_check_and_do_dbr_buff_debug; +} +#else +static inline void +target_if_sptrl_debug_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) +{ +} +#endif + void target_if_sptrl_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) { @@ -3940,7 +4212,10 @@ target_if_sptrl_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) tx_ops->sptrl_tx_ops.sptrlto_deregister_netlink_cb = target_if_deregister_netlink_cb; tx_ops->sptrl_tx_ops.sptrlto_process_spectral_report = - target_if_process_spectral_report; + target_if_process_spectral_report; + tx_ops->sptrl_tx_ops.sptrlto_direct_dma_support = + target_if_spectral_direct_dma_support; + target_if_sptrl_debug_register_tx_ops(tx_ops); } qdf_export_symbol(target_if_sptrl_register_tx_ops); diff --git a/target_if/spectral/target_if_spectral.h b/target_if/spectral/target_if_spectral.h index 199ba1a1cc..73e9aae97c 100644 --- a/target_if/spectral/target_if_spectral.h +++ b/target_if/spectral/target_if_spectral.h @@ -87,6 +87,9 @@ #define SPECTRAL_PARAM_RPT_MODE_MIN (0) #define SPECTRAL_PARAM_RPT_MODE_MAX (3) +/* DBR ring debug size for Spectral */ +#define SPECTRAL_DBR_RING_DEBUG_SIZE 512 + #ifdef BIG_ENDIAN_HOST #define SPECTRAL_MESSAGE_COPY_CHAR_ARRAY(destp, srcp, len) do { \ int j; \ @@ -837,6 +840,7 @@ struct spectral_param_properties { * @timestamp_war_offset: Offset to be added to correct timestamp * @dbr_ring_debug: Whether Spectral DBR ring debug is enabled * @dbr_buff_debug: Whether Spectral DBR buffer debug is enabled + * @direct_dma_support: Whether Direct-DMA is supported on the current radio */ struct target_if_spectral { struct wlan_objmgr_pdev *pdev_obj; @@ -953,6 +957,7 @@ struct target_if_spectral { uint16_t fft_size_max; bool dbr_ring_debug; bool dbr_buff_debug; + bool direct_dma_support; }; /** diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h index 32b2751959..ff54bd9ca4 100644 --- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h +++ b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h @@ -514,6 +514,12 @@ struct wmi_spectral_cmd_ops; * @sptrlto_use_nl_bcast: Get whether to use Netlink broadcast/unicast * @sptrlto_deregister_netlink_cb: De-register Spectral Netlink callbacks * @sptrlto_process_spectral_report: Process spectral report + * @sptrlto_set_dma_debug: Set DMA debug for Spectral + * @sptrlto_direct_dma_support: Whether Direct-DMA is supported on this radio + * @sptrlto_check_and_do_dbr_ring_debug: Start/Stop Spectral ring debug based + * on the previous state + * @sptrlto_check_and_do_dbr_buff_debug: Start/Stop Spectral buffer debug based + * on the previous state **/ struct wlan_lmac_if_sptrl_tx_ops { void *(*sptrlto_pdev_spectral_init)(struct wlan_objmgr_pdev *pdev); @@ -560,6 +566,16 @@ struct wlan_lmac_if_sptrl_tx_ops { int (*sptrlto_process_spectral_report)( struct wlan_objmgr_pdev *pdev, void *payload); + QDF_STATUS (*sptrlto_set_dma_debug)( + struct wlan_objmgr_pdev *pdev, + enum spectral_dma_debug dma_debug_type, + bool dma_debug_enable); + bool (*sptrlto_direct_dma_support)(struct wlan_objmgr_pdev *pdev); + QDF_STATUS (*sptrlto_check_and_do_dbr_ring_debug)( + struct wlan_objmgr_pdev *pdev); + QDF_STATUS (*sptrlto_check_and_do_dbr_buff_debug)( + struct wlan_objmgr_pdev *pdev); + }; #endif /* WLAN_CONV_SPECTRAL_ENABLE */ @@ -627,7 +643,7 @@ struct wlan_lmac_if_direct_buf_rx_tx_ops { QDF_STATUS (*direct_buf_rx_stop_buffer_poisoning)( struct wlan_objmgr_pdev *pdev, uint8_t mod_id); }; -#endif +#endif /* DIRECT_BUF_RX_ENABLE */ #ifdef FEATURE_WLAN_TDLS /* fwd declarations for tdls tx ops */