qcacmn: Extract enhanced aoa data
Changes to extract enhanced aoa data from WMI event CRs-Fixed: 3553725 Change-Id: I4a37fdb889cd5d461ee6ef92966a042aeed91fc8
Этот коммит содержится в:

коммит произвёл
Rahul Choudhary

родитель
2a073ca079
Коммит
0536af115e
@@ -114,8 +114,6 @@
|
|||||||
|
|
||||||
#define STREAMFS_NUM_SUBBUF_WAIKIKI 127
|
#define STREAMFS_NUM_SUBBUF_WAIKIKI 127
|
||||||
|
|
||||||
#define MAX_AGC_GAIN_VALUE_WAIKIKI 64
|
|
||||||
|
|
||||||
/* Max 4 users in MU case for Spruce */
|
/* Max 4 users in MU case for Spruce */
|
||||||
#define SPRUCE_CFR_MU_USERS 4
|
#define SPRUCE_CFR_MU_USERS 4
|
||||||
|
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
#include <target_if_direct_buf_rx_api.h>
|
#include <target_if_direct_buf_rx_api.h>
|
||||||
#include <target_if_cfr_enh.h>
|
#include <target_if_cfr_enh.h>
|
||||||
#include "cdp_txrx_ctrl.h"
|
#include "cdp_txrx_ctrl.h"
|
||||||
|
#include <wlan_reg_services_api.h>
|
||||||
|
|
||||||
#define CMN_NOISE_FLOOR (-96)
|
#define CMN_NOISE_FLOOR (-96)
|
||||||
#define NUM_CHAINS_FW_TO_HOST(n) ((1 << ((n) + 1)) - 1)
|
#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
|
#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.
|
* consider target_type.
|
||||||
* @target_type: target type of the pdev
|
* @target_type: target type of the pdev
|
||||||
* @meta: pointer to CFR metadata
|
* @meta: pointer to CFR metadata
|
||||||
@@ -942,21 +943,222 @@ bool target_if_cfr_get_11be_support_flag(uint8_t pdev_id,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
#ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
static inline
|
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)
|
/* if default gain table return true */
|
||||||
return MAX_AGC_GAIN_VALUE_WAIKIKI;
|
if (!tbl_idx)
|
||||||
else
|
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;
|
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;
|
uint8_t srng_id = 0;
|
||||||
struct wlan_lmac_if_rx_ops *rx_ops;
|
struct wlan_lmac_if_rx_ops *rx_ops;
|
||||||
uint32_t target_type;
|
uint32_t target_type;
|
||||||
uint16_t pdelta, gain;
|
|
||||||
uint16_t gain_info[HOST_MAX_CHAINS];
|
uint16_t gain_info[HOST_MAX_CHAINS];
|
||||||
bool invalid_gain_table_idx = false;
|
bool invalid_gain_table_idx = false;
|
||||||
uint32_t target_max_agc_gain = 0;
|
uint32_t max_agc_gain = 0;
|
||||||
bool supports_11be;
|
bool supports_11be;
|
||||||
uint8_t pdev_id;
|
uint8_t pdev_id;
|
||||||
struct target_psoc_info *tgt_hdl;
|
struct target_psoc_info *tgt_hdl;
|
||||||
|
|
||||||
|
|
||||||
if (qdf_unlikely(!pdev)) {
|
if (qdf_unlikely(!pdev)) {
|
||||||
cfr_err("pdev is null\n");
|
cfr_err("pdev is null\n");
|
||||||
qdf_nbuf_free(nbuf);
|
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[6] = get_u16_lsb(cfr_info->agc_gain_info3);
|
||||||
gain_info[7] = get_u16_msb(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++) {
|
for (i = 0; i < HOST_MAX_CHAINS; i++) {
|
||||||
meta->agc_gain[i] = get_gain_db(gain_info[i]);
|
meta->agc_gain[i] = get_gain_db(gain_info[i]);
|
||||||
meta->agc_gain_tbl_index[i] = get_gain_table_idx(gain_info[i]);
|
meta->agc_gain_tbl_index[i] = get_gain_table_idx(gain_info[i]);
|
||||||
|
max_agc_gain = get_max_agc_gain(vdev,
|
||||||
if (pcfr->is_aoa_for_rcc_support &&
|
meta->agc_gain_tbl_index[i],
|
||||||
(i < pcfr->max_aoa_chains) &&
|
pcfr,
|
||||||
(meta->agc_gain_tbl_index[i] != 0)) {
|
supports_11be);
|
||||||
|
if (!is_valid_gain_table_idx(meta->agc_gain_tbl_index[i],
|
||||||
|
pcfr)) {
|
||||||
cfr_debug("Invalid gain table index reported");
|
cfr_debug("Invalid gain table index reported");
|
||||||
invalid_gain_table_idx = true;
|
invalid_gain_table_idx = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meta->agc_gain[i] > target_max_agc_gain)
|
if (meta->agc_gain[i] > max_agc_gain)
|
||||||
meta->agc_gain[i] = target_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
|
* Do not derive the chain phase when capability is not set Or
|
||||||
* when an invalid gain table index is reported by Hardware.
|
* when an invalid gain table index is reported by Hardware.
|
||||||
*/
|
*/
|
||||||
if (wlan_vdev_mlme_is_special_vdev(vdev)) {
|
if (pcfr->is_aoa_for_rcc_support) {
|
||||||
for (i = 0; i < pcfr->max_aoa_chains; i++)
|
if (supports_11be) {
|
||||||
meta->chain_phase[i] = INVALID_PHASE_DELTA;
|
populate_enh_chain_phase(vdev, pcfr,
|
||||||
}
|
meta, invalid_gain_table_idx);
|
||||||
|
} else {
|
||||||
if (pcfr->is_aoa_for_rcc_support && !invalid_gain_table_idx) {
|
populate_chain_phase(vdev, pcfr,
|
||||||
for (i = 0; i < pcfr->max_aoa_chains; i++) {
|
meta, invalid_gain_table_idx);
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1668,6 +1812,158 @@ target_if_pdev_aoa_phasedaelta_event_handler(ol_scn_t sc,
|
|||||||
return retval;
|
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
|
#ifdef DIRECT_BUF_RX_ENABLE
|
||||||
/**
|
/**
|
||||||
* enh_prepare_cfr_header_txstatus() - Prepare CFR metadata for TX failures
|
* 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;
|
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
|
* target_if_register_tx_completion_enh_event_handler() - Register callback for
|
||||||
* WMI TX completion event
|
* WMI TX completion event
|
||||||
@@ -2292,6 +2651,12 @@ QDF_STATUS cfr_enh_init_pdev(struct wlan_objmgr_psoc *psoc,
|
|||||||
return status;
|
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);
|
status = target_if_register_phase_delta_for_rcc_event_handler(psoc);
|
||||||
if (status != QDF_STATUS_SUCCESS) {
|
if (status != QDF_STATUS_SUCCESS) {
|
||||||
cfr_err("Failed to register with phase delta event handler");
|
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)
|
if (status != QDF_STATUS_SUCCESS)
|
||||||
cfr_err("Failed to register with dbr");
|
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);
|
status = target_if_unregister_phase_delta_for_rcc_event_handler(psoc);
|
||||||
if (status != QDF_STATUS_SUCCESS)
|
if (status != QDF_STATUS_SUCCESS)
|
||||||
cfr_err("Failed to unregister phase delta handler");
|
cfr_err("Failed to unregister phase delta handler");
|
||||||
|
Ссылка в новой задаче
Block a user