Merge "qca-wifi: free nbuf on WMI command failed"
diff --git a/target_if/cfr/inc/target_if_cfr.h b/target_if/cfr/inc/target_if_cfr.h
new file mode 100644
index 0000000..6beff13
--- /dev/null
+++ b/target_if/cfr/inc/target_if_cfr.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <wlan_objmgr_cmn.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_objmgr_peer_obj.h>
+
+#define PEER_CFR_CAPTURE_ENABLE 1
+#define PEER_CFR_CAPTURE_DISABLE 0
+
+/**
+ * target_if_cfr_init_pdev() - Inits cfr pdev and registers necessary handlers.
+ * @psoc: pointer to psoc object
+ * @pdev: pointer to pdev object
+ *
+ * Return: Registration status for necessary handlers
+ */
+int target_if_cfr_init_pdev(struct wlan_objmgr_psoc *psoc,
+ struct wlan_objmgr_pdev *pdev);
+
+/**
+ * target_if_cfr_deinit_pdev() - De-inits corresponding pdev and handlers.
+ * @psoc: pointer to psoc object
+ * @pdev: pointer to pdev object
+ *
+ * Return: De-registration status for necessary handlers
+ */
+int target_if_cfr_deinit_pdev(struct wlan_objmgr_psoc *psoc,
+ struct wlan_objmgr_pdev *pdev);
+
+/**
+ * target_if_cfr_tx_ops_register() - Registers tx ops for cfr module
+ * @tx_ops - pointer to tx_ops structure.
+ */
+void target_if_cfr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops);
+
+/**
+ * target_if_cfr_enable_cfr_timer() - Enables cfr timer
+ * @pdev: pointer to pdev object
+ * @cfr_timer: Amount of time this timer has to run
+ *
+ * Return: status of timer
+ */
+int target_if_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev,
+ uint32_t cfr_timer);
+
+/**
+ * target_if_cfr_pdev_set_param() - Function to set params for cfr config
+ * @pdev: pointer to pdev object
+ * @param_id: param id which has to be set
+ * @param_value: value of param being set
+ *
+ * Return: success/failure of setting param
+ */
+int target_if_cfr_pdev_set_param(struct wlan_objmgr_pdev *pdev,
+ uint32_t param_id, uint32_t param_value);
+/**
+ * target_if_cfr_start_capture() - Function to start cfr capture for a peer
+ * @pdev: pointer to pdev object
+ * @peer: pointer to peer object
+ * @cfr_params: capture parameters for this peer
+ *
+ * Return: success/failure status of start capture
+ */
+int target_if_cfr_start_capture(struct wlan_objmgr_pdev *pdev,
+ struct wlan_objmgr_peer *peer,
+ struct cfr_capture_params *cfr_params);
+/**
+ * target_if_cfr_stop_capture() - Function to stop cfr capture for a peer
+ * @pdev: pointer to pdev object
+ * @peer: pointer to peer object
+ *
+ * Return: success/failure status of stop capture
+ */
+int target_if_cfr_stop_capture(struct wlan_objmgr_pdev *pdev,
+ struct wlan_objmgr_peer *peer);
diff --git a/target_if/cfr/inc/target_if_cfr_8074v2.h b/target_if/cfr/inc/target_if_cfr_8074v2.h
new file mode 100644
index 0000000..2f46c0f
--- /dev/null
+++ b/target_if/cfr/inc/target_if_cfr_8074v2.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+struct whal_cfir_dma_hdr {
+ uint16_t
+ // 'BA'
+ tag : 8,
+ // '02', length of header in 4 octet units
+ length : 6,
+ // 00
+ reserved : 2;
+ uint16_t
+ // [16]
+ upload_done : 1,
+ // [17:18], 0: invalid, 1: CFR, 2: CIR, 3: DebugH
+ capture_type : 3,
+ // [19:20], 0: Legacy, 1: HT, 2: VHT, 3: HE
+ preamble_type : 2,
+ // [21:23], 0: 1-stream, 1: 2-stream, ..., 7: 8-stream
+ nss : 3,
+ // [24:27], 0: invalid, 1: 1-chain, 2: 2-chain, etc.
+ num_chains : 3,
+ // [28:30], 0: 20 MHz, 1: 40 MHz, 2: 80 MHz, 3: 160 MHz
+ upload_pkt_bw : 3, // [31]
+ sw_peer_id_valid : 1;
+ uint16_t
+ sw_peer_id : 16; // [15:0]
+ uint16_t
+ phy_ppdu_id : 16; // [15:0]
+};
+
+/**
+ * cfr_8074v2_init_pdev() - Inits cfr pdev and registers necessary handlers.
+ * @psoc: pointer to psoc object
+ * @pdev: pointer to pdev object
+ *
+ * Return: Registration status for necessary handlers
+ */
+int cfr_8074v2_init_pdev(
+ struct wlan_objmgr_psoc *psoc,
+ struct wlan_objmgr_pdev *pdev);
+
+/**
+ * cfr_8074v2_deinit_pdev() - De-inits corresponding pdev and handlers.
+ * @psoc: pointer to psoc object
+ * @pdev: pointer to pdev object
+ *
+ * Return: De-registration status for necessary handlers
+ */
+int cfr_8074v2_deinit_pdev(
+ struct wlan_objmgr_psoc *psoc,
+ struct wlan_objmgr_pdev *pdev);
+
+/**
+ * target_if_register_to_dbr() - Register to Direct DMA handler
+ * @pdev: pointer to pdev object
+ *
+ * Return: Status
+ */
+QDF_STATUS
+target_if_register_to_dbr(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * target_if_register_tx_completion_event_handler()
+ * register TX completion handler
+ * @pdev: pointer to pdev object
+ *
+ * Return: Status
+ */
+int
+target_if_register_tx_completion_event_handler(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_unregister_tx_completion_event_handler
+ * unregister TX completion handler
+ * @pdev: pointer to pdev object
+ *
+ * Return: Status
+ */
+int
+target_if_unregister_tx_completion_event_handler(struct wlan_objmgr_psoc *psoc);
+
diff --git a/target_if/cfr/src/target_if_cfr.c b/target_if/cfr/src/target_if_cfr.c
new file mode 100644
index 0000000..6a6f31f
--- /dev/null
+++ b/target_if/cfr/src/target_if_cfr.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <target_if_cfr.h>
+#include <wlan_tgt_def_config.h>
+#include <target_type.h>
+#include <hif_hw_version.h>
+#include <ol_if_athvar.h>
+#include <target_if.h>
+#include <wlan_lmac_if_def.h>
+#include <wlan_osif_priv.h>
+#include <wlan_mlme_dispatcher.h>
+#include <init_deinit_lmac.h>
+#include <wlan_cfr_utils_api.h>
+#include <target_if_cfr_8074v2.h>
+
+int target_if_cfr_stop_capture(struct wlan_objmgr_pdev *pdev,
+ struct wlan_objmgr_peer *peer)
+{
+ struct peer_cfr_params param = {0};
+ struct common_wmi_handle *pdev_wmi_handle = NULL;
+ struct wlan_objmgr_vdev *vdev = {0};
+ int retv = 0;
+
+ pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
+ vdev = wlan_peer_get_vdev(peer);
+
+ qdf_mem_set(¶m, sizeof(param), 0);
+
+ param.request = PEER_CFR_CAPTURE_DISABLE;
+ param.macaddr = wlan_peer_get_macaddr(peer);
+ param.vdev_id = wlan_vdev_get_id(vdev);
+
+ retv = wmi_unified_send_peer_cfr_capture_cmd(pdev_wmi_handle, ¶m);
+
+ return retv;
+}
+
+int target_if_cfr_start_capture(struct wlan_objmgr_pdev *pdev,
+ struct wlan_objmgr_peer *peer,
+ struct cfr_capture_params *cfr_params)
+{
+ struct peer_cfr_params param = {0};
+ struct common_wmi_handle *pdev_wmi_handle = NULL;
+ struct wlan_objmgr_vdev *vdev;
+ int retv = 0;
+
+ pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
+ vdev = wlan_peer_get_vdev(peer);
+ qdf_mem_set(¶m, sizeof(param), 0);
+
+ param.request = PEER_CFR_CAPTURE_ENABLE;
+ param.macaddr = wlan_peer_get_macaddr(peer);
+ param.vdev_id = wlan_vdev_get_id(vdev);
+
+ param.periodicity = cfr_params->period;
+ param.bandwidth = cfr_params->bandwidth;
+ param.capture_method = cfr_params->method;
+
+ retv = wmi_unified_send_peer_cfr_capture_cmd(pdev_wmi_handle, ¶m);
+
+ return retv;
+}
+
+int target_if_cfr_pdev_set_param(struct wlan_objmgr_pdev *pdev,
+ uint32_t param_id, uint32_t param_value)
+{
+ struct pdev_params pparam;
+ uint32_t pdev_id;
+
+ pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
+ if (pdev_id < 0)
+ return -EINVAL;
+
+ qdf_mem_set(&pparam, sizeof(pparam), 0);
+ pparam.param_id = param_id;
+ pparam.param_value = param_value;
+
+ return wmi_unified_pdev_param_send(lmac_get_pdev_wmi_handle(pdev),
+ &pparam, pdev_id);
+}
+
+int target_if_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev,
+ uint32_t cfr_timer)
+{
+ int retval;
+
+ if (!cfr_timer) {
+ retval =
+ target_if_cfr_pdev_set_param(pdev,
+ wmi_pdev_param_per_peer_prd_cfr_enable,
+ WMI_HOST_PEER_CFR_TIMER_DISABLE);
+ } else {
+ retval =
+ target_if_cfr_pdev_set_param(pdev,
+ wmi_pdev_param_per_peer_prd_cfr_enable,
+ WMI_HOST_PEER_CFR_TIMER_ENABLE);
+ }
+
+ return retval;
+}
+
+int target_if_cfr_get_target_type(struct wlan_objmgr_psoc *psoc)
+{
+ uint32_t target_type = 0;
+ struct wlan_lmac_if_target_tx_ops *target_type_tx_ops;
+
+ target_type_tx_ops = &psoc->soc_cb.tx_ops.target_tx_ops;
+
+ if (target_type_tx_ops->tgt_get_tgt_type)
+ target_type = target_type_tx_ops->tgt_get_tgt_type(psoc);
+
+ return target_type;
+}
+
+int target_if_cfr_init_pdev(struct wlan_objmgr_psoc *psoc,
+ struct wlan_objmgr_pdev *pdev)
+{
+ if (target_if_cfr_get_target_type(psoc) == TARGET_TYPE_QCA8074V2)
+ return cfr_8074v2_init_pdev(psoc, pdev);
+ else
+ return -EINVAL;
+}
+
+int target_if_cfr_deinit_pdev(struct wlan_objmgr_psoc *psoc,
+ struct wlan_objmgr_pdev *pdev)
+{
+ if (target_if_cfr_get_target_type(psoc) == TARGET_TYPE_QCA8074V2)
+ return cfr_8074v2_deinit_pdev(psoc, pdev);
+ return 0;
+}
+
+void target_if_cfr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
+{
+ tx_ops->cfr_tx_ops.cfr_init_pdev =
+ target_if_cfr_init_pdev;
+ tx_ops->cfr_tx_ops.cfr_deinit_pdev =
+ target_if_cfr_deinit_pdev;
+ tx_ops->cfr_tx_ops.cfr_enable_cfr_timer =
+ target_if_cfr_enable_cfr_timer;
+ tx_ops->cfr_tx_ops.cfr_start_capture =
+ target_if_cfr_start_capture;
+ tx_ops->cfr_tx_ops.cfr_stop_capture =
+ target_if_cfr_stop_capture;
+}
diff --git a/target_if/cfr/src/target_if_cfr_8074v2.c b/target_if/cfr/src/target_if_cfr_8074v2.c
new file mode 100644
index 0000000..92aa646
--- /dev/null
+++ b/target_if/cfr/src/target_if_cfr_8074v2.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <target_if_cfr.h>
+#include <wlan_tgt_def_config.h>
+#include <target_type.h>
+#include <hif_hw_version.h>
+#include <ol_if_athvar.h>
+#include <target_if.h>
+#include <wlan_lmac_if_def.h>
+#include <wlan_osif_priv.h>
+#include <wlan_mlme_dispatcher.h>
+#include <init_deinit_lmac.h>
+#include <wlan_cfr_utils_api.h>
+#include <target_if_cfr_8074v2.h>
+#ifdef DIRECT_BUF_RX_ENABLE
+#include <target_if_direct_buf_rx_api.h>
+#endif
+
+#ifdef DIRECT_BUF_RX_ENABLE
+void dump_dma_hdr(struct whal_cfir_dma_hdr *dma_hdr)
+{
+ cfr_info("Tag: 0x%02x Length: %d udone: %d ctype: %d preamble: %d\n",
+ dma_hdr->tag, dma_hdr->length, dma_hdr->upload_done,
+ dma_hdr->capture_type, dma_hdr->preamble_type);
+ cfr_info("Nss: %d num_chains: %d bw: %d\n", dma_hdr->nss,
+ dma_hdr->num_chains, dma_hdr->upload_pkt_bw);
+ cfr_info("peervalid: %d peer_id: %d ppdu_id: 0x%04x\n",
+ dma_hdr->sw_peer_id_valid, dma_hdr->sw_peer_id,
+ dma_hdr->phy_ppdu_id);
+}
+
+int cfr_dbr_event_handler(struct wlan_objmgr_pdev *pdev,
+ struct direct_buf_rx_data *payload)
+{
+ uint8_t *data = payload->vaddr;
+ struct whal_cfir_dma_hdr dma_hdr = {0};
+
+ if ((!pdev) || (!payload)) {
+ cfr_err("%s Error!! pdev or payload is null\n", __func__);
+ return -EINVAL;
+ }
+
+ qdf_mem_copy(&dma_hdr, &data[0], sizeof(struct whal_cfir_dma_hdr));
+ dump_dma_hdr(&dma_hdr);
+
+ return 0;
+}
+#endif
+
+static int
+target_if_peer_capture_event(ol_scn_t sc, u_int8_t *data, u_int32_t datalen)
+{
+ return 0;
+}
+
+int
+target_if_register_tx_completion_event_handler(struct wlan_objmgr_psoc *psoc)
+{
+ /* Register completion handler here */
+ return 0;
+}
+
+int
+target_if_unregister_tx_completion_event_handler(struct wlan_objmgr_psoc *psoc)
+{
+ /* UnRegister completion hoandler here */
+ return 0;
+}
+
+#ifdef DIRECT_BUF_RX_ENABLE
+QDF_STATUS
+target_if_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;
+
+ psoc = wlan_pdev_get_psoc(pdev);
+ dbr_tx_ops = &psoc->soc_cb.tx_ops.dbr_tx_ops;
+ if (dbr_tx_ops->direct_buf_rx_module_register) {
+ return dbr_tx_ops->direct_buf_rx_module_register
+ (pdev, DBR_MODULE_CFR,
+ cfr_dbr_event_handler);
+ }
+
+ return QDF_STATUS_SUCCESS;
+}
+#else
+QDF_STATUS
+target_if_cfr_register_to_dbr(struct wlan_objmgr_pdev *pdev)
+{
+ return QDF_STATUS_SUCCESS;
+}
+#endif
+
+int cfr_8074v2_init_pdev(
+ struct wlan_objmgr_psoc *psoc,
+ struct wlan_objmgr_pdev *pdev)
+{
+ int status;
+
+ status = target_if_register_to_dbr(pdev);
+ status = target_if_register_tx_completion_event_handler(psoc);
+
+ return status;
+}
+
+int cfr_8074v2_deinit_pdev(
+ struct wlan_objmgr_psoc *psoc,
+ struct wlan_objmgr_pdev *pdev)
+{
+ int status;
+
+ status = target_if_unregister_tx_complection_event_handler(pdev);
+ return status;
+}
+
diff --git a/umac/cfr/core/inc/cfr_defs_i.h b/umac/cfr/core/inc/cfr_defs_i.h
new file mode 100644
index 0000000..f7aabe5
--- /dev/null
+++ b/umac/cfr/core/inc/cfr_defs_i.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _CFR_DEFS_I_H_
+#define _CFR_DEFS_I_H_
+
+#include <wlan_objmgr_cmn.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_objmgr_peer_obj.h>
+#include <qdf_list.h>
+#include <qdf_timer.h>
+#include <qdf_util.h>
+#include <qdf_types.h>
+#include <wlan_cfr_utils_api.h>
+
+#define cfr_log(level, args...) \
+QDF_TRACE(QDF_MODULE_ID_CFR, level, ##args)
+
+#define cfr_log_fl(level, format, args...) cfr_log(level, FL(format), ## args)
+
+#define cfr_err(format, args...) \
+ cfr_log_fl(QDF_TRACE_LEVEL_ERROR, format, ## args)
+#define cfr_info(format, args...) \
+ cfr_log_fl(QDF_TRACE_LEVEL_INFO, format, ## args)
+#define cfr_debug(format, args...) \
+ cfr_log_fl(QDF_TRACE_LEVEL_DEBUG, format, ## args)
+
+/**
+ * wlan_cfr_psoc_obj_create_handler() - psoc object create handler for cfr
+ * @psoc - pointer to psoc object
+ * @args - void pointer in case it needs arguments
+ *
+ * Return: status of object creation
+ */
+QDF_STATUS
+wlan_cfr_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ * wlan_cfr_psoc_obj_destroy_handler() - psoc object destroy handler for cfr
+ * @psoc - pointer to psoc object
+ * @args - void pointer in case it needs arguments
+ *
+ * Return: status of destroy object
+ */
+QDF_STATUS
+wlan_cfr_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ * wlan_cfr_pdev_obj_create_handler() - pdev object create handler for cfr
+ * @pdev - pointer to pdev object
+ * @args - void pointer in case it needs arguments
+ *
+ * Return: status of object creation
+ */
+QDF_STATUS
+wlan_cfr_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg);
+
+/**
+ * wlan_cfr_pdev_obj_destroy_handler() - pdev object destroy handler for cfr
+ * @pdev - pointer to pdev object
+ * @args - void pointer in case it needs arguments
+ *
+ * Return: status of destroy object
+ */
+QDF_STATUS
+wlan_cfr_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev, void *arg);
+
+/**
+ * wlan_cfr_peer_obj_create_handler() - peer object create handler for cfr
+ * @peer - pointer to peer object
+ * @args - void pointer in case it needs arguments
+ *
+ * Return: status of object creation
+ */
+QDF_STATUS
+wlan_cfr_peer_obj_create_handler(struct wlan_objmgr_peer *peer, void *arg);
+
+/**
+ * wlan_cfr_peer_obj_destroy_handler() - peer object destroy handler for cfr
+ * @peer - pointer to peer object
+ * @args - void pointer in case it needs arguments
+ *
+ * Return: status ofi destry object
+ */
+QDF_STATUS
+wlan_cfr_peer_obj_destroy_handler(struct wlan_objmgr_peer *peer, void *arg);
+#endif
diff --git a/umac/cfr/core/src/cfr_common.c b/umac/cfr/core/src/cfr_common.c
new file mode 100644
index 0000000..9e04f4f
--- /dev/null
+++ b/umac/cfr/core/src/cfr_common.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <cfr_defs_i.h>
+#include <qdf_types.h>
+#include <osif_private.h>
+#include <wlan_osif_priv.h>
+
+QDF_STATUS
+wlan_cfr_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+ /* CFR is per pdev; psoc doesn't contain any private object for now */
+ struct psoc_cfr *cfr_sc = NULL;
+
+ cfr_sc = (struct psoc_cfr *)qdf_mem_malloc(sizeof(struct psoc_cfr));
+ if (NULL == cfr_sc) {
+ cfr_err("Failed to allocate cfr_ctx object\n");
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ cfr_sc->psoc_obj = psoc;
+ cfr_sc->is_cfr_capable = 1;
+
+ wlan_objmgr_psoc_component_obj_attach(psoc, WLAN_UMAC_COMP_CFR,
+ (void *)cfr_sc,
+ QDF_STATUS_SUCCESS);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_cfr_psoc_obj_destroy_handler(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+ struct psoc_cfr *cfr_sc = NULL;
+
+ cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+ WLAN_UMAC_COMP_CFR);
+ if (NULL != cfr_sc) {
+ wlan_objmgr_psoc_component_obj_detach(psoc, WLAN_UMAC_COMP_CFR,
+ (void *)cfr_sc);
+ qdf_mem_free(cfr_sc);
+ }
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_cfr_pdev_obj_create_handler(struct wlan_objmgr_pdev *pdev, void *arg)
+{
+ struct pdev_cfr *pa = NULL;
+
+ if (NULL == pdev) {
+ cfr_err("PDEV is NULL\n");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ pa = (struct pdev_cfr *)qdf_mem_malloc(sizeof(struct pdev_cfr));
+ if (NULL == pa) {
+ cfr_err("Failed to allocate pdev_cfr object\n");
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ qdf_mem_zero(pa, sizeof(struct pdev_cfr));
+ pa->pdev_obj = pdev;
+ pa->is_cfr_capable = 1; /* derive for WMI Service ready capable */
+ pa->cfr_timer_enable = 0;
+
+ wlan_objmgr_pdev_component_obj_attach(pdev, WLAN_UMAC_COMP_CFR,
+ (void *)pa, QDF_STATUS_SUCCESS);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_cfr_pdev_obj_destroy_handler(struct wlan_objmgr_pdev *pdev, void *arg)
+{
+ struct pdev_cfr *pa = NULL;
+
+ if (NULL == pdev) {
+ cfr_err("PDEV is NULL\n");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
+ if (NULL != pa) {
+ wlan_objmgr_pdev_component_obj_detach(pdev, WLAN_UMAC_COMP_CFR,
+ (void *)pa);
+ qdf_mem_free(pa);
+ }
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_cfr_peer_obj_create_handler(struct wlan_objmgr_peer *peer, void *arg)
+{
+ struct peer_cfr *pe = NULL;
+
+ if (NULL == peer) {
+ cfr_err("PEER is NULL\n");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ pe = (struct peer_cfr *)qdf_mem_malloc(sizeof(struct peer_cfr));
+ if (NULL == pe) {
+ cfr_err("Failed to allocate peer_cfr object\n");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ qdf_mem_zero(pe, sizeof(struct peer_cfr));
+ pe->peer_obj = peer;
+
+ /* Remaining will be populated when we give CFR capture command */
+ wlan_objmgr_peer_component_obj_attach(peer, WLAN_UMAC_COMP_CFR,
+ (void *)pe, QDF_STATUS_SUCCESS);
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_cfr_peer_obj_destroy_handler(struct wlan_objmgr_peer *peer, void *arg)
+{
+ struct peer_cfr *pe = NULL;
+
+ if (NULL == peer) {
+ cfr_err("PEER is NULL\n");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR);
+ if (NULL != pe) {
+ wlan_objmgr_peer_component_obj_detach(peer, WLAN_UMAC_COMP_CFR,
+ (void *)pe);
+ qdf_mem_free(pe);
+ }
+
+ return QDF_STATUS_SUCCESS;
+}
diff --git a/umac/cfr/dispatcher/inc/wlan_cfr_tgt_api.h b/umac/cfr/dispatcher/inc/wlan_cfr_tgt_api.h
new file mode 100644
index 0000000..af796ad
--- /dev/null
+++ b/umac/cfr/dispatcher/inc/wlan_cfr_tgt_api.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _WLAN_CFR_TGT_API_H_
+#define _WLAN_CFR_TGT_API_H_
+
+#include <wlan_objmgr_peer_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_objmgr_cmn.h>
+#include <qdf_types.h>
+
+/* tgt layer has APIs in application, to access functions in target
+ * through tx_ops.
+ */
+
+/**
+ * tgt_cfr_init_pdev() - API that registers CFR to handlers.
+ * @pdev: pointer to pdev_object
+ *
+ * Return: success/failure of init
+ */
+int tgt_cfr_init_pdev(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * tgt_cfr_deinit_pdev() - API that de-registers CFR to handlers.
+ * @pdev: pointer to pdev_object
+ *
+ * Return: success/failure of de-init
+ */
+int tgt_cfr_deinit_pdev(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * tgt_cfr_get_target_type() - API to determine target type.
+ * @psoc: pointer to psoc_object
+ *
+ * Return: enum value of target type
+ */
+int tgt_cfr_get_target_type(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * tgt_cfr_start_capture() - API to start cfr capture on a peer.
+ * @pdev: pointer to pdev_object
+ * @peer: pointer to peer_object
+ * @cfr_params: pointer to config cfr_params
+ *
+ * Return: success/failure of start capture
+ */
+int tgt_cfr_start_capture(struct wlan_objmgr_pdev *pdev,
+ struct wlan_objmgr_peer *peer,
+ struct cfr_capture_params *cfr_params);
+
+/**
+ * tgt_cfr_stop_capture() - API to stop cfr capture on a peer.
+ * @pdev: pointer to pdev_object
+ * @peer: pointer to peer_object
+ *
+ * Return: success/failure of stop capture
+ */
+int tgt_cfr_stop_capture(struct wlan_objmgr_pdev *pdev,
+ struct wlan_objmgr_peer *peer);
+
+/**
+ * tgt_cfr_enable_cfr_timer() - API to enable cfr timer
+ * @pdev: pointer to pdev_object
+ * @cfr_timer: Amount of time this timer has to run. If 0, it disables timer.
+ *
+ * Return: success/failure of init
+ */
+void
+tgt_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev, uint32_t cfr_timer);
+#endif
diff --git a/umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h b/umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h
new file mode 100644
index 0000000..dadb980
--- /dev/null
+++ b/umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _WLAN_CFR_UCFG_API_H_
+#define _WLAN_CFR_UCFG_API_H_
+
+#include <wlan_objmgr_peer_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+
+/**
+ * ucfg_cfr_start_capture() - function to start cfr capture
+ * @pdev: pointer to pdev object
+ * @peer: pointer to peer object
+ * @cfr_params: config params to cfr capture
+ *
+ * Return: startus of start capture.
+ */
+int ucfg_cfr_start_capture(struct wlan_objmgr_pdev *pdev,
+ struct wlan_objmgr_peer *peer,
+ struct cfr_capture_params *cfr_params);
+
+/**
+ * ucfg_cfr_stop_capture() - function to stop cfr capture
+ * @pdev: pointer to pdev object
+ * @peer: pointer to peer object
+ *
+ * Return: startus of stop capture.
+ */
+int ucfg_cfr_stop_capture(struct wlan_objmgr_pdev *pdev,
+ struct wlan_objmgr_peer *peer);
+
+/**
+ * ucfg_cfr_list_peers() - Lists total number of peers with cfr capture enabled
+ * @pdev: pointer to pdev object
+ *
+ * Return: number of peers with cfr capture enabled
+ */
+int ucfg_cfr_list_peers(struct wlan_objmgr_pdev *pdev);
+#endif
diff --git a/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h b/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h
new file mode 100644
index 0000000..ffc7715
--- /dev/null
+++ b/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _WLAN_CFR_UTILS_API_H_
+#define _WLAN_CFR_UTILS_API_H_
+#include <wlan_objmgr_cmn.h>
+
+/**
+ * struct cfr_capture_params - structure to store cfr config param
+ * bandwidth: bandwitdh of capture
+ * period: period of capture
+ * method: enum of method being followed to capture cfr data. 0-QoS null data
+ */
+struct cfr_capture_params {
+ u_int8_t bandwidth;
+ u_int32_t period;
+ u_int8_t method;
+};
+
+/**
+ * struct psoc_cfr - private psoc object for cfr
+ * psoc_obj: pointer to psoc object
+ * is_cfr_capable: flag to determine if cfr is enabled or not
+ */
+struct psoc_cfr {
+ struct wlan_objmgr_psoc *psoc_obj;
+ uint8_t is_cfr_capable;
+};
+
+/**
+ * struct pdev_cfr - private pdev object for cfr
+ * pdev_obj: pointer to pdev object
+ * is_cfr_capable: flag to determine if cfr is enabled or not
+ * cfr_timer_enable: flag to enable/disable timer
+ */
+/*
+ * To be extended if we get more capbality info
+ * from FW's extended service ready event.
+ */
+struct pdev_cfr {
+ struct wlan_objmgr_pdev *pdev_obj;
+ uint8_t is_cfr_capable;
+ uint8_t cfr_timer_enable;
+ /*
+ * RealyFS data stucts can be here
+ * or add RealyFS object speperately per pdev
+ */
+
+ /*
+ * More fileds will come for data interface
+ * to stitch Tx completion & D-DMA completions
+ */
+};
+
+/**
+ * struct peer_cfr - private peer object for cfr
+ * peer_obj: pointer to peer_obj
+ * request: Type of request (start/stop)
+ * bandwidth: bandwitdth of capture for this peer
+ * capture_method: enum determining type of cfr data capture.
+ * 0-Qos null data
+ */
+struct peer_cfr {
+ struct wlan_objmgr_peer *peer_obj;
+ u_int8_t request; /* start/stop */
+ u_int8_t bandwidth;
+ u_int32_t period;
+ u_int8_t capture_method;
+};
+
+/**
+ * wlan_cfr_init() - Global init for cfr.
+ *
+ * Return: status of global init pass/fail
+ */
+QDF_STATUS wlan_cfr_init(void);
+
+/**
+ * wlan_cfr_deinit() - Global de-init for cfr.
+ *
+ * Return: status of global de-init pass/fail
+ */
+QDF_STATUS wlan_cfr_deinit(void);
+
+/**
+ * wlan_cfr_pdev_open() - pdev_open function for cfr.
+ * @pdev: pointer to pdev object
+ *
+ * Return: status of pdev_open pass/fail
+ */
+QDF_STATUS wlan_cfr_pdev_open(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * wlan_cfr_pdev_close() - pdev_close function for cfr.
+ * @pdev: pointer to pdev object
+ *
+ * Return: status of pdev_close pass/fail
+ */
+QDF_STATUS wlan_cfr_pdev_close(struct wlan_objmgr_pdev *pdev);
+#endif
diff --git a/umac/cfr/dispatcher/src/wlan_cfr_tgt_api.c b/umac/cfr/dispatcher/src/wlan_cfr_tgt_api.c
new file mode 100644
index 0000000..df8544d
--- /dev/null
+++ b/umac/cfr/dispatcher/src/wlan_cfr_tgt_api.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Layer b/w umac and target_if (ol) txops
+ * It contains wrapers for txops
+ */
+
+#include <wlan_cfr_tgt_api.h>
+#include <wlan_cfr_utils_api.h>
+#include <target_type.h>
+
+static inline struct wlan_lmac_if_cfr_tx_ops *
+ wlan_psoc_get_cfr_txops(struct wlan_objmgr_psoc *psoc)
+{
+ return &((psoc->soc_cb.tx_ops.cfr_tx_ops));
+}
+
+int tgt_cfr_get_target_type(struct wlan_objmgr_psoc *psoc)
+{
+ uint32_t target_type = 0;
+ struct wlan_lmac_if_target_tx_ops *target_type_tx_ops;
+
+ target_type_tx_ops = &psoc->soc_cb.tx_ops.target_tx_ops;
+
+ if (target_type_tx_ops->tgt_get_tgt_type)
+ target_type = target_type_tx_ops->tgt_get_tgt_type(psoc);
+
+ return target_type;
+}
+
+int tgt_cfr_init_pdev(struct wlan_objmgr_pdev *pdev)
+{
+ struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL;
+ int status = 0;
+ struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+
+ cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc);
+
+ if (cfr_tx_ops->cfr_init_pdev)
+ status = cfr_tx_ops->cfr_init_pdev(psoc, pdev);
+
+ if (status != 0)
+ cfr_err("Error occurred with exit code %d\n", status);
+
+ return status;
+}
+
+int tgt_cfr_deinit_pdev(struct wlan_objmgr_pdev *pdev)
+{
+ struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL;
+ int status = 0;
+ struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+
+ cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc);
+
+ if (cfr_tx_ops->cfr_deinit_pdev)
+ status = cfr_tx_ops->cfr_deinit_pdev(psoc, pdev);
+
+ if (status != 0)
+ cfr_err("Error occurred with exit code %d\n", status);
+
+ return status;
+}
+
+int tgt_cfr_start_capture(struct wlan_objmgr_pdev *pdev,
+ struct wlan_objmgr_peer *peer,
+ struct cfr_capture_params *cfr_params)
+{
+ struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL;
+ int status = 0;
+ struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+
+ cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc);
+
+ if (cfr_tx_ops->cfr_start_capture)
+ status = cfr_tx_ops->cfr_start_capture(pdev, peer, cfr_params);
+
+ if (status != 0)
+ cfr_err("Error occurred with exit code %d\n", status);
+
+ return status;
+}
+
+int tgt_cfr_stop_capture(struct wlan_objmgr_pdev *pdev,
+ struct wlan_objmgr_peer *peer)
+{
+ struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL;
+ int status;
+ struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+
+ cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc);
+
+ if (cfr_tx_ops->cfr_stop_capture)
+ status = cfr_tx_ops->cfr_stop_capture(pdev, peer);
+
+ if (status != 0)
+ cfr_err("Error occurred with exit code %d\n", status);
+
+ return status;
+}
+
+void
+tgt_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev, uint32_t cfr_timer)
+{
+ struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL;
+ struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+
+ cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc);
+
+ if (cfr_tx_ops->cfr_enable_cfr_timer)
+ cfr_tx_ops->cfr_enable_cfr_timer(pdev, cfr_timer);
+}
diff --git a/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c b/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c
new file mode 100644
index 0000000..778564b
--- /dev/null
+++ b/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <wlan_cfr_ucfg_api.h>
+#include "../../core/inc/cfr_defs_i.h"
+#include <wlan_cfr_utils_api.h>
+#include <wlan_cfr_tgt_api.h>
+#include <wlan_objmgr_peer_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+
+int ucfg_cfr_start_capture(struct wlan_objmgr_pdev *pdev,
+ struct wlan_objmgr_peer *peer,
+ struct cfr_capture_params *params)
+{
+ struct pdev_cfr *pa;
+ struct peer_cfr *pe;
+
+ if (NULL == pdev) {
+ cfr_err("PDEV is NULL!\n");
+ return -EINVAL;
+ }
+ pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
+ if (NULL == pa) {
+ cfr_err("PDEV cfr object is NULL!\n");
+ return -EINVAL;
+ }
+
+ /* Get peer private object */
+ pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR);
+ if (NULL == pe) {
+ cfr_err("PEER cfr object is NULL!\n");
+ return -EINVAL;
+ }
+ pe->bandwidth = params->bandwidth;
+ pe->period = params->period;
+ pe->capture_method = params->method;
+
+ return tgt_cfr_start_capture(pdev, peer, params);
+}
+
+int ucfg_cfr_stop_capture(struct wlan_objmgr_pdev *pdev,
+ struct wlan_objmgr_peer *peer)
+{
+ if (NULL == pdev) {
+ cfr_err("pdev is null!\n");
+ return -EINVAL;
+ }
+
+ if (NULL == peer) {
+ cfr_err("peer is null!\n");
+ return -EINVAL;
+ }
+
+ return tgt_cfr_stop_capture(pdev, peer);
+}
+
+int ucfg_cfr_list_peers(struct wlan_objmgr_pdev *pdev)
+{
+ return 0;
+}
diff --git a/umac/cfr/dispatcher/src/wlan_cfr_utils_api.c b/umac/cfr/dispatcher/src/wlan_cfr_utils_api.c
new file mode 100644
index 0000000..cc734c2
--- /dev/null
+++ b/umac/cfr/dispatcher/src/wlan_cfr_utils_api.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 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
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <wlan_cfr_utils_api.h>
+#include <wlan_cfr_tgt_api.h>
+#include <qdf_module.h>
+#include "../../core/inc/cfr_defs_i.h"
+#include <wlan_objmgr_global_obj.h>
+
+QDF_STATUS wlan_cfr_init(void)
+{
+ if (wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_CFR,
+ wlan_cfr_psoc_obj_create_handler, NULL)
+ != QDF_STATUS_SUCCESS) {
+ return QDF_STATUS_E_FAILURE;
+ }
+ if (wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_CFR,
+ wlan_cfr_psoc_obj_destroy_handler, NULL)
+ != QDF_STATUS_SUCCESS) {
+ return QDF_STATUS_E_FAILURE;
+ }
+ if (wlan_objmgr_register_pdev_create_handler(WLAN_UMAC_COMP_CFR,
+ wlan_cfr_pdev_obj_create_handler, NULL)
+ != QDF_STATUS_SUCCESS) {
+ return QDF_STATUS_E_FAILURE;
+ }
+ if (wlan_objmgr_register_pdev_destroy_handler(WLAN_UMAC_COMP_CFR,
+ wlan_cfr_pdev_obj_destroy_handler, NULL)
+ != QDF_STATUS_SUCCESS) {
+ return QDF_STATUS_E_FAILURE;
+ }
+ if (wlan_objmgr_register_peer_create_handler(WLAN_UMAC_COMP_CFR,
+ wlan_cfr_peer_obj_create_handler, NULL)
+ != QDF_STATUS_SUCCESS) {
+ return QDF_STATUS_E_FAILURE;
+ }
+ if (wlan_objmgr_register_peer_destroy_handler(WLAN_UMAC_COMP_CFR,
+ wlan_cfr_peer_obj_destroy_handler, NULL)
+ != QDF_STATUS_SUCCESS) {
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_cfr_deinit(void)
+{
+ if (wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_CFR,
+ wlan_cfr_psoc_obj_create_handler, NULL)
+ != QDF_STATUS_SUCCESS) {
+ return QDF_STATUS_E_FAILURE;
+ }
+ if (wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_CFR,
+ wlan_cfr_psoc_obj_destroy_handler, NULL)
+ != QDF_STATUS_SUCCESS) {
+ return QDF_STATUS_E_FAILURE;
+ }
+ if (wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_CFR,
+ wlan_cfr_pdev_obj_create_handler, NULL)
+ != QDF_STATUS_SUCCESS) {
+ return QDF_STATUS_E_FAILURE;
+ }
+ if (wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_CFR,
+ wlan_cfr_pdev_obj_destroy_handler, NULL)
+ != QDF_STATUS_SUCCESS) {
+ return QDF_STATUS_E_FAILURE;
+ }
+ if (wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_CFR,
+ wlan_cfr_peer_obj_create_handler, NULL)
+ != QDF_STATUS_SUCCESS) {
+ return QDF_STATUS_E_FAILURE;
+ }
+ if (wlan_objmgr_unregister_peer_destroy_handler(WLAN_UMAC_COMP_CFR,
+ wlan_cfr_peer_obj_destroy_handler, NULL)
+ != QDF_STATUS_SUCCESS) {
+ return QDF_STATUS_E_FAILURE;
+ }
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_cfr_pdev_open(struct wlan_objmgr_pdev *pdev)
+{
+ int status = QDF_STATUS_SUCCESS;
+
+ status = tgt_cfr_init_pdev(pdev);
+
+ return status;
+}
+
+QDF_STATUS wlan_cfr_pdev_close(struct wlan_objmgr_pdev *pdev)
+{
+ int status = QDF_STATUS_SUCCESS;
+ /*
+ * DBR does not have close as of now;
+ * but this is getting added as part for new gerrit
+ * Once we have that support we will add it.
+ */
+ status = tgt_cfr_deinit_pdev(pdev);
+
+ return status;
+}
diff --git a/wmi/inc/wmi_unified_ap_api.h b/wmi/inc/wmi_unified_ap_api.h
index a79dcc7..6f12628 100644
--- a/wmi/inc/wmi_unified_ap_api.h
+++ b/wmi/inc/wmi_unified_ap_api.h
@@ -124,6 +124,10 @@
QDF_STATUS wmi_extract_swba_tim_info(void *wmi_hdl, void *evt_buf,
uint32_t idx, wmi_host_tim_info *tim_info);
+QDF_STATUS wmi_extract_swba_quiet_info(void *wmi_hdl, void *evt_buf,
+ uint32_t idx,
+ wmi_host_quiet_info *quiet_info);
+
QDF_STATUS wmi_extract_swba_noa_info(void *wmi_hdl, void *evt_buf,
uint32_t idx, wmi_host_p2p_noa_info *p2p_desc);
diff --git a/wmi/src/wmi_unified_ap_api.c b/wmi/src/wmi_unified_ap_api.c
index 7dfd058..701c27f 100644
--- a/wmi/src/wmi_unified_ap_api.c
+++ b/wmi/src/wmi_unified_ap_api.c
@@ -494,6 +494,28 @@
}
/**
+ * wmi_extract_swba_quiet_info() - extract swba quiet info from event
+ * @wmi_handle: wmi handle
+ * @param evt_buf: pointer to event buffer
+ * @param idx: Index to bcn info
+ * @param quiet_info: Pointer to hold quiet info
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_extract_swba_quiet_info(void *wmi_hdl, void *evt_buf,
+ uint32_t idx,
+ wmi_host_quiet_info *quiet_info)
+{
+ wmi_unified_t wmi_handle = (wmi_unified_t)wmi_hdl;
+
+ if (wmi_handle->ops->extract_swba_quiet_info)
+ return wmi_handle->ops->extract_swba_quiet_info(wmi_handle,
+ evt_buf, idx,
+ quiet_info);
+ return QDF_STATUS_E_FAILURE;
+}
+
+/**
* wmi_extract_swba_noa_info() - extract swba NoA information from event
* @wmi_handle: wmi handle
* @param evt_buf: pointer to event buffer
diff --git a/wmi/src/wmi_unified_ap_tlv.c b/wmi/src/wmi_unified_ap_tlv.c
index 58ef9e0..5a372b9 100644
--- a/wmi/src/wmi_unified_ap_tlv.c
+++ b/wmi/src/wmi_unified_ap_tlv.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-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
@@ -1110,13 +1110,15 @@
tim_info_ev = ¶m_buf->tim_info[idx];
- tim_info->tim_len = tim_info_ev->tim_len;
- tim_info->tim_mcast = tim_info_ev->tim_mcast;
- qdf_mem_copy(tim_info->tim_bitmap, tim_info_ev->tim_bitmap,
- (sizeof(uint32_t) * WMI_TIM_BITMAP_ARRAY_SIZE));
- tim_info->tim_changed = tim_info_ev->tim_changed;
- tim_info->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending;
- tim_info->vdev_id = tim_info_ev->vdev_id;
+ if (tim_info_ev->tim_len != 0) {
+ tim_info->tim_len = tim_info_ev->tim_len;
+ tim_info->tim_mcast = tim_info_ev->tim_mcast;
+ qdf_mem_copy(tim_info->tim_bitmap, tim_info_ev->tim_bitmap,
+ (sizeof(uint32_t) * WMI_TIM_BITMAP_ARRAY_SIZE));
+ tim_info->tim_changed = tim_info_ev->tim_changed;
+ tim_info->tim_num_ps_pending = tim_info_ev->tim_num_ps_pending;
+ tim_info->vdev_id = tim_info_ev->vdev_id;
+ }
return QDF_STATUS_SUCCESS;
}
@@ -1176,6 +1178,44 @@
}
/**
+ * extract_swba_quiet_info_tlv() - extract swba quiet info from event
+ * @wmi_handle: wmi handle
+ * @param evt_buf: pointer to event buffer
+ * @param idx: Index to bcn info
+ * @param quiet_info: Pointer to hold quiet info
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS extract_swba_quiet_info_tlv(wmi_unified_t wmi_handle,
+ void *evt_buf, uint32_t idx,
+ wmi_host_quiet_info *quiet_info)
+{
+ WMI_HOST_SWBA_EVENTID_param_tlvs *param_buf;
+ wmi_quiet_offload_info *quiet_info_ev;
+
+ param_buf = (WMI_HOST_SWBA_EVENTID_param_tlvs *)evt_buf;
+ if (!param_buf) {
+ WMI_LOGE("Invalid swba event buffer");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (!param_buf->quiet_offload_info)
+ return QDF_STATUS_E_NULL_VALUE;
+
+ quiet_info_ev = ¶m_buf->quiet_offload_info[idx];
+
+ if (quiet_info_ev->tbttcount != 0) {
+ quiet_info->vdev_id = quiet_info_ev->vdev_id;
+ quiet_info->tbttcount = quiet_info_ev->tbttcount;
+ quiet_info->period = quiet_info_ev->period;
+ quiet_info->duration = quiet_info_ev->duration;
+ quiet_info->offset = quiet_info_ev->offset;
+ }
+
+ return QDF_STATUS_SUCCESS;
+}
+
+/**
* extract_offchan_data_tx_compl_param_tlv() -
* extract Offchan data tx completion event params
* @wmi_handle: wmi handle
@@ -2674,6 +2714,7 @@
extract_ext_tbttoffset_num_vdevs_tlv;
ops->extract_swba_num_vdevs = extract_swba_num_vdevs_tlv;
ops->extract_swba_tim_info = extract_swba_tim_info_tlv;
+ ops->extract_swba_quiet_info = extract_swba_quiet_info_tlv;
ops->extract_swba_noa_info = extract_swba_noa_info_tlv;
ops->extract_offchan_data_tx_compl_param =
extract_offchan_data_tx_compl_param_tlv;