qcacmn: Extract enhanced aoa data
Changes to extract enhanced aoa data from WMI event CRs-Fixed: 3553725 Change-Id: I4a37fdb889cd5d461ee6ef92966a042aeed91fc8
This commit is contained in:
parent
2a073ca079
commit
0536af115e
@ -114,8 +114,6 @@
|
||||
|
||||
#define STREAMFS_NUM_SUBBUF_WAIKIKI 127
|
||||
|
||||
#define MAX_AGC_GAIN_VALUE_WAIKIKI 64
|
||||
|
||||
/* Max 4 users in MU case for Spruce */
|
||||
#define SPRUCE_CFR_MU_USERS 4
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <target_if_direct_buf_rx_api.h>
|
||||
#include <target_if_cfr_enh.h>
|
||||
#include "cdp_txrx_ctrl.h"
|
||||
#include <wlan_reg_services_api.h>
|
||||
|
||||
#define CMN_NOISE_FLOOR (-96)
|
||||
#define NUM_CHAINS_FW_TO_HOST(n) ((1 << ((n) + 1)) - 1)
|
||||
@ -63,7 +64,7 @@ u_int32_t snr_to_signal_strength(uint8_t snr)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* tagret_if_snr_to_signal_strength() - wrapper API to snr_to_signal_strength to
|
||||
* target_if_snr_to_signal_strength() - wrapper API to snr_to_signal_strength to
|
||||
* consider target_type.
|
||||
* @target_type: target type of the pdev
|
||||
* @meta: pointer to CFR metadata
|
||||
@ -942,21 +943,222 @@ bool target_if_cfr_get_11be_support_flag(uint8_t pdev_id,
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* target_if_get_max_agc_gain(): Function to get the max agc gain supported
|
||||
* based on the target_type
|
||||
*
|
||||
* @target_type: target type to which max agc gain needed
|
||||
*
|
||||
* Return: max agc gain value supported on target_type
|
||||
*/
|
||||
#ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT
|
||||
static inline
|
||||
uint32_t target_if_get_max_agc_gain(uint32_t target_type)
|
||||
bool is_valid_gain_table_idx(uint16_t tbl_idx, struct pdev_cfr *pcfr)
|
||||
{
|
||||
if (target_type == TARGET_TYPE_QCN9224)
|
||||
return MAX_AGC_GAIN_VALUE_WAIKIKI;
|
||||
else
|
||||
/* if default gain table return true */
|
||||
if (!tbl_idx)
|
||||
return true;
|
||||
|
||||
/* non zero gain table is invalid when is_enh_aoa_data is not set */
|
||||
if (!pcfr->is_enh_aoa_data)
|
||||
return false;
|
||||
|
||||
if ((tbl_idx > 0) && (tbl_idx < pcfr->max_agc_gain_tbls))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline
|
||||
uint16_t get_max_agc_gain(struct wlan_objmgr_vdev *vdev,
|
||||
uint16_t tbl_idx, struct pdev_cfr *pcfr,
|
||||
bool supports_11be)
|
||||
{
|
||||
uint16_t *max_agc_gain_per_tbl = NULL;
|
||||
struct wlan_channel *bss_chan;
|
||||
|
||||
if (!supports_11be)
|
||||
return MAX_AGC_GAIN;
|
||||
|
||||
if (!pcfr->is_enh_aoa_data)
|
||||
return INVALID_AGC_GAIN;
|
||||
|
||||
bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
|
||||
if (wlan_reg_is_24ghz_ch_freq(bss_chan->ch_freq))
|
||||
max_agc_gain_per_tbl = pcfr->max_agc_gain_per_tbl_2g;
|
||||
else if (wlan_reg_is_5ghz_ch_freq(bss_chan->ch_freq))
|
||||
max_agc_gain_per_tbl = pcfr->max_agc_gain_per_tbl_5g;
|
||||
else if (wlan_reg_is_6ghz_chan_freq(bss_chan->ch_freq))
|
||||
max_agc_gain_per_tbl = pcfr->max_agc_gain_per_tbl_6g;
|
||||
|
||||
if (is_valid_gain_table_idx(tbl_idx, pcfr) && max_agc_gain_per_tbl)
|
||||
return max_agc_gain_per_tbl[tbl_idx];
|
||||
else
|
||||
return INVALID_AGC_GAIN;
|
||||
}
|
||||
|
||||
static
|
||||
void populate_enh_chain_phase(struct wlan_objmgr_vdev *vdev,
|
||||
struct pdev_cfr *pcfr,
|
||||
struct enh_cfr_metadata *meta,
|
||||
bool invalid_gain_table_idx)
|
||||
{
|
||||
uint16_t *phase_array, *gain_array;
|
||||
uint16_t phase_delta;
|
||||
uint32_t start_ent, stop_ent, chain, tbl_idx, grp_stp_idx, found;
|
||||
uint32_t data_idx, rf_chain;
|
||||
|
||||
if (invalid_gain_table_idx || !pcfr->is_enh_aoa_data) {
|
||||
/**
|
||||
* When AoA is enabled but invalid gain table index is reported
|
||||
* by HW, it indicates the AoA result is not reliable. Hence,
|
||||
* set the chain_phase to 0xFFFF indicating an error.
|
||||
* Set invalid phase when enhanced aoa capability is not set.
|
||||
*/
|
||||
for (chain = 0; chain < pcfr->max_aoa_chains; chain++)
|
||||
meta->chain_phase[chain] = INVALID_PHASE_DELTA;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (chain = 0; chain < pcfr->max_aoa_chains; chain++) {
|
||||
rf_chain = (pcfr->xbar_config) ?
|
||||
((pcfr->xbar_config >> (3 * chain)) & 0x07) :
|
||||
chain;
|
||||
data_idx = (rf_chain * pcfr->max_entries_all_table);
|
||||
|
||||
phase_array = &pcfr->enh_phase_delta_array[data_idx];
|
||||
gain_array = &pcfr->gain_stop_index_array[data_idx];
|
||||
tbl_idx = meta->agc_gain_tbl_index[chain];
|
||||
start_ent = pcfr->start_ent[tbl_idx];
|
||||
stop_ent = start_ent + pcfr->max_bdf_entries_per_tbl[tbl_idx];
|
||||
|
||||
/**
|
||||
* if default gain table exceeds max_agc_gain, chain_phase needs
|
||||
* to be considered as 0. Remaining gain tables would have a
|
||||
* phase delta assigned with max agc gain as well
|
||||
*/
|
||||
if (!tbl_idx && (meta->agc_gain[chain] ==
|
||||
get_max_agc_gain(vdev, tbl_idx, pcfr, true))) {
|
||||
phase_delta = 0;
|
||||
meta->chain_phase[chain] =
|
||||
(pcfr->ibf_cal_val[rf_chain] +
|
||||
phase_delta) & 0x3FF;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (grp_stp_idx = start_ent, found = 0;
|
||||
grp_stp_idx < stop_ent; grp_stp_idx++) {
|
||||
if (meta->agc_gain[chain] <= gain_array[grp_stp_idx]) {
|
||||
phase_delta = phase_array[grp_stp_idx];
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!found) && (grp_stp_idx >= stop_ent))
|
||||
phase_delta = 0;
|
||||
|
||||
meta->chain_phase[chain] = (pcfr->ibf_cal_val[rf_chain] +
|
||||
phase_delta) & 0x3FF;
|
||||
}
|
||||
}
|
||||
#else
|
||||
static inline
|
||||
bool is_valid_gain_table_idx(uint16_t tbl_idx, struct pdev_cfr *pcfr)
|
||||
{
|
||||
/* if default gain table return true */
|
||||
if (!tbl_idx)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline
|
||||
uint16_t get_max_agc_gain(struct wlan_objmgr_vdev *vdev,
|
||||
uint16_t tbl_idx, struct pdev_cfr *pcfr,
|
||||
bool supports_11be)
|
||||
{
|
||||
if (!supports_11be)
|
||||
return MAX_AGC_GAIN;
|
||||
|
||||
return INVALID_AGC_GAIN;
|
||||
}
|
||||
|
||||
static
|
||||
void populate_enh_chain_phase(struct wlan_objmgr_vdev *vdev,
|
||||
struct pdev_cfr *pcfr,
|
||||
struct enh_cfr_metadata *meta,
|
||||
bool invalid_gain_table_idx)
|
||||
{
|
||||
uint8_t chain;
|
||||
|
||||
cfr_debug("Enahced AoA not supported.. Invsetigate");
|
||||
for (chain = 0; chain < pcfr->max_aoa_chains; chain++)
|
||||
meta->chain_phase[chain] = INVALID_PHASE_DELTA;
|
||||
}
|
||||
#endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */
|
||||
|
||||
static
|
||||
void populate_chain_phase(struct wlan_objmgr_vdev *vdev,
|
||||
struct pdev_cfr *pcfr,
|
||||
struct enh_cfr_metadata *meta,
|
||||
bool invalid_gain_table_idx)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t gain, pdelta;
|
||||
|
||||
if (invalid_gain_table_idx) {
|
||||
/**
|
||||
* When AoA is enabled but invalid gain table index is reported
|
||||
* by HW, it indicates the AoA result is not reliable. Hence,
|
||||
* set the chain_phase to 0xFFFF indicating an error.
|
||||
*/
|
||||
for (i = 0; i < pcfr->max_aoa_chains; i++) {
|
||||
if (wlan_vdev_mlme_is_special_vdev(vdev) &&
|
||||
i == CHAIN_SHIFT_INDEX_PINE_SCAN) {
|
||||
meta->chain_phase[i - 1] = INVALID_PHASE_DELTA;
|
||||
break;
|
||||
}
|
||||
meta->chain_phase[i] = INVALID_PHASE_DELTA;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < pcfr->max_aoa_chains; i++) {
|
||||
/**
|
||||
* phase delta stored in reverse order by FW.
|
||||
* Hence, index accordingly
|
||||
*/
|
||||
gain = meta->agc_gain[i];
|
||||
if (gain < MAX_AGC_GAIN) {
|
||||
pdelta = pcfr->phase_delta[i][MAX_AGC_GAIN -
|
||||
1 -
|
||||
gain];
|
||||
} else {
|
||||
/* populate 0 for last gain index */
|
||||
pdelta = 0;
|
||||
}
|
||||
/**
|
||||
* FW sets 0xFFFF as invalid phase delta in
|
||||
* invalid cases. Retain same in HOST as well.
|
||||
* In case of valid phase, add the ibf cal value
|
||||
* to the delta & ensure the derived phase value
|
||||
* is in the range of 0 - 1024 indicating 0 - 360
|
||||
* degrees
|
||||
*/
|
||||
if (pdelta == INVALID_PHASE_DELTA) {
|
||||
if (wlan_vdev_mlme_is_special_vdev(vdev) &&
|
||||
i == CHAIN_SHIFT_INDEX_PINE_SCAN) {
|
||||
meta->chain_phase[i - 1] =
|
||||
INVALID_PHASE_DELTA;
|
||||
break;
|
||||
}
|
||||
meta->chain_phase[i] = INVALID_PHASE_DELTA;
|
||||
} else {
|
||||
if (wlan_vdev_mlme_is_special_vdev(vdev) &&
|
||||
i == CHAIN_SHIFT_INDEX_PINE_SCAN) {
|
||||
meta->chain_phase[i - 1] =
|
||||
((pcfr->ibf_cal_val[i] +
|
||||
pdelta) & 0x3FF);
|
||||
break;
|
||||
}
|
||||
meta->chain_phase[i] = ((pcfr->ibf_cal_val[i] +
|
||||
pdelta) & 0x3FF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -991,15 +1193,13 @@ void target_if_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf)
|
||||
uint8_t srng_id = 0;
|
||||
struct wlan_lmac_if_rx_ops *rx_ops;
|
||||
uint32_t target_type;
|
||||
uint16_t pdelta, gain;
|
||||
uint16_t gain_info[HOST_MAX_CHAINS];
|
||||
bool invalid_gain_table_idx = false;
|
||||
uint32_t target_max_agc_gain = 0;
|
||||
uint32_t max_agc_gain = 0;
|
||||
bool supports_11be;
|
||||
uint8_t pdev_id;
|
||||
struct target_psoc_info *tgt_hdl;
|
||||
|
||||
|
||||
if (qdf_unlikely(!pdev)) {
|
||||
cfr_err("pdev is null\n");
|
||||
qdf_nbuf_free(nbuf);
|
||||
@ -1136,95 +1336,39 @@ void target_if_cfr_rx_tlv_process(struct wlan_objmgr_pdev *pdev, void *nbuf)
|
||||
gain_info[6] = get_u16_lsb(cfr_info->agc_gain_info3);
|
||||
gain_info[7] = get_u16_msb(cfr_info->agc_gain_info3);
|
||||
|
||||
target_max_agc_gain = target_if_get_max_agc_gain(target_type);
|
||||
|
||||
for (i = 0; i < HOST_MAX_CHAINS; i++) {
|
||||
meta->agc_gain[i] = get_gain_db(gain_info[i]);
|
||||
meta->agc_gain_tbl_index[i] = get_gain_table_idx(gain_info[i]);
|
||||
|
||||
if (pcfr->is_aoa_for_rcc_support &&
|
||||
(i < pcfr->max_aoa_chains) &&
|
||||
(meta->agc_gain_tbl_index[i] != 0)) {
|
||||
max_agc_gain = get_max_agc_gain(vdev,
|
||||
meta->agc_gain_tbl_index[i],
|
||||
pcfr,
|
||||
supports_11be);
|
||||
if (!is_valid_gain_table_idx(meta->agc_gain_tbl_index[i],
|
||||
pcfr)) {
|
||||
cfr_debug("Invalid gain table index reported");
|
||||
invalid_gain_table_idx = true;
|
||||
}
|
||||
|
||||
if (meta->agc_gain[i] > target_max_agc_gain)
|
||||
meta->agc_gain[i] = target_max_agc_gain;
|
||||
if (meta->agc_gain[i] > max_agc_gain)
|
||||
meta->agc_gain[i] = max_agc_gain;
|
||||
}
|
||||
|
||||
if (wlan_vdev_mlme_is_special_vdev(vdev)) {
|
||||
for (i = 0; i < pcfr->max_aoa_chains; i++)
|
||||
meta->chain_phase[i] = INVALID_PHASE_DELTA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not derive the chain phase when capability is not set Or
|
||||
* when an invalid gain table index is reported by Hardware.
|
||||
*/
|
||||
if (wlan_vdev_mlme_is_special_vdev(vdev)) {
|
||||
for (i = 0; i < pcfr->max_aoa_chains; i++)
|
||||
meta->chain_phase[i] = INVALID_PHASE_DELTA;
|
||||
}
|
||||
|
||||
if (pcfr->is_aoa_for_rcc_support && !invalid_gain_table_idx) {
|
||||
for (i = 0; i < pcfr->max_aoa_chains; i++) {
|
||||
/**
|
||||
* phase delta stored in reverse order by FW.
|
||||
* Hence, index accordingly
|
||||
*/
|
||||
gain = meta->agc_gain[i];
|
||||
if (gain < MAX_AGC_GAIN) {
|
||||
pdelta = pcfr->phase_delta[i][MAX_AGC_GAIN -
|
||||
1 -
|
||||
gain];
|
||||
} else if (supports_11be &&
|
||||
gain < target_max_agc_gain) {
|
||||
/**
|
||||
* 11be supports gain 62, 63 & gain 61's phase
|
||||
* delta need to be copied to 62 & 63
|
||||
*/
|
||||
pdelta = pcfr->phase_delta[i][0];
|
||||
} else {
|
||||
/* populate 0 for last gain index */
|
||||
pdelta = 0;
|
||||
}
|
||||
/**
|
||||
* FW sets 0xFFFF as invalid phase delta in
|
||||
* invalid cases. Retain same in HOST as well.
|
||||
* In case of valid phase, add the ibf cal value
|
||||
* to the delta & ensure the derived phase value
|
||||
* is in the range of 0 - 1024 indicating 0 - 360
|
||||
* degrees
|
||||
*/
|
||||
if (pdelta == INVALID_PHASE_DELTA) {
|
||||
if (wlan_vdev_mlme_is_special_vdev(vdev) &&
|
||||
i == CHAIN_SHIFT_INDEX_PINE_SCAN) {
|
||||
meta->chain_phase[i - 1] =
|
||||
INVALID_PHASE_DELTA;
|
||||
break;
|
||||
}
|
||||
meta->chain_phase[i] = INVALID_PHASE_DELTA;
|
||||
} else {
|
||||
if (wlan_vdev_mlme_is_special_vdev(vdev) &&
|
||||
i == CHAIN_SHIFT_INDEX_PINE_SCAN) {
|
||||
meta->chain_phase[i - 1] =
|
||||
((pcfr->ibf_cal_val[i] +
|
||||
pdelta) & 0x3FF);
|
||||
break;
|
||||
}
|
||||
meta->chain_phase[i] = ((pcfr->ibf_cal_val[i] +
|
||||
pdelta) & 0x3FF);
|
||||
}
|
||||
}
|
||||
} else if (pcfr->is_aoa_for_rcc_support) {
|
||||
/**
|
||||
* When AoA is enabled but invalid gain table index is reported
|
||||
* by HW, it indicates the AoA result is not reliable. Hence,
|
||||
* set the chain_phase to 0xFFFF indicating an error.
|
||||
*/
|
||||
for (i = 0; i < pcfr->max_aoa_chains; i++) {
|
||||
if (wlan_vdev_mlme_is_special_vdev(vdev) &&
|
||||
i == CHAIN_SHIFT_INDEX_PINE_SCAN) {
|
||||
meta->chain_phase[i - 1] = INVALID_PHASE_DELTA;
|
||||
break;
|
||||
}
|
||||
meta->chain_phase[i] = INVALID_PHASE_DELTA;
|
||||
if (pcfr->is_aoa_for_rcc_support) {
|
||||
if (supports_11be) {
|
||||
populate_enh_chain_phase(vdev, pcfr,
|
||||
meta, invalid_gain_table_idx);
|
||||
} else {
|
||||
populate_chain_phase(vdev, pcfr,
|
||||
meta, invalid_gain_table_idx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1668,6 +1812,158 @@ target_if_pdev_aoa_phasedaelta_event_handler(ol_scn_t sc,
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT
|
||||
static int
|
||||
target_if_pdev_enhanced_aoa_phasedelta_event_handler(ol_scn_t sc,
|
||||
uint8_t *data,
|
||||
uint32_t datalen)
|
||||
{
|
||||
struct wmi_unified *wmi_handle;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
struct wlan_objmgr_pdev *pdev;
|
||||
struct pdev_cfr *pcfr;
|
||||
QDF_STATUS retval = 0;
|
||||
struct wmi_cfr_enh_phase_delta_param param = {0};
|
||||
uint32_t dst_idx, src_idx, max_src_ent, max_dst_ent;
|
||||
uint32_t num_data_chains;
|
||||
uint32_t offset;
|
||||
|
||||
qdf_bitmap(data_chain_bmap, sizeof(uint32_t) * QDF_CHAR_BIT);
|
||||
|
||||
if (!sc || !data) {
|
||||
cfr_err("sc or data is null");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
psoc = target_if_get_psoc_from_scn_hdl(sc);
|
||||
if (!psoc) {
|
||||
cfr_err("psoc is null");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
retval = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_CFR_ID);
|
||||
if (QDF_IS_STATUS_ERROR(retval)) {
|
||||
cfr_err("unable to get psoc reference");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
|
||||
if (!wmi_handle) {
|
||||
cfr_err("wmi_handle is null");
|
||||
wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
retval = wmi_extract_cfr_pdev_enhanced_aoa_phasedelta_event_fixed_param
|
||||
(wmi_handle, data, ¶m);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(retval)) {
|
||||
cfr_err("Failed to extract phase delta fixed param tlv");
|
||||
wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pdev = wlan_objmgr_get_pdev_by_id(psoc, param.pdev_id, WLAN_CFR_ID);
|
||||
if (!pdev) {
|
||||
cfr_err("pdev is null");
|
||||
wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
|
||||
|
||||
if (!pcfr) {
|
||||
cfr_err("pdev object for CFR is NULL");
|
||||
wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
|
||||
wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pcfr->freq = param.freq;
|
||||
pcfr->max_aoa_chains = (param.max_chains <= HOST_MAX_CHAINS) ?
|
||||
param.max_chains : HOST_MAX_CHAINS;
|
||||
|
||||
num_data_chains = qdf_get_hweight32(param.data_for_chainmask);
|
||||
|
||||
if (num_data_chains != param.max_chains)
|
||||
cfr_debug("data not received for all chains");
|
||||
|
||||
qdf_mem_zero(data_chain_bmap, sizeof(data_chain_bmap));
|
||||
qdf_mem_copy(data_chain_bmap, ¶m.data_for_chainmask,
|
||||
qdf_min(sizeof(data_chain_bmap),
|
||||
sizeof(param.data_for_chainmask)));
|
||||
pcfr->xbar_config = param.xbar_config;
|
||||
|
||||
qdf_mem_copy(pcfr->ibf_cal_val, param.ibf_cal_val,
|
||||
sizeof(uint32_t) * HOST_MAX_CHAINS);
|
||||
|
||||
param.array_size = (pcfr->max_aoa_chains *
|
||||
pcfr->max_entries_all_table * sizeof(uint16_t));
|
||||
|
||||
param.gain_stop_index_array = qdf_mem_malloc(param.array_size);
|
||||
if (!param.gain_stop_index_array) {
|
||||
cfr_err("Failed to allocate gain stop index array");
|
||||
wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
|
||||
wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
param.enh_phase_delta_array = qdf_mem_malloc(param.array_size);
|
||||
if (!param.enh_phase_delta_array) {
|
||||
cfr_err("Failed to allocate phase delta array");
|
||||
qdf_mem_free(param.gain_stop_index_array);
|
||||
wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
|
||||
wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
qdf_mem_zero(param.gain_stop_index_array, param.array_size);
|
||||
qdf_mem_zero(param.enh_phase_delta_array, param.array_size);
|
||||
|
||||
retval = wmi_extract_cfr_pdev_enhanced_aoa_phasedelta_event_data
|
||||
(wmi_handle, data, ¶m);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(retval)) {
|
||||
cfr_err("Failed to extract phase data tlv");
|
||||
wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
|
||||
wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
|
||||
qdf_mem_free(param.gain_stop_index_array);
|
||||
qdf_mem_free(param.enh_phase_delta_array);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!pcfr->is_aoa_for_rcc_support || !pcfr->is_enh_aoa_data)
|
||||
cfr_err("AoA data event from unsupported target");
|
||||
|
||||
max_src_ent = param.array_size / sizeof(uint32_t);
|
||||
max_dst_ent = pcfr->max_entries_all_table * pcfr->max_aoa_chains;
|
||||
|
||||
offset = pcfr->max_entries_all_table *
|
||||
qdf_find_first_bit(data_chain_bmap,
|
||||
sizeof(uint32_t) * QDF_CHAR_BIT);
|
||||
for (dst_idx = (0 + offset), src_idx = 0;
|
||||
((dst_idx < max_dst_ent) && (src_idx < max_src_ent));
|
||||
dst_idx += 2, src_idx++) {
|
||||
uint32_t data;
|
||||
|
||||
data = param.gain_stop_index_array[src_idx];
|
||||
pcfr->gain_stop_index_array[dst_idx] = get_u16_lsb(data);
|
||||
pcfr->gain_stop_index_array[dst_idx + 1] = get_u16_msb(data);
|
||||
|
||||
data = param.enh_phase_delta_array[src_idx];
|
||||
pcfr->enh_phase_delta_array[dst_idx] = get_u16_lsb(data);
|
||||
pcfr->enh_phase_delta_array[dst_idx + 1] = get_u16_msb(data);
|
||||
}
|
||||
|
||||
wlan_objmgr_psoc_release_ref(psoc, WLAN_CFR_ID);
|
||||
wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
|
||||
qdf_mem_free(param.gain_stop_index_array);
|
||||
qdf_mem_free(param.enh_phase_delta_array);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */
|
||||
|
||||
#ifdef DIRECT_BUF_RX_ENABLE
|
||||
/**
|
||||
* enh_prepare_cfr_header_txstatus() - Prepare CFR metadata for TX failures
|
||||
@ -2012,6 +2308,69 @@ target_if_unregister_phase_delta_for_rcc_event_handler(struct wlan_objmgr_psoc
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT
|
||||
static QDF_STATUS
|
||||
target_if_register_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc
|
||||
*psoc)
|
||||
{
|
||||
wmi_unified_t wmi_hdl;
|
||||
QDF_STATUS ret = QDF_STATUS_SUCCESS;
|
||||
|
||||
wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc);
|
||||
if (!wmi_hdl) {
|
||||
cfr_err("Unable to get wmi handle");
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
ret = wmi_unified_register_event_handler
|
||||
(wmi_hdl, wmi_pdev_enhanced_aoa_phasedelta_eventid,
|
||||
target_if_pdev_enhanced_aoa_phasedelta_event_handler,
|
||||
WMI_RX_UMAC_CTX);
|
||||
|
||||
/*
|
||||
* Event registration is called per pdev
|
||||
* Ignore error if event is already registered.
|
||||
*/
|
||||
if (ret == QDF_STATUS_E_FAILURE)
|
||||
ret = QDF_STATUS_SUCCESS;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
target_if_unregister_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc
|
||||
*psoc)
|
||||
{
|
||||
wmi_unified_t wmi_hdl;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
|
||||
wmi_hdl = get_wmi_unified_hdl_from_psoc(psoc);
|
||||
if (!wmi_hdl) {
|
||||
cfr_err("Unable to get wmi handle");
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
status = wmi_unified_unregister_event
|
||||
(wmi_hdl, wmi_pdev_enhanced_aoa_phasedelta_eventid);
|
||||
|
||||
return status;
|
||||
}
|
||||
#else
|
||||
static QDF_STATUS
|
||||
target_if_register_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc
|
||||
*psoc)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
target_if_unregister_enh_phase_for_rcc_event_handler(struct wlan_objmgr_psoc
|
||||
*psoc)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */
|
||||
|
||||
/**
|
||||
* target_if_register_tx_completion_enh_event_handler() - Register callback for
|
||||
* WMI TX completion event
|
||||
@ -2292,6 +2651,12 @@ QDF_STATUS cfr_enh_init_pdev(struct wlan_objmgr_psoc *psoc,
|
||||
return status;
|
||||
}
|
||||
|
||||
status = target_if_register_enh_phase_for_rcc_event_handler(psoc);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
cfr_err("Failed to register with phase delta event handler");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = target_if_register_phase_delta_for_rcc_event_handler(psoc);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
cfr_err("Failed to register with phase delta event handler");
|
||||
@ -2442,6 +2807,10 @@ QDF_STATUS cfr_enh_deinit_pdev(struct wlan_objmgr_psoc *psoc,
|
||||
if (status != QDF_STATUS_SUCCESS)
|
||||
cfr_err("Failed to register with dbr");
|
||||
|
||||
status = target_if_unregister_enh_phase_for_rcc_event_handler(psoc);
|
||||
if (status != QDF_STATUS_SUCCESS)
|
||||
cfr_err("Failed to unregister phase delta handler");
|
||||
|
||||
status = target_if_unregister_phase_delta_for_rcc_event_handler(psoc);
|
||||
if (status != QDF_STATUS_SUCCESS)
|
||||
cfr_err("Failed to unregister phase delta handler");
|
||||
|
Loading…
Reference in New Issue
Block a user