qcacmn: Add CFR feature support

Add CFR feature support for WIN and MCL.

Change-Id: I135409c00df953ad7ae4e570418403b11ebc1bc7
CRs-Fixed: 2639069
This commit is contained in:
Padma Raghunathan 2020-03-03 10:46:56 +05:30 • committed by nshrivas
commit 9946d36d19
12 changed files with 5532 additions and 0 deletions

View file

@ -0,0 +1,167 @@
/*
* 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 _TARGET_IF_CFR_H_
#define _TARGET_IF_CFR_H_
#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>
#include "wmi_unified_cfr_api.h"
#include "wmi_unified_param.h"
#include "wmi_unified_cfr_param.h"
#define PEER_CFR_CAPTURE_ENABLE 1
#define PEER_CFR_CAPTURE_DISABLE 0
#define PEER_CFR_CAPTURE_EVT_STATUS_MASK 0x80000000
#define PEER_CFR_CAPTURE_EVT_PS_STATUS_MASK 0x40000000
#define CFR_TX_EVT_STATUS_MASK 0x00000003
/* Status codes used by correlate and relay function */
#define STATUS_STREAM_AND_RELEASE 0
#define STATUS_HOLD 1
#define STATUS_ERROR -1
/* Module IDs using corrlation function */
#define CORRELATE_DBR_MODULE_ID 0
/*
* HKV2 - Tx completion event for one-shot capture
* Cypress - Tx completion event for one-shot capture (or) RXTLV event for RCC
*/
#define CORRELATE_TX_EV_MODULE_ID 1
/**
* 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);
/**
* target_if_cfr_get_target_type() - Function to get target type
* @psoc: pointer to psoc object
*
* Return: target type of target
*/
int target_if_cfr_get_target_type(struct wlan_objmgr_psoc *psoc);
/**
* target_if_cfr_set_cfr_support() - Function to set cfr support
* @psoc: pointer to psoc object
* @value: value to be set
*/
void target_if_cfr_set_cfr_support(struct wlan_objmgr_psoc *psoc,
uint8_t value);
/**
* target_if_cfr_info_send() - Function to send cfr info to upper layers
* @pdev: pointer to pdev object
* @head: pointer to cfr info head
* @hlen: head len
* @data: pointer to cfr info data
* @dlen: data len
* @tail: pointer to cfr info tail
* @tlen: tail len
*/
void target_if_cfr_info_send(struct wlan_objmgr_pdev *pdev, void *head,
size_t hlen, void *data, size_t dlen, void *tail,
size_t tlen);
/**
* cfr_wifi2_0_init_pdev() - Function to init legacy pdev
* @psoc: pointer to psoc object
* @pdev: pointer to pdev object
*
* Return: success/failure status of init
*/
QDF_STATUS cfr_wifi2_0_init_pdev(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev);
/**
* cfr_wifi2_0_deinit_pdev() - Function to deinit legacy pdev
* @psoc: pointer to psoc object
* @pdev: pointer to pdev object
*
* Return: success/failure status of deinit
*/
QDF_STATUS cfr_wifi2_0_deinit_pdev(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev);
#endif

View file

@ -0,0 +1,335 @@
/*
* 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 _TARGET_IF_CFR_6018_H_
#define _TARGET_IF_CFR_6018_H_
#ifdef WLAN_ENH_CFR_ENABLE
/*
* Memory requirements :
*
* 1. DMA header :
*
* Legacy DMA header(QCA8074V2) : 2 words (length = 8 bytes)
* Enhanced DMA header(QCA6018) : Upto 16 words depending on no. of MU users
* in UL-MU-PPDU (Max length = 64 bytes)
*
* Fixed 4 words for whal_cfir_enhanced_hdr + freeze TLV
* + uplink_user_info TLV (MAX 4)
*
* mu_rx_num_users -> No. of words in CFR DMA header
* 0 -> 12 = 4 + 7(freeze TLV) + 1(for 64-bit alignment)
* 1 -> 12 = 4 + 7(freeze TLV) + 1(user1)
* 2 -> 14 = 4 + 7(freeze TLV) + 2(users 1,2) + 1(for 64-bit alignment)
* 3 -> 14 = 4 + 7(freeze TLV) + 3(users 1,2,3)
* 4 -> 16 = 4 + 7(freeze TLV) + 4(users 1,2,3,4) + 1(for 64-bit alignment)
*
*
* 2. CFR data size for max BW/Nss/Nrx
*
* Cypress : Max BW = 80 MHz
* NSS = 2
* Nrx = 2
* Size of one tone = 4 bytes
*
* a. RTT-H - 2048 bytes
*
* b. Debug-H (MIMO CFR) - 16016 bytes
*
* c. RTT-H + CIR - 10240 bytes = 2048(RTT-H) + 8192(CIR)
*/
/* Max 4 users in MU case */
#define CYP_CFR_MU_USERS 4
#define CYP_MAX_HEADER_LENGTH_WORDS 16
/* payload_len = Max(2048, 16016, 10240) = 16064 (64-bit alignment) */
#define CYP_MAX_DATA_LENGTH_BYTES 16064
/* in ms */
#define LUT_AGE_TIMER 3000
#define LUT_AGE_THRESHOLD 3000
#define NUM_LUT_ENTRIES 136
/* Max size :
* 16173 = 93 bytes(csi header) + 64 bytes(cfr header) + 16016 bytes(cfr
* payload)
*/
#define STREAMFS_MAX_SUBBUF_CYP 16173
#define STREAMFS_NUM_SUBBUF_CYP 255
/*
* @tag: ucode fills this with 0xBA
*
* @length: length of CFR header in words (32-bit)
*
* @upload_done: ucode sets this to 1 to indicate DMA completion
*
* @capture_type:
*
* 0 - None
* 1 - RTT-H (Nss = 1, Nrx)
* 2 - Debug-H (Nss, Nrx)
* 3 - Reserved
* 5 - RTT-H + CIR(Nss, Nrx)
*
* @preamble_type:
*
* 0 - Legacy
* 1 - HT
* 2 - VHT
* 3 - HE
*
* @nss:
*
* 0 - 1-stream
* 1 - 2-stream
* .. ..
* 7 - 8-stream
*
*@num_chains:
*
* 0 - 1-chain
* 1 - 2-chain
* .. ..
* 7 - 8-chain
*
*@upload_bw_pkt:
*
* 0 - 20 MHz
* 1 - 40 MHz
* 2 - 80 MHz
* 3 - 160 MHz
*
* @sw_peer_id_valid: Indicates whether sw_peer_id field is valid or not,
* sent from MAC to PHY via the MACRX_FREEZE_CAPTURE_CHANNEL TLV
*
* @sw_peer_id: Indicates peer id based on AST search, sent from MAC to PHY
* via the MACRX_FREEZE_CAPTURE_CHANNEL TLV
*
* @phy_ppdu_id: sent from PHY to MAC, copied to MACRX_FREEZE_CAPTURE_CHANNEL
* TLV
*
* @total_bytes: Total size of CFR payload (FFT bins)
*
* @header_version:
*
* 1 - HKV2/Hastings
* 2 - Cypress
*
* @target_id:
*
* 1 - Hastings
* 2 - Cypress
* 3 - Hastings Prime
* 4 - Pine
*
* @cfr_fmt:
*
* 0 - raw (32-bit format)
* 1 - compressed (24-bit format)
*
* @mu_rx_data_incl: Indicates whether CFR header contains UL-MU-MIMO info
*
* @freeze_data_incl: Indicates whether CFR header contains
* MACRX_FREEZE_CAPTURE_CHANNEL TLV
*
* @decimation_factor: FFT bins decimation
* @mu_rx_num_users: Number of users in UL-MU-PPDU
*/
struct whal_cfir_enhanced_hdr {
uint16_t tag : 8,
length : 6,
rsvd1 : 2;
uint16_t upload_done : 1,
capture_type : 3,
preamble_type : 2,
nss : 3,
num_chains : 3,
upload_pkt_bw : 3,
sw_peer_id_valid : 1;
uint16_t sw_peer_id : 16;
uint16_t phy_ppdu_id : 16;
uint16_t total_bytes;
uint16_t header_version :4,
target_id :4,
cfr_fmt :1,
rsvd2 :1,
mu_rx_data_incl :1,
freeze_data_incl:1,
rsvd3 :4;
uint16_t mu_rx_num_users :8,
decimation_factor :4,
rsvd4 :4;
uint16_t rsvd5;
};
struct macrx_freeze_capture_channel {
uint16_t freeze : 1, //[0]
capture_reason : 3, //[3:1]
packet_type : 2, //[5:4]
packet_sub_type : 4, //[9:6]
reserved : 5, //[14:10]
sw_peer_id_valid : 1; //[15]
uint16_t sw_peer_id : 16; //[15:0]
uint16_t phy_ppdu_id : 16; //[15:0]
uint16_t packet_ta_lower_16 : 16; //[15:0]
uint16_t packet_ta_mid_16 : 16; //[15:0]
uint16_t packet_ta_upper_16 : 16; //[15:0]
uint16_t packet_ra_lower_16 : 16; //[15:0]
uint16_t packet_ra_mid_16 : 16; //[15:0]
uint16_t packet_ra_upper_16 : 16; //[15:0]
uint16_t tsf_timestamp_15_0 : 16; //[15:0]
uint16_t tsf_timestamp_31_16 : 16; //[15:0]
uint16_t tsf_timestamp_47_32 : 16; //[15:0]
uint16_t tsf_timestamp_63_48 : 16; //[15:0]
uint16_t user_index : 6, //[5:0]
directed : 1, //[6]
reserved_13 : 9; //[15:7]
};
struct uplink_user_setup_info {
uint32_t bw_info_valid : 1, //[0]
uplink_receive_type : 2, //[2:1]
reserved_0a : 1, //[3]
uplink_11ax_mcs : 4, //[7:4]
ru_width : 7, //[14:8]
reserved_0b : 1, //[15]
nss : 3, //[18:16]
stream_offset : 3, //[21:19]
sta_dcm : 1, //[22]
sta_coding : 1, //[23]
ru_start_index : 7, //[30:24]
reserved_0c : 1; //[31]
};
/**
* cfr_6018_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
*/
QDF_STATUS cfr_6018_init_pdev(
struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev);
/**
* cfr_6018_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
*/
QDF_STATUS cfr_6018_deinit_pdev(
struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev);
/**
* target_if_cfr_start_lut_age_timer() - Start timer to flush aged-out LUT
* entries
* @pdev: pointer to pdev object
*
* Return: None
*/
void target_if_cfr_start_lut_age_timer(struct wlan_objmgr_pdev *pdev);
/**
* target_if_cfr_stop_lut_age_timer() - Stop timer to flush aged-out LUT
* entries
* @pdev: pointer to pdev object
*
* Return: None
*/
void target_if_cfr_stop_lut_age_timer(struct wlan_objmgr_pdev *pdev);
/**
* target_if_cfr_dump_lut_enh() - Dump all valid LUT entries
* @pdev: objmgr PDEV
*
* Return: none
*/
void target_if_cfr_dump_lut_enh(struct wlan_objmgr_pdev *pdev);
/**
* target_if_cfr_config_rcc() - Start repetitive channel capture
* @pdev: pointer to pdev object
* @rcc_param: rcc configurations
*
* Return: Success/Failure status
*/
QDF_STATUS target_if_cfr_config_rcc(struct wlan_objmgr_pdev *pdev,
struct cfr_rcc_param *rcc_param);
/**
* target_if_cfr_default_ta_ra_config() - Configure default values to all
* params(BW/NSS/TA/RA) in TA_RA mode
* @rcc_param: rcc configurations
* @allvalid: Indicates whether all TA_RA params are valid or not.
* It could be either 0 or 1.
* 1: should be sent to FW during CFR initialization
* 0: should be set, after a successful commit session.
* @reset_cfg: This bitmap is being used to determine which groups'
* parameters are needed to be reset to its default state.
*/
void target_if_cfr_default_ta_ra_config(struct cfr_rcc_param *rcc_param,
bool allvalid, uint16_t reset_cfg);
/**
* target_if_cfr_rx_tlv_process() - Process PPDU status TLVs and store info in
* lookup table
* @pdev: PDEV object
* @nbuf: ppdu info
*
* Return: none
*/
void target_if_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf);
/**
* target_if_cfr_update_global_cfg() - Update global config after a successful
* commit
* @pdev: pointer to pdev object
*
* Return: None
*/
void target_if_cfr_update_global_cfg(struct wlan_objmgr_pdev *pdev);
#else
static QDF_STATUS cfr_6018_init_pdev(
struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev)
{
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS cfr_6018_deinit_pdev(
struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev)
{
return QDF_STATUS_SUCCESS;
}
#endif
#endif

View file

@ -0,0 +1,362 @@
/*
* 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 <wlan_objmgr_pdev_obj.h>
#include <target_if_cfr_8074v2.h>
#include <target_if_cfr_6018.h>
int target_if_cfr_stop_capture(struct wlan_objmgr_pdev *pdev,
struct wlan_objmgr_peer *peer)
{
struct peer_cfr *pe;
struct peer_cfr_params param = {0};
struct wmi_unified *pdev_wmi_handle = NULL;
struct wlan_objmgr_vdev *vdev = {0};
struct pdev_cfr *pdev_cfrobj;
int retv = 0;
pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR);
if (pe == NULL)
return -EINVAL;
pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
vdev = wlan_peer_get_vdev(peer);
qdf_mem_set(&param, sizeof(param), 0);
param.request = PEER_CFR_CAPTURE_DISABLE;
param.macaddr = wlan_peer_get_macaddr(peer);
param.vdev_id = wlan_vdev_get_id(vdev);
param.periodicity = pe->period;
param.bandwidth = pe->bandwidth;
param.capture_method = pe->capture_method;
retv = wmi_unified_send_peer_cfr_capture_cmd(pdev_wmi_handle, &param);
pdev_cfrobj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
WLAN_UMAC_COMP_CFR);
if (!pdev_cfrobj) {
cfr_err("pdev object for CFR is null");
return -EINVAL;
}
cfr_err("CFR capture stats for this capture:");
cfr_err("DBR event count = %llu, Tx event count = %llu "
"Release count = %llu",
pdev_cfrobj->dbr_evt_cnt, pdev_cfrobj->tx_evt_cnt,
pdev_cfrobj->release_cnt);
pdev_cfrobj->dbr_evt_cnt = 0;
pdev_cfrobj->tx_evt_cnt = 0;
pdev_cfrobj->release_cnt = 0;
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 wmi_unified *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(&param, 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, &param);
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)
{
struct pdev_cfr *pa;
int retval;
pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
if (pa == NULL)
return QDF_STATUS_E_FAILURE;
if (!cfr_timer) {
/* disable periodic cfr capture */
retval =
target_if_cfr_pdev_set_param(pdev,
wmi_pdev_param_per_peer_prd_cfr_enable,
WMI_HOST_PEER_CFR_TIMER_DISABLE);
if (retval == QDF_STATUS_SUCCESS)
pa->cfr_timer_enable = 0;
} else {
/* enable periodic cfr capture (default base timer is 10ms ) */
retval =
target_if_cfr_pdev_set_param(pdev,
wmi_pdev_param_per_peer_prd_cfr_enable,
WMI_HOST_PEER_CFR_TIMER_ENABLE);
if (retval == QDF_STATUS_SUCCESS)
pa->cfr_timer_enable = 1;
}
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)
{
uint32_t target_type;
struct pdev_cfr *pa;
struct psoc_cfr *cfr_sc;
pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
if (pa == NULL)
return QDF_STATUS_E_FAILURE;
/* Reset unassociated entries for every init */
qdf_mem_zero(&pa->unassoc_pool[0], MAX_CFR_ENABLED_CLIENTS *
sizeof(struct unassoc_pool_entry));
cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
WLAN_UMAC_COMP_CFR);
if (cfr_sc == NULL)
return QDF_STATUS_E_FAILURE;
target_type = target_if_cfr_get_target_type(psoc);
if (target_type == TARGET_TYPE_QCA8074V2) {
pa->is_cfr_capable = cfr_sc->is_cfr_capable;
return cfr_8074v2_init_pdev(psoc, pdev);
} else if ((target_type == TARGET_TYPE_IPQ4019) ||
(target_type == TARGET_TYPE_QCA9984) ||
(target_type == TARGET_TYPE_QCA9888)) {
pa->is_cfr_capable = cfr_sc->is_cfr_capable;
return cfr_wifi2_0_init_pdev(psoc, pdev);
} else if (target_type == TARGET_TYPE_QCA6018) {
pa->is_cfr_capable = cfr_sc->is_cfr_capable;
return cfr_6018_init_pdev(psoc, pdev);
} else
return QDF_STATUS_E_NOSUPPORT;
}
int target_if_cfr_deinit_pdev(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev)
{
uint32_t target_type;
target_type = target_if_cfr_get_target_type(psoc);
if (target_type == TARGET_TYPE_QCA8074V2) {
return cfr_8074v2_deinit_pdev(psoc, pdev);
} else if ((target_type == TARGET_TYPE_IPQ4019) ||
(target_type == TARGET_TYPE_QCA9984) ||
(target_type == TARGET_TYPE_QCA9888)) {
return cfr_wifi2_0_deinit_pdev(psoc, pdev);
} else if (target_type == TARGET_TYPE_QCA6018) {
return cfr_6018_deinit_pdev(psoc, pdev);
} else
return QDF_STATUS_E_NOSUPPORT;
}
#ifdef WLAN_ENH_CFR_ENABLE
QDF_STATUS target_if_cfr_config_rcc(struct wlan_objmgr_pdev *pdev,
struct cfr_rcc_param *rcc_info)
{
QDF_STATUS status;
struct wmi_unified *pdev_wmi_handle = NULL;
pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
if (!pdev_wmi_handle) {
cfr_err("pdev_wmi_handle is null");
return QDF_STATUS_E_NULL_VALUE;
}
rcc_info->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
rcc_info->num_grp_tlvs =
count_set_bits(rcc_info->modified_in_curr_session);
status = wmi_unified_send_cfr_rcc_cmd(pdev_wmi_handle, rcc_info);
return status;
}
void target_if_cfr_default_ta_ra_config(struct cfr_rcc_param *rcc_info,
bool allvalid, uint16_t reset_cfg)
{
struct ta_ra_cfr_cfg *curr_cfg = NULL;
int grp_id;
uint8_t def_mac[QDF_MAC_ADDR_SIZE] = {0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF};
uint8_t null_mac[QDF_MAC_ADDR_SIZE] = {0, 0, 0, 0, 0, 0};
for (grp_id = 0; grp_id < MAX_TA_RA_ENTRIES; grp_id++) {
if (qdf_test_bit(grp_id, (unsigned long *)&reset_cfg)) {
curr_cfg = &rcc_info->curr[grp_id];
qdf_mem_copy(curr_cfg->tx_addr,
def_mac, QDF_MAC_ADDR_SIZE);
qdf_mem_copy(curr_cfg->tx_addr_mask,
null_mac, QDF_MAC_ADDR_SIZE);
qdf_mem_copy(curr_cfg->rx_addr,
def_mac, QDF_MAC_ADDR_SIZE);
qdf_mem_copy(curr_cfg->rx_addr_mask,
null_mac, QDF_MAC_ADDR_SIZE);
curr_cfg->bw = 0xf;
curr_cfg->nss = 0xff;
curr_cfg->mgmt_subtype_filter = 0xffff;
curr_cfg->ctrl_subtype_filter = 0xffff;
curr_cfg->data_subtype_filter = 0xffff;
if (!allvalid) {
curr_cfg->valid_ta = 0;
curr_cfg->valid_ta_mask = 0;
curr_cfg->valid_ra = 0;
curr_cfg->valid_ra_mask = 0;
curr_cfg->valid_bw_mask = 0;
curr_cfg->valid_nss_mask = 0;
curr_cfg->valid_mgmt_subtype = 0;
curr_cfg->valid_ctrl_subtype = 0;
curr_cfg->valid_data_subtype = 0;
} else {
curr_cfg->valid_ta = 1;
curr_cfg->valid_ta_mask = 1;
curr_cfg->valid_ra = 1;
curr_cfg->valid_ra_mask = 1;
curr_cfg->valid_bw_mask = 1;
curr_cfg->valid_nss_mask = 1;
curr_cfg->valid_mgmt_subtype = 1;
curr_cfg->valid_ctrl_subtype = 1;
curr_cfg->valid_data_subtype = 1;
}
}
}
}
#endif
#ifdef WLAN_ENH_CFR_ENABLE
void target_if_enh_cfr_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
{
tx_ops->cfr_tx_ops.cfr_config_rcc =
target_if_cfr_config_rcc;
tx_ops->cfr_tx_ops.cfr_start_lut_timer =
target_if_cfr_start_lut_age_timer;
tx_ops->cfr_tx_ops.cfr_stop_lut_timer =
target_if_cfr_stop_lut_age_timer;
tx_ops->cfr_tx_ops.cfr_default_ta_ra_cfg =
target_if_cfr_default_ta_ra_config;
tx_ops->cfr_tx_ops.cfr_dump_lut_enh =
target_if_cfr_dump_lut_enh;
tx_ops->cfr_tx_ops.cfr_rx_tlv_process =
target_if_cfr_rx_tlv_process;
tx_ops->cfr_tx_ops.cfr_update_global_cfg =
target_if_cfr_update_global_cfg;
}
#else
void target_if_enh_cfr_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
{
}
#endif
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;
target_if_enh_cfr_tx_ops(tx_ops);
}
void target_if_cfr_set_cfr_support(struct wlan_objmgr_psoc *psoc,
uint8_t value)
{
if (psoc->soc_cb.rx_ops.cfr_rx_ops.cfr_support_set)
psoc->soc_cb.rx_ops.cfr_rx_ops.cfr_support_set(psoc, value);
}
void target_if_cfr_info_send(struct wlan_objmgr_pdev *pdev, void *head,
size_t hlen, void *data, size_t dlen, void *tail,
size_t tlen)
{
struct wlan_objmgr_psoc *psoc;
psoc = wlan_pdev_get_psoc(pdev);
if (psoc->soc_cb.rx_ops.cfr_rx_ops.cfr_info_send)
psoc->soc_cb.rx_ops.cfr_rx_ops.cfr_info_send(pdev, head, hlen,
data, dlen, tail,
tlen);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,133 @@
/*
* 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>
/**
* 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);
/**
* cfr_streamfs_init() - stream filesystem init
* @pdev - pointer to pdev object
*
* Return: status of fs init
*/
QDF_STATUS
cfr_streamfs_init(struct wlan_objmgr_pdev *pdev);
/**
* cfr_streamfs_remove() - stream filesystem remove
* @pdev - pointer to pdev object
*
* Return: status of fs remove
*/
QDF_STATUS
cfr_streamfs_remove(struct wlan_objmgr_pdev *pdev);
/**
* cfr_streamfs_write() - write to stream filesystem
* @pa - pointer to pdev_cfr object
* @write_data - Pointer to data
* @write_len - data len
*
* Return: status of fs write
*/
QDF_STATUS
cfr_streamfs_write(struct pdev_cfr *pa, const void *write_data,
size_t write_len);
/**
* cfr_streamfs_flush() - flush the write to streamfs
* @pa - pointer to pdev_cfr object
*
* Return: status of fs flush
*/
QDF_STATUS
cfr_streamfs_flush(struct pdev_cfr *pa);
#endif

View file

@ -0,0 +1,323 @@
/*
* 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 <ol_if_athvar.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_objmgr_vdev_obj.h>
#include <wlan_objmgr_peer_obj.h>
#include <wlan_cfr_tgt_api.h>
#include <qal_streamfs.h>
#include <relay.h>
#include <debugfs.h>
#include <target_if.h>
QDF_STATUS
wlan_cfr_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg)
{
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;
}
qdf_mem_zero(cfr_sc, sizeof(struct psoc_cfr));
cfr_sc->psoc_obj = psoc;
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;
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;
}
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;
struct wlan_objmgr_vdev *vdev;
struct wlan_objmgr_pdev *pdev = NULL;
struct pdev_cfr *pa = NULL;
if (NULL == peer) {
cfr_err("PEER is NULL\n");
return QDF_STATUS_E_FAILURE;
}
vdev = wlan_peer_get_vdev(peer);
if (vdev)
pdev = wlan_vdev_get_pdev(vdev);
if (pdev)
pa = wlan_objmgr_pdev_get_comp_private_obj(pdev,
WLAN_UMAC_COMP_CFR);
pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR);
if (pa && pe) {
if (pe->period && pe->request)
pa->cfr_current_sta_count--;
}
if (NULL != pe) {
wlan_objmgr_peer_component_obj_detach(peer, WLAN_UMAC_COMP_CFR,
(void *)pe);
qdf_mem_free(pe);
}
return QDF_STATUS_SUCCESS;
}
/**
* create_buf_file_handler() - Create streamfs buffer file
* @filename: base name of files to create, NULL for buffering only
* @parent: dentry of parent directory, NULL for root directory
* @mode: filemode
* @rchan_buf: streamfs channel buf
*
* Returns dentry if successful, NULL otherwise.
*/
static struct dentry *create_buf_file_handler(const char *filename,
struct dentry *parent,
umode_t mode,
struct rchan_buf *buf,
int *is_global)
{
struct qal_dentry_t *buf_file;
*is_global = 1;
buf_file = qal_streamfs_create_file(filename, mode,
(struct qal_dentry_t *)parent,
(struct qal_streamfs_chan_buf *)buf);
if (!buf_file) {
cfr_err("Chan buffer creation failed\n");
return NULL;
}
return (struct dentry *)buf_file;
}
/**
* remove_buf_file_handler() - Remove streamfs buffer file
* @dentry:dentry
*/
static int remove_buf_file_handler(struct dentry *dentry)
{
qal_streamfs_remove_file((struct qal_dentry_t *)dentry);
return 0;
}
static struct rchan_callbacks cfr_streamfs_cb = {
.create_buf_file = create_buf_file_handler,
.remove_buf_file = remove_buf_file_handler,
};
QDF_STATUS cfr_streamfs_init(struct wlan_objmgr_pdev *pdev)
{
struct pdev_cfr *pa = NULL;
char folder[32];
struct net_device *pdev_netdev;
struct ol_ath_softc_net80211 *scn;
struct target_pdev_info *tgt_hdl;
if (pdev == NULL) {
cfr_err("PDEV is NULL\n");
return QDF_STATUS_E_FAILURE;
}
tgt_hdl = wlan_pdev_get_tgt_if_handle(pdev);
if (!tgt_hdl) {
cfr_err("target_pdev_info is NULL\n");
return QDF_STATUS_E_FAILURE;
}
scn = target_pdev_get_feature_ptr(tgt_hdl);
pdev_netdev = scn->netdev;
pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
if (pa == NULL) {
cfr_err("pdev_cfr is NULL\n");
return QDF_STATUS_E_FAILURE;
}
if (!pa->is_cfr_capable) {
cfr_err("CFR IS NOT SUPPORTED\n");
return QDF_STATUS_E_FAILURE;
}
snprintf(folder, sizeof(folder), "cfr%s", pdev_netdev->name);
pa->dir_ptr = qal_streamfs_create_dir((const char *)folder, NULL);
if (!pa->dir_ptr) {
cfr_err("Directory create failed");
return QDF_STATUS_E_FAILURE;
}
pa->chan_ptr = qal_streamfs_open("cfr_dump", pa->dir_ptr,
pa->subbuf_size, pa->num_subbufs,
(struct qal_streamfs_chan_callbacks *)&cfr_streamfs_cb,
NULL);
if (!pa->chan_ptr) {
cfr_err("Chan create failed");
qal_streamfs_remove_dir_recursive(pa->dir_ptr);
pa->dir_ptr = NULL;
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
}
QDF_STATUS cfr_streamfs_remove(struct wlan_objmgr_pdev *pdev)
{
struct pdev_cfr *pa = NULL;
pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
if (pa) {
if (pa->chan_ptr) {
qal_streamfs_close(pa->chan_ptr);
pa->chan_ptr = NULL;
}
if (pa->dir_ptr) {
qal_streamfs_remove_dir_recursive(pa->dir_ptr);
pa->dir_ptr = NULL;
}
} else
return QDF_STATUS_E_FAILURE;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS cfr_streamfs_write(struct pdev_cfr *pa, const void *write_data,
size_t write_len)
{
if (pa->chan_ptr) {
/* write to channel buffer */
qal_streamfs_write(pa->chan_ptr, (const void *)write_data,
write_len);
} else
return QDF_STATUS_E_FAILURE;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS cfr_streamfs_flush(struct pdev_cfr *pa)
{
if (pa->chan_ptr) {
/* Flush the data write to channel buffer */
qal_streamfs_flush(pa->chan_ptr);
} else
return QDF_STATUS_E_FAILURE;
return QDF_STATUS_SUCCESS;
}

View file

@ -0,0 +1,169 @@
/*
* 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 timer enable
*/
int
tgt_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev, uint32_t cfr_timer);
/**
* tgt_cfr_support_set() - API to set cfr support
* @psoc: pointer to psoc_object
* @value: value to be set
*/
void tgt_cfr_support_set(struct wlan_objmgr_psoc *psoc, uint32_t value);
/**
* tgt_cfr_info_send() - API to send cfr info
* @pdev: pointer to pdev_object
* @head: pointer to cfr info head
* @hlen: head len
* @data: pointer to cfr info data
* @dlen: data len
* @tail: pointer to cfr info tail
* @tlen: tail len
*
* Return: success/failure of cfr info send
*/
uint32_t tgt_cfr_info_send(struct wlan_objmgr_pdev *pdev, void *head,
size_t hlen, void *data, size_t dlen, void *tail,
size_t tlen);
#ifdef WLAN_ENH_CFR_ENABLE
/**
* tgt_cfr_config_rcc() - API to set RCC
* @pdev: pointer to pdev_object
* @rcc_param: rcc configurations
*
* Return: succcess / failure
*/
QDF_STATUS tgt_cfr_config_rcc(struct wlan_objmgr_pdev *pdev,
struct cfr_rcc_param *rcc_param);
/**
* tgt_cfr_start_lut_age_timer() - API to start timer to flush aged out LUT
* entries
* @pdev: pointer to pdev_object
*
* Return: None
*/
void tgt_cfr_start_lut_age_timer(struct wlan_objmgr_pdev *pdev);
/**
* tgt_cfr_stop_lut_age_timer() - API to stop timer to flush aged out LUT
* entries
* @pdev: pointer to pdev_object
*
* Return: None
*/
void tgt_cfr_stop_lut_age_timer(struct wlan_objmgr_pdev *pdev);
/**
* tgt_cfr_default_ta_ra_cfg() - API to configure default values in TA_RA mode
* entries
* @pdev: pointer to pdev_object
*
* Return: none
*/
void tgt_cfr_default_ta_ra_cfg(struct wlan_objmgr_pdev *pdev,
struct cfr_rcc_param *rcc_param,
bool allvalid, uint16_t reset_cfg);
/**
* tgt_cfr_dump_lut_enh() - Print all LUT entries
* @pdev: pointer to pdev_object
*/
void tgt_cfr_dump_lut_enh(struct wlan_objmgr_pdev *pdev);
/**
* tgt_cfr_rx_tlv_process() - Process PPDU status TLVs
* @pdev_obj: pointer to pdev_object
* @nbuf: pointer to cdp_rx_indication_ppdu
*/
void tgt_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf);
/**
* tgt_cfr_update_global_cfg() - Update global config after successful commit
* @pdev: pointer to pdev_object
*/
void tgt_cfr_update_global_cfg(struct wlan_objmgr_pdev *pdev);
#endif
#endif

View file

@ -0,0 +1,267 @@
/*
* 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>
#include <ieee80211_ioctl.h>
#define MAX_CFR_PRD (10*60*1000) /* 10 minutes */
/**
* ucfg_cfr_start_capture() - function to start cfr capture for connected client
* @pdev: pointer to pdev object
* @peer: pointer to peer object
* @cfr_params: config params to cfr capture
*
* Return: status 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 for connected client
* @pdev: pointer to pdev object
* @peer: pointer to peer object
*
* Return: status of stop capture.
*/
int ucfg_cfr_stop_capture(struct wlan_objmgr_pdev *pdev,
struct wlan_objmgr_peer *peer);
/**
* ucfg_cfr_start_capture_probe_req() - function to start cfr capture for
* unassociated clients
* @pdev: pointer to pdev object
* @unassoc_mac: mac address of un-associated client
* @cfr_params: config params to cfr capture
*
* Return: status of start capture.
*/
int ucfg_cfr_start_capture_probe_req(struct wlan_objmgr_pdev *pdev,
struct qdf_mac_addr *unassoc_mac,
struct cfr_capture_params *params);
/**
* ucfg_cfr_stop_capture_probe_req() - function to stop cfr capture for
* unassociated cleints
* @pdev: pointer to pdev object
* @unassoc_mac: mac address of un-associated client
*
* Return: status of stop capture.
*/
int ucfg_cfr_stop_capture_probe_req(struct wlan_objmgr_pdev *pdev,
struct qdf_mac_addr *unassoc_mac);
/**
* 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);
/**
* ucfg_cfr_set_timer() - function to enable cfr timer
* @pdev: pointer to pdev object
* @value: value to be set
*
* Return: status of timer enable
*/
int ucfg_cfr_set_timer(struct wlan_objmgr_pdev *pdev, uint32_t value);
/**
* ucfg_cfr_get_timer() - function to get cfr_timer_enable
* @pdev: pointer to pdev object
*
* Return: value of cfr_timer_enable
*/
int ucfg_cfr_get_timer(struct wlan_objmgr_pdev *pdev);
#ifdef WLAN_ENH_CFR_ENABLE
/* Channel capture recipe filters */
enum capture_type {
RCC_DIRECTED_FTM_FILTER,
RCC_ALL_FTM_ACK_FILTER,
RCC_DIRECTED_NDPA_NDP_FILTER,
RCC_NDPA_NDP_ALL_FILTER,
RCC_TA_RA_FILTER,
RCC_ALL_PACKET_FILTER,
RCC_DIS_ALL_MODE,
};
/**
* ucfg_cfr_set_rcc_mode() - function to set RCC mode
* @vdev: pointer to vdev object
* @mode: capture type passed by user
* @value: Enable/Disable capture mode
*
* Return: status if the mode is set or not
*/
QDF_STATUS ucfg_cfr_set_rcc_mode(struct wlan_objmgr_vdev *vdev,
enum capture_type mode, uint8_t value);
/**
* ucfg_cfr_get_rcc_enabled() - function to get RCC mode
* @vdev: pointer to vdev object
*
* Return: if the rcc is enabled or not
*/
bool ucfg_cfr_get_rcc_enabled(struct wlan_objmgr_vdev *vdev);
/**
* ucfg_cfr_set_tara_config() - function to configure TA/RA address and mask
* @vdev: pointer to vdev object
* @params: user config
*
* Return: status
*/
QDF_STATUS ucfg_cfr_set_tara_config(struct wlan_objmgr_vdev *vdev,
struct ieee80211_wlanconfig_cfr *params);
/**
* ucfg_cfr_set_bw_nss() - function to configure nss and bandwidth
* @vdev: pointer to vdev object
* @params: user config
*
* Return: status
*/
QDF_STATUS ucfg_cfr_set_bw_nss(struct wlan_objmgr_vdev *vdev,
struct ieee80211_wlanconfig_cfr *params);
/**
* ucfg_cfr_set_frame_type_subtype() - function to configure frame type/subtype
* @vdev: pointer to vdev object
* @params: user config
*
* Return: status
*/
QDF_STATUS
ucfg_cfr_set_frame_type_subtype(struct wlan_objmgr_vdev *vdev,
struct ieee80211_wlanconfig_cfr *params);
/**
* ucfg_cfr_set_capture_duration() - function to configure capture duration
* @vdev: pointer to vdev object
* @params: user config
*
* Return: status
*/
QDF_STATUS
ucfg_cfr_set_capture_duration(struct wlan_objmgr_vdev *vdev,
struct ieee80211_wlanconfig_cfr *params);
/**
* ucfg_cfr_set_capture_interval() - function to configure capture interval
* @vdev: pointer to vdev object
* @params: user config
*
* Return: status
*/
QDF_STATUS
ucfg_cfr_set_capture_interval(struct wlan_objmgr_vdev *vdev,
struct ieee80211_wlanconfig_cfr *params);
/**
* ucfg_cfr_set_en_bitmap() - function to configure 16-bit bitmap in TA_RA mode
* @vdev: pointer to vdev object
* @params: user config
*
* Return: status
*/
QDF_STATUS ucfg_cfr_set_en_bitmap(struct wlan_objmgr_vdev *vdev,
struct ieee80211_wlanconfig_cfr *params);
/**
* ucfg_cfr_set_reset_bitmap() - function to clear all 9 params for all 16
* groups in TA_RA mode
* @vdev: pointer to vdev object
* @params: user config
*
* Return: status
*/
QDF_STATUS ucfg_cfr_set_reset_bitmap(struct wlan_objmgr_vdev *vdev,
struct ieee80211_wlanconfig_cfr *params);
/**
* ucfg_cfr_set_ul_mu_user_mask() - function to configure UL MU user mask
* @vdev: pointer to vdev object
* @params: user config
*
* Return: status
*/
QDF_STATUS
ucfg_cfr_set_ul_mu_user_mask(struct wlan_objmgr_vdev *vdev,
struct ieee80211_wlanconfig_cfr *params);
/**
* ucfg_cfr_set_freeze_tlv_delay_cnt() - function to configure freeze TLV delay
* count threshold
* @vdev: pointer to vdev object
* @params: user config
*
* Return: status
*/
QDF_STATUS
ucfg_cfr_set_freeze_tlv_delay_cnt(struct wlan_objmgr_vdev *vdev,
struct ieee80211_wlanconfig_cfr *params);
/**
* ucfg_cfr_committed_rcc_config() - function to commit user config
* @vdev: pointer to vdev object
*
* Return: status
*/
QDF_STATUS ucfg_cfr_committed_rcc_config(struct wlan_objmgr_vdev *vdev);
/**
* ucfg_cfr_get_cfg() - function to display user config
* @vdev: pointer to vdev object
*
* Return: status
*/
QDF_STATUS ucfg_cfr_get_cfg(struct wlan_objmgr_vdev *vdev);
/**
* ucfg_cfr_rcc_dump_dbg_counters() - function to display PPDU counters
* @vdev: pointer to vdev object
*
* Return: status
*/
QDF_STATUS ucfg_cfr_rcc_dump_dbg_counters(struct wlan_objmgr_vdev *vdev);
/**
* ucfg_cfr_rcc_clr_dbg_counters() - function to clear CFR PPDU counters
* @vdev: pointer to vdev object
*
* Return: status
*/
QDF_STATUS ucfg_cfr_rcc_clr_dbg_counters(struct wlan_objmgr_vdev *vdev);
/**
* ucfg_cfr_rcc_dump_lut() - function to display lookup table
* @vdev: pointer to vdev object
*
* Return: status
*/
QDF_STATUS ucfg_cfr_rcc_dump_lut(struct wlan_objmgr_vdev *vdev);
#endif
#endif

View file

@ -0,0 +1,583 @@
/*
* 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>
#include <qal_streamfs.h>
#ifdef WLAN_ENH_CFR_ENABLE
#include <qdf_timer.h>
#endif
#define cfr_alert(format, args...) \
QDF_TRACE_FATAL(QDF_MODULE_ID_CFR, format, ## args)
#define cfr_err(format, args...) \
QDF_TRACE_ERROR(QDF_MODULE_ID_CFR, format, ## args)
#define cfr_warn(format, args...) \
QDF_TRACE_WARN(QDF_MODULE_ID_CFR, format, ## args)
#define cfr_info(format, args...) \
QDF_TRACE_INFO(QDF_MODULE_ID_CFR, format, ## args)
#define cfr_debug(format, args...) \
QDF_TRACE_DEBUG(QDF_MODULE_ID_CFR, format, ## args)
#define DBR_EVENT_TIMEOUT_IN_MS_CFR 1
#define DBR_NUM_RESP_PER_EVENT_CFR 1
#define MAX_CFR_ENABLED_CLIENTS 10
#ifdef WLAN_ENH_CFR_ENABLE
#define MAX_CFR_MU_USERS 4
#define NUM_CHAN_CAPTURE_STATUS 4
#define NUM_CHAN_CAPTURE_REASON 6
#define MAX_TA_RA_ENTRIES 16
#define MAX_RESET_CFG_ENTRY 0xFFFF
#endif
enum cfrmetaversion {
CFR_META_VERSION_NONE,
CFR_META_VERSION_1,
CFR_META_VERSION_2,
CFR_META_VERSION_3,
CFR_META_VERSION_MAX = 0xFF,
};
enum cfrdataversion {
CFR_DATA_VERSION_NONE,
CFR_DATA_VERSION_1,
CFR_DATA_VERSION_MAX = 0xFF,
};
enum cfrplatformtype {
CFR_PLATFORM_TYPE_NONE,
CFR_PLATFORM_TYPE_MIPS,
CFR_PLATFORM_TYPE_ARM,
CFR_PLATFFORM_TYPE_MAX = 0xFF,
};
enum cfrradiotype {
CFR_CAPTURE_RADIO_NONE,
CFR_CAPTURE_RADIO_OSPREY,
CFR_CAPTURE_RADIO_PEAKCOCK,
CFR_CAPTURE_RADIO_SCORPION,
CFR_CAPTURE_RADIO_HONEYBEE,
CFR_CAPTURE_RADIO_DRAGONFLY,
CFR_CAPTURE_RADIO_JET,
CFR_CAPTURE_RADIO_PEREGRINE = 17,
CFR_CAPTURE_RADIO_SWIFT,
CFR_CAPTURE_RADIO_BEELINER,
CFR_CAPTURE_RADIO_CASCADE,
CFR_CAPTURE_RADIO_DAKOTA,
CFR_CAPTURE_RADIO_BESRA,
CFR_CAPTURE_RADIO_HKV2,
CFR_CAPTURE_RADIO_CYP,
CFR_CAPTURE_RADIO_MAX = 0xFF,
};
enum ack_capture_mode {
CFR_LEGACY_ACK = 0,
CFR_DUP_LEGACY_ACK = 1,
CFR_HT_ACK = 2,
CFR_VHT_ACK = 3,
CFR_INVALID_ACK, /*Always keep this at last*/
};
/* Similar to WMI_PEER_CFR_CAPTURE_METHOD used in one-shot capture */
enum cfr_capture_type {
CFR_TYPE_METHOD_NULL_FRAME = 0,
CFR_TYPE_METHOD_NULL_FRAME_WITH_PHASE = 1,
CFR_TYPE_METHOD_PROBE_RESP = 2,
CFR_TYPE_METHOD_TM = 3,
CFR_TYPE_METHOD_FTM = 4,
CFR_TYPE_METHOD_ACK_RESP_TO_TM_FTM = 5,
CFR_TYPE_METHOD_TA_RA_TYPE_FILTER = 6,
CFR_TYPE_METHOD_NDPA_NDP = 7,
CFR_TYPE_METHOD_ALL_PACKET = 8,
/* Add new capture methods before this line */
CFR_TYPE_METHOD_LAST_VALID,
CFR_TYPE_METHOD_AUTO = 0xff,
CFR_TYPE_METHOD_MAX,
};
struct cfr_metadata_version_1 {
u_int8_t peer_addr[QDF_MAC_ADDR_SIZE];
u_int8_t status;
u_int8_t capture_bw;
u_int8_t channel_bw;
u_int8_t phy_mode;
u_int16_t prim20_chan;
u_int16_t center_freq1;
u_int16_t center_freq2;
u_int8_t capture_mode;
u_int8_t capture_type;
u_int8_t sts_count;
u_int8_t num_rx_chain;
u_int32_t timestamp;
u_int32_t length;
} __attribute__ ((__packed__));
#define HOST_MAX_CHAINS 8
struct cfr_metadata_version_2 {
u_int8_t peer_addr[QDF_MAC_ADDR_SIZE];
u_int8_t status;
u_int8_t capture_bw;
u_int8_t channel_bw;
u_int8_t phy_mode;
u_int16_t prim20_chan;
u_int16_t center_freq1;
u_int16_t center_freq2;
u_int8_t capture_mode;
u_int8_t capture_type;
u_int8_t sts_count;
u_int8_t num_rx_chain;
u_int32_t timestamp;
u_int32_t length;
u_int32_t chain_rssi[HOST_MAX_CHAINS];
u_int16_t chain_phase[HOST_MAX_CHAINS];
} __attribute__ ((__packed__));
#ifdef WLAN_ENH_CFR_ENABLE
struct cfr_metadata_version_3 {
u_int8_t status;
u_int8_t capture_bw;
u_int8_t channel_bw;
u_int8_t phy_mode;
u_int16_t prim20_chan;
u_int16_t center_freq1;
u_int16_t center_freq2;
u_int8_t capture_mode; /* ack_capture_mode */
u_int8_t capture_type; /* cfr_capture_type */
u_int8_t sts_count;
u_int8_t num_rx_chain;
u_int32_t timestamp;
u_int32_t length;
u_int8_t is_mu_ppdu;
u_int8_t num_mu_users;
union {
u_int8_t su_peer_addr[QDF_MAC_ADDR_SIZE];
u_int8_t mu_peer_addr[MAX_CFR_MU_USERS][QDF_MAC_ADDR_SIZE];
} peer_addr;
u_int32_t chain_rssi[HOST_MAX_CHAINS];
u_int16_t chain_phase[HOST_MAX_CHAINS];
} __attribute__ ((__packed__));
#endif
struct csi_cfr_header {
u_int32_t start_magic_num;
u_int32_t vendorid;
u_int8_t cfr_metadata_version;
u_int8_t cfr_data_version;
u_int8_t chip_type;
u_int8_t pltform_type;
u_int32_t Reserved;
union {
struct cfr_metadata_version_1 meta_v1;
struct cfr_metadata_version_2 meta_v2;
#ifdef WLAN_ENH_CFR_ENABLE
struct cfr_metadata_version_3 meta_v3;
#endif
} u;
} __attribute__ ((__packed__));
/**
* 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 cfr_wmi_host_mem_chunk - wmi mem chunk related
* vaddr: pointer to virtual address
* paddr: physical address
* len: len of the mem chunk allocated
* req_id: reqid related to the mem chunk
*/
struct cfr_wmi_host_mem_chunk {
uint32_t *vaddr;
uint32_t paddr;
uint32_t len;
uint32_t req_id;
};
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]
};
#define MAX_LUT_ENTRIES 140 /* For HKv2 136 is max */
/**
* struct look_up_table - Placeholder for 2 asynchronous events (DBR and
* TXRX event)
* dbr_recv: Indicates whether WMI for DBR completion is received or not
* tx_recv: Indicates whether WMI for TX completion (or) WDI event for RX
* status is received or not
* data: pointer to CFR data that ucode DMAs to host memory
* data_len: length of CFR data DMAed by ucode
* dbr_ppdu_id: PPDU id retrieved from DBR completion WMI event
* tx_ppdu_id: PPDU id retrieved from WMI TX completion event (or) PPDU status
* TLV
* dbr_address: Physical address of the CFR data dump retrieved from DBR
* completion WMI event
* tx_address1: Physical address of the CFR data from TX/RX event
* tx_address2: Physical address of the CFR data from TX/RX event
* csi_cfr_header: CFR header constructed by host
* whal_cfir_enhanced_hdr: CFR header constructed by ucode
* tx_tstamp: Timestamp when TX/RX event was received
* dbr_tstamp: Timestamp when DBR completion event was received
* header_length: Length of header DMAed by ucode in words
* payload_length: Length of CFR payload
*/
struct look_up_table {
bool dbr_recv;
bool tx_recv;
uint8_t *data; /* capture payload */
uint32_t data_len; /* capture len */
uint16_t dbr_ppdu_id; /* ppdu id from dbr */
uint16_t tx_ppdu_id; /* ppdu id from TX event */
qdf_dma_addr_t dbr_address; /* capture len */
uint32_t tx_address1; /* capture len */
uint32_t tx_address2; /* capture len */
struct csi_cfr_header header;
struct whal_cfir_dma_hdr dma_hdr;
uint64_t txrx_tstamp;
uint64_t dbr_tstamp;
uint32_t header_length;
uint32_t payload_length;
};
struct unassoc_pool_entry {
struct qdf_mac_addr mac;
struct cfr_capture_params cfr_params;
bool is_valid;
};
#ifdef WLAN_ENH_CFR_ENABLE
/**
* struct ta_ra_cfr_cfg - structure to store configuration of 16 groups in
* M_TA_RA mode
* filter_group_id: Filter group number for which the below filters needs to be
* applied
* bw: CFR capture will be done for packets matching the bandwidths specified
* within this bitmask
* nss: CFR capture will be done for packets matching the Nss specified within
* this bitmask
* valid_ta: Ta_addr is valid if set
* valid_ta_mask: Ta_addr_mask is valid if set
* valid_ra: Ra_addr is valid if set
* valid_ra_mask: Ra_addr_mask is valid if set
* valid_bw_mask: Bandwidth is valid if set
* valid_nss_mask: NSS is valid if set
* valid_mgmt_subtype: Mgmt_subtype is valid if set
* valid_ctrl_subtype: Ctrl_subtype is valid if set
* valid_data_subtype: Data_subtype is valid if set
* mgmt_subtype_filter: Managments Packets matching the subtype filter
* categories will be filtered in by MAC for CFR capture.
* ctrl_subtype_filter: Control Packets matching the subtype filter
* categories will be filtered in by MAC for CFR capture.
* data_subtype_filter: Data Packets matching the subtype filter
* categories will be filtered in by MAC for CFR capture.
* tx_addr: Packets whose transmitter address matches (tx_addr & tx_addr_mask)
* will be filtered in by MAC
* tx_addr_mask: Packets whose transmitter address matches (tx_addr &
* tx_addr_mask) will be filtered in by MAC
* rx_addr: Packets whose receiver address matches (rx_addr & rx_addr_mask)
* will be filtered in by MAC
* rx_addr_mask: Packets whose receiver address matches (rx_addr &
* rx_addr_mask) will be filtered in by MAC
*/
struct ta_ra_cfr_cfg {
uint8_t filter_group_id;
uint16_t bw :5,
nss :8,
rsvd0 :3;
uint16_t valid_ta :1,
valid_ta_mask :1,
valid_ra :1,
valid_ra_mask :1,
valid_bw_mask :1,
valid_nss_mask :1,
valid_mgmt_subtype :1,
valid_ctrl_subtype :1,
valid_data_subtype :1,
rsvd1 :7;
uint16_t mgmt_subtype_filter;
uint16_t ctrl_subtype_filter;
uint16_t data_subtype_filter;
uint8_t tx_addr[QDF_MAC_ADDR_SIZE];
uint8_t rx_addr[QDF_MAC_ADDR_SIZE];
uint8_t tx_addr_mask[QDF_MAC_ADDR_SIZE];
uint8_t rx_addr_mask[QDF_MAC_ADDR_SIZE];
} qdf_packed;
/**
* struct cfr_rcc_param - structure to store cfr config param
* pdev_id: pdev_id for identifying the MAC
* capture_duration: Capture Duration field for which CFR capture has to happen,
* in microsecond units
* capture_interval: Capture interval field which is time in between
* consecutive CFR capture, in microsecond units
* ul_mu_user_mask_lower: Bitfields indicates which of the users in the current
* UL MU tranmission are enabled for CFR capture.
* ul_mu_user_mask_upper: This is contiuation of the above lower mask.
* freeze_tlv_delay_cnt_en: Enable Freeze TLV delay counter in MAC
* freeze_tlv_delay_cnt_thr: Indicates the number of consecutive Rx packets to
* be skipped before CFR capture is enabled again.
* filter_group_bitmap: Bitfields set indicates which of the CFR group config is
* enabled
* m_directed_ftm: Filter Directed FTM ACK frames for CFR capture
* m_all_ftm_ack: Filter All FTM ACK frames for CFR capture
* m_ndpa_ndp_directed: Filter NDPA NDP Directed Frames for CFR capture
* m_ndpa_ndp_all: Filter all NDPA NDP for CFR capture
* m_ta_ra_filter: Filter Frames based on TA/RA/Subtype as provided in CFR Group
* config
* m_all_packet: Filter in All packets for CFR Capture
* num_grp_tlvs: Indicates the number of groups in M_TA_RA mode, that have
* changes in the current commit session, use to construct WMI group TLV(s)
* curr: Placeholder for M_TA_RA group config in current commit session
* modified_in_curr_session: Bitmap indicating number of groups in M_TA_RA mode
* that have changed in current commit session.
*/
struct cfr_rcc_param {
uint8_t pdev_id;
uint32_t capture_duration;
uint32_t capture_interval;
uint32_t ul_mu_user_mask_lower;
uint32_t ul_mu_user_mask_upper;
uint16_t freeze_tlv_delay_cnt_en :1,
freeze_tlv_delay_cnt_thr :8,
rsvd0 :7;
uint16_t filter_group_bitmap;
uint8_t m_directed_ftm : 1,
m_all_ftm_ack : 1,
m_ndpa_ndp_directed : 1,
m_ndpa_ndp_all : 1,
m_ta_ra_filter : 1,
m_all_packet : 1,
rsvd1 : 2;
uint8_t num_grp_tlvs;
struct ta_ra_cfr_cfg curr[MAX_TA_RA_ENTRIES];
uint16_t modified_in_curr_session;
};
#endif /* WLAN_ENH_CFR_ENABLE */
/**
* 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
* cfr_mem_chunk: Region of memory used for storing cfr data
* cfr_max_sta_count: Maximum stations supported in one-shot capture mode
* num_subbufs: No. of sub-buffers used in relayfs
* subbuf_size: Size of sub-buffer used in relayfs
* chan_ptr: Channel in relayfs
* dir_ptr: Parent directory of relayfs file
* lut: lookup table used to store asynchronous DBR and TX/RX events for
* correlation
* dbr_buf_size: Size of DBR completion buffer
* dbr_num_bufs: No. of DBR completions
* tx_evt_cnt: No. of TX completion events till CFR stop was issued
* total_tx_evt_cnt: No. of Tx completion events since wifi was up
* dbr_evt_cnt: No. of WMI DBR completion events
* release_cnt: No. of CFR data buffers relayed to userspace
* rcc_param: Structure to store CFR config for the current commit session
* global: Structure to store accumulated CFR config
* rx_tlv_evt_cnt: Number of CFR WDI events from datapath
* lut_age_timer: Timer to flush pending TXRX/DBR events in lookup table
* lut_timer_init: flag to determine if lut_age_timer is initialized or not
* is_cfr_rcc_capable: Flag to determine if RCC is enabled or not.
* flush_dbr_cnt: No. of un-correlated DBR completions flushed when a newer PPDU
* is correlated successfully with newer DBR completion
* invalid_dma_length_cnt: No. of buffers for which CFR DMA header length (or)
* data length was invalid
* flush_timeout_dbr_cnt: No. of DBR completion flushed out in ageout logic
* clear_txrx_event: No. of PPDU status TLVs over-written in LUT
* unassoc_pool: Pool of un-associated clients used when capture method is
* CFR_CAPTURE_METHOD_PROBE_RESPONSE
* last_success_tstamp: DBR timestamp which indicates that both DBR and TX/RX
* events have been received successfully.
* cfr_dma_aborts: No. of CFR DMA aborts in ucode
*/
/*
* 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;
struct cfr_wmi_host_mem_chunk cfr_mem_chunk;
uint16_t cfr_max_sta_count;
uint16_t cfr_current_sta_count;
uint32_t num_subbufs;
uint32_t subbuf_size;
struct qal_streamfs_chan *chan_ptr;
struct qal_dentry_t *dir_ptr;
struct look_up_table lut[MAX_LUT_ENTRIES];
uint32_t dbr_buf_size;
uint32_t dbr_num_bufs;
uint64_t tx_evt_cnt;
uint64_t total_tx_evt_cnt;
uint64_t dbr_evt_cnt;
uint64_t release_cnt;
#ifdef WLAN_ENH_CFR_ENABLE
struct cfr_rcc_param rcc_param;
struct ta_ra_cfr_cfg global[MAX_TA_RA_ENTRIES];
uint64_t rx_tlv_evt_cnt;
qdf_timer_t lut_age_timer;
uint8_t lut_timer_init;
uint8_t is_cfr_rcc_capable;
uint64_t flush_dbr_cnt;
uint64_t invalid_dma_length_cnt;
uint64_t flush_timeout_dbr_cnt;
uint64_t clear_txrx_event;
uint64_t last_success_tstamp;
uint64_t cfr_dma_aborts;
#endif
struct unassoc_pool_entry unassoc_pool[MAX_CFR_ENABLED_CLIENTS];
};
#define PEER_CFR_CAPTURE_ENABLE 1
#define PEER_CFR_CAPTURE_DISABLE 0
/**
* 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;
};
/**
* cfr_initialize_pdev() - cfr initialize pdev
* @pdev: Pointer to pdev_obj
*
* Return: status of cfr pdev init
*/
QDF_STATUS cfr_initialize_pdev(struct wlan_objmgr_pdev *pdev);
/**
* cfr_deinitialize_pdev() - cfr deinitialize pdev
* @pdev: Pointer to pdev_obj
*
* Return: status of cfr pdev deinit
*/
QDF_STATUS cfr_deinitialize_pdev(struct wlan_objmgr_pdev *pdev);
/**
* 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);
/**
* count_set_bits() - function to count set bits in a bitmap
* @value: input bitmap
*
* Return: No. of set bits
*/
uint8_t count_set_bits(uint32_t value);
#ifdef WLAN_ENH_CFR_ENABLE
/**
* wlan_cfr_rx_tlv_process() - Process PPDU status TLVs and store info in
* lookup table
* @pdev_obj: PDEV object
* @nbuf: ppdu info
*
* Return: none
*/
void wlan_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf);
#endif
#endif

View file

@ -0,0 +1,287 @@
/*
* 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>
#include <cfr_defs_i.h>
uint32_t tgt_cfr_info_send(struct wlan_objmgr_pdev *pdev, void *head,
size_t hlen, void *data, size_t dlen, void *tail,
size_t tlen)
{
struct pdev_cfr *pa;
uint32_t status;
pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
if (pa == NULL) {
cfr_err("pdev_cfr is NULL\n");
return -1;
}
if (head)
status = cfr_streamfs_write(pa, (const void *)head, hlen);
if (data)
status = cfr_streamfs_write(pa, (const void *)data, dlen);
if (tail)
status = cfr_streamfs_write(pa, (const void *)tail, tlen);
/* finalise the write */
status = cfr_streamfs_flush(pa);
return status;
}
void tgt_cfr_support_set(struct wlan_objmgr_psoc *psoc, uint32_t value)
{
struct psoc_cfr *cfr_sc;
if (psoc == NULL)
return;
cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
WLAN_UMAC_COMP_CFR);
if (cfr_sc == NULL)
return;
cfr_sc->is_cfr_capable = !!value;
cfr_debug("CFR:%s FW support advert=%d\n", __func__,
cfr_sc->is_cfr_capable);
}
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 = 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_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;
}
int
tgt_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev, uint32_t cfr_timer)
{
int status = 0;
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)
status = cfr_tx_ops->cfr_enable_cfr_timer(pdev, cfr_timer);
if (status != 0)
cfr_err("Error occurred with exit code %d\n", status);
return status;
}
#ifdef WLAN_ENH_CFR_ENABLE
QDF_STATUS
tgt_cfr_config_rcc(struct wlan_objmgr_pdev *pdev,
struct cfr_rcc_param *rcc_param)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
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_config_rcc)
status = cfr_tx_ops->cfr_config_rcc(pdev, rcc_param);
if (status != QDF_STATUS_SUCCESS)
cfr_err("Error occurred with exit code %d\n", status);
return status;
}
void tgt_cfr_start_lut_age_timer(struct wlan_objmgr_pdev *pdev)
{
struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL;
struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
cfr_err("Invalid PSOC: Flush LUT Timer cannot be started\n");
return;
}
cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc);
if (cfr_tx_ops->cfr_start_lut_timer)
cfr_tx_ops->cfr_start_lut_timer(pdev);
}
void tgt_cfr_stop_lut_age_timer(struct wlan_objmgr_pdev *pdev)
{
struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL;
struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
cfr_err("Invalid PSOC: Flush LUT Timer cannot be stopped\n");
return;
}
cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc);
if (cfr_tx_ops->cfr_stop_lut_timer)
cfr_tx_ops->cfr_stop_lut_timer(pdev);
}
void tgt_cfr_default_ta_ra_cfg(struct wlan_objmgr_pdev *pdev,
struct cfr_rcc_param *rcc_param,
bool allvalid, uint16_t reset_cfg)
{
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_default_ta_ra_cfg)
cfr_tx_ops->cfr_default_ta_ra_cfg(rcc_param,
allvalid, reset_cfg);
}
void tgt_cfr_dump_lut_enh(struct wlan_objmgr_pdev *pdev)
{
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_dump_lut_enh)
cfr_tx_ops->cfr_dump_lut_enh(pdev);
}
void tgt_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf)
{
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_rx_tlv_process)
cfr_tx_ops->cfr_rx_tlv_process(pdev, nbuf);
}
void tgt_cfr_update_global_cfg(struct wlan_objmgr_pdev *pdev)
{
struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL;
struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
cfr_err("Invalid PSOC:Cannot update global config.\n");
return;
}
cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc);
if (cfr_tx_ops->cfr_update_global_cfg)
cfr_tx_ops->cfr_update_global_cfg(pdev);
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,184 @@
/*
* 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>
#include <wlan_objmgr_pdev_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;
/* chip specific init */
status = tgt_cfr_init_pdev(pdev);
if (status != QDF_STATUS_SUCCESS) {
cfr_err("tgt_cfr_init_pdev failed with %d\n", status);
return QDF_STATUS_SUCCESS;
}
/* RealyFS init */
status = cfr_streamfs_init(pdev);
if (status != QDF_STATUS_SUCCESS) {
cfr_err("cfr_streamfs_init failed with %d\n", status);
return QDF_STATUS_SUCCESS;
}
return QDF_STATUS_SUCCESS;
}
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 = cfr_streamfs_remove(pdev);
return status;
}
QDF_STATUS cfr_initialize_pdev(struct wlan_objmgr_pdev *pdev)
{
int status = QDF_STATUS_SUCCESS;
/* chip specific init */
status = tgt_cfr_init_pdev(pdev);
if (status != QDF_STATUS_SUCCESS)
cfr_err("cfr_initialize_pdev status=%d\n", status);
return status;
}
qdf_export_symbol(cfr_initialize_pdev);
QDF_STATUS cfr_deinitialize_pdev(struct wlan_objmgr_pdev *pdev)
{
int status = QDF_STATUS_SUCCESS;
/* chip specific deinit */
status = tgt_cfr_deinit_pdev(pdev);
if (status != QDF_STATUS_SUCCESS)
cfr_err("cfr_deinitialize_pdev status=%d\n", status);
return status;
}
qdf_export_symbol(cfr_deinitialize_pdev);
uint8_t count_set_bits(uint32_t value)
{
uint8_t count = 0;
while (value) {
value &= (value - 1);
count++;
}
return count;
}
qdf_export_symbol(count_set_bits);
#ifdef WLAN_ENH_CFR_ENABLE
void wlan_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf)
{
tgt_cfr_rx_tlv_process(pdev, nbuf);
}
qdf_export_symbol(wlan_cfr_rx_tlv_process);
#endif