commit 9475682c524b74537820eebf5c0c171f53fc1f70 Author: Vikram Kandukuri Date: Thu Jan 31 10:58:54 2019 +0530 qca-wifi: Add CFR component Add Channel Frequency Response component, This provides dispatcher and core API that can be used by other modules. Change-Id: I032b312c6b88494756a21afb5a36179bceb2f214 CRs-Fixed: 2372061 diff --git a/cfr/inc/target_if_cfr.h b/cfr/inc/target_if_cfr.h new file mode 100644 index 0000000000..6beff1357a --- /dev/null +++ b/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 +#include +#include +#include +#include + +#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/cfr/inc/target_if_cfr_8074v2.h b/cfr/inc/target_if_cfr_8074v2.h new file mode 100644 index 0000000000..2f46c0f806 --- /dev/null +++ b/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/cfr/src/target_if_cfr.c b/cfr/src/target_if_cfr.c new file mode 100644 index 0000000000..6a6f31f37b --- /dev/null +++ b/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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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/cfr/src/target_if_cfr_8074v2.c b/cfr/src/target_if_cfr_8074v2.c new file mode 100644 index 0000000000..92aa646dec --- /dev/null +++ b/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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef DIRECT_BUF_RX_ENABLE +#include +#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; +} +