diff --git a/wmi/inc/wmi_unified_cfr_api.h b/wmi/inc/wmi_unified_cfr_api.h index bffbd06cda..f1fcee72d9 100644 --- a/wmi/inc/wmi_unified_cfr_api.h +++ b/wmi/inc/wmi_unified_cfr_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2019, 2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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 @@ -69,6 +70,18 @@ QDF_STATUS wmi_extract_cfr_pdev_phase_delta_event(wmi_unified_t wmi_handle, void *evt_buf, struct wmi_cfr_phase_delta_param *param); + +#ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT +QDF_STATUS +wmi_extract_cfr_pdev_enhanced_aoa_phasedelta_event_fixed_param + (wmi_unified_t wmi_handle, void *evt_buf, + struct wmi_cfr_enh_phase_delta_param *param); + +QDF_STATUS +wmi_extract_cfr_pdev_enhanced_aoa_phasedelta_event_data + (wmi_unified_t wmi_handle, void *evt_buf, + struct wmi_cfr_enh_phase_delta_param *param); +#endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ #endif #endif /* WLAN_CFR_ENABLE */ #endif /* _WMI_UNIFIED_CFR_API_H_ */ diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index b5277bc213..7a31cab411 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -5347,6 +5347,9 @@ typedef enum { wmi_peer_ptqm_migration_response_eventid, #endif wmi_pdev_set_rf_path_resp_eventid, +#ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT + wmi_pdev_enhanced_aoa_phasedelta_eventid, +#endif wmi_events_max, } wmi_conv_event_id; @@ -9608,6 +9611,20 @@ struct wmi_cfr_phase_delta_param { uint32_t ibf_cal_val[WMI_MAX_CHAINS_PHASE]; }; +#ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT +struct wmi_cfr_enh_phase_delta_param { + uint32_t pdev_id; + uint32_t freq; + uint32_t max_chains; + uint32_t data_for_chainmask; + uint32_t xbar_config; + uint32_t ibf_cal_val[WMI_HOST_MAX_NUM_CHAINS]; + uint32_t array_size; + uint32_t *gain_stop_index_array; + uint32_t *enh_phase_delta_array; +}; +#endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ + /** * struct wmi_host_oem_indirect_data - Indirect OEM data * @pdev_id: pdev id diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 1fe61eae0a..1f22bfbe8d 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -3069,6 +3069,17 @@ QDF_STATUS (*extract_cfr_phase_param)(wmi_unified_t wmi_handle, void *evt_buf, struct wmi_cfr_phase_delta_param *param); +#ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT +QDF_STATUS +(*extract_cfr_enh_phase_data)(wmi_unified_t wmi_handle, + void *evt_buf, + struct wmi_cfr_enh_phase_delta_param *param); +QDF_STATUS +(*extract_cfr_enh_phase_fixed_param)( + wmi_unified_t wmi_handle, + void *evt_buf, + struct wmi_cfr_enh_phase_delta_param *param); +#endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ #endif QDF_STATUS (*send_set_halphy_cal)(wmi_unified_t wmi_handle, diff --git a/wmi/src/wmi_unified_cfr_api.c b/wmi/src/wmi_unified_cfr_api.c index 10d48ce3b4..cf113e2881 100644 --- a/wmi/src/wmi_unified_cfr_api.c +++ b/wmi/src/wmi_unified_cfr_api.c @@ -62,5 +62,33 @@ wmi_extract_cfr_pdev_phase_delta_event(wmi_unified_t wmi_handle, param); return QDF_STATUS_E_FAILURE; } + +#ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT +QDF_STATUS +wmi_extract_cfr_pdev_enhanced_aoa_phasedelta_event_fixed_param( + wmi_unified_t wmi_handle, + void *evt_buf, + struct wmi_cfr_enh_phase_delta_param *param) +{ + if (wmi_handle->ops->extract_cfr_enh_phase_fixed_param) + return wmi_handle->ops->extract_cfr_enh_phase_fixed_param + (wmi_handle, evt_buf, param); + + return QDF_STATUS_E_FAILURE; +} + +QDF_STATUS +wmi_extract_cfr_pdev_enhanced_aoa_phasedelta_event_data( + wmi_unified_t wmi_handle, void *evt_buf, + struct wmi_cfr_enh_phase_delta_param *param) +{ + if (wmi_handle->ops->extract_cfr_enh_phase_data) + return wmi_handle->ops->extract_cfr_enh_phase_data(wmi_handle, + evt_buf, + param); + + return QDF_STATUS_E_FAILURE; +} +#endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ #endif /* WLAN_ENH_CFR_ENABLE */ #endif /* WLAN_CFR_ENABLE */ diff --git a/wmi/src/wmi_unified_cfr_tlv.c b/wmi/src/wmi_unified_cfr_tlv.c index ea8813c634..345178e43c 100644 --- a/wmi/src/wmi_unified_cfr_tlv.c +++ b/wmi/src/wmi_unified_cfr_tlv.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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 @@ -281,7 +282,127 @@ extract_cfr_phase_param_tlv(wmi_unified_t wmi_handle, return QDF_STATUS_SUCCESS; } -#endif + +#ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT +static QDF_STATUS +extract_cfr_enh_phase_fixed_param_tlv + (wmi_unified_t wmi_handle, + void *evt_buf, + struct wmi_cfr_enh_phase_delta_param *param) +{ + WMI_PDEV_ENHANCED_AOA_PHASEDELTA_EVENTID_param_tlvs *ev_buf; + wmi_pdev_enhanced_aoa_phasedelta_evt_fixed_param *fixed_param; + + ev_buf = (WMI_PDEV_ENHANCED_AOA_PHASEDELTA_EVENTID_param_tlvs *)evt_buf; + if (!ev_buf) { + wmi_err("Invalid cfr enh aoa phase delta event buffer"); + return QDF_STATUS_E_INVAL; + } + + fixed_param = ev_buf->fixed_param; + if (!fixed_param) { + wmi_err("cfr enh aoa event fixed_param is NULL"); + return QDF_STATUS_E_NULL_VALUE; + } + + param->freq = fixed_param->freq; + param->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host + (wmi_handle, fixed_param->pdev_id); + + param->max_chains = + WMI_AOA_MAX_SUPPORTED_CHAINS_GET(fixed_param->chain_info); + param->data_for_chainmask = + WMI_AOA_SUPPORTED_CHAINMASK_GET(fixed_param->chain_info); + param->xbar_config = fixed_param->xbar_config; + + if (sizeof(param->ibf_cal_val) < + sizeof(fixed_param->per_chain_ibf_cal_val)) { + wmi_err("ibf_cal_val can not hold all values from event data"); + return QDF_STATUS_E_RANGE; + } + + qdf_mem_copy(param->ibf_cal_val, fixed_param->per_chain_ibf_cal_val, + QDF_MIN(sizeof(param->ibf_cal_val), + sizeof(fixed_param->per_chain_ibf_cal_val))); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS +populate_enhanced_aoa_data(uint32_t *dst_array, uint32_t *src_array, + wmi_enhanced_aoa_gain_phase_data_hdr *data_hdr, + uint32_t offset, uint32_t dst_size) +{ + uint32_t src_size = WMI_AOA_NUM_ENTIRES_GET(data_hdr->data_info) * + sizeof(uint32_t); + + if (src_size > dst_size) { + wmi_err("the amount of data can not fit in the host array"); + return QDF_STATUS_E_RANGE; + } + + qdf_mem_copy(dst_array, src_array + offset, src_size); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS +extract_cfr_enh_phase_data_tlv(wmi_unified_t wmi_handle, + void *evt_buf, + struct wmi_cfr_enh_phase_delta_param *param) +{ + WMI_PDEV_ENHANCED_AOA_PHASEDELTA_EVENTID_param_tlvs *ev_buf; + wmi_enhanced_aoa_gain_phase_data_hdr *data_hdr; + QDF_STATUS status; + uint32_t *dst_array = NULL; + uint32_t i, offset = 0; + uint8_t data_type; + + ev_buf = (WMI_PDEV_ENHANCED_AOA_PHASEDELTA_EVENTID_param_tlvs *)evt_buf; + + if (!ev_buf) { + wmi_err("Invalid cfr enh aoa phase delta event buffer"); + return QDF_STATUS_E_INVAL; + } + + if (!ev_buf->aoa_data_hdr) { + wmi_err("data headers NULL.. investigate"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (!ev_buf->aoa_data_buf) { + wmi_err("data bufs NULL.. investigate"); + return QDF_STATUS_E_NULL_VALUE; + } + + for (i = 0; i < ev_buf->num_aoa_data_hdr; i++) { + data_hdr = &ev_buf->aoa_data_hdr[i]; + data_type = WMI_AOA_DATA_TYPE_GET(data_hdr->data_info); + + if (data_type == WMI_PHASE_DELTA_ARRAY) { + dst_array = param->enh_phase_delta_array; + } else if (data_type == WMI_GAIN_GROUP_STOP_ARRAY) { + dst_array = param->gain_stop_index_array; + } else { + wmi_err("invalid aoa data type received"); + return QDF_STATUS_E_INVAL; + } + + status = populate_enhanced_aoa_data + (dst_array, ev_buf->aoa_data_buf, + data_hdr, offset, param->array_size); + if (status) { + wmi_err("error in populating aoa data"); + return status; + } + + offset += WMI_AOA_NUM_ENTIRES_GET(data_hdr->data_info); + } + + return QDF_STATUS_SUCCESS; +} +#endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ +#endif /* WLAN_ENH_CFR_ENABLE */ static QDF_STATUS send_peer_cfr_capture_cmd_tlv(wmi_unified_t wmi_handle, struct peer_cfr_params *param) @@ -333,6 +454,19 @@ static inline void wmi_enh_cfr_attach_tlv(wmi_unified_t wmi_handle) } #endif +#ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT +static void wmi_cfr_attach_enh_aoa_tlv(struct wmi_ops *ops) +{ + ops->extract_cfr_enh_phase_data = extract_cfr_enh_phase_data_tlv; + ops->extract_cfr_enh_phase_fixed_param = + extract_cfr_enh_phase_fixed_param_tlv; +} +#else +static void wmi_cfr_attach_enh_aoa_tlv(struct wmi_ops *ops) +{ +} +#endif /* WLAN_RCC_ENHANCED_AOA_SUPPORT */ + void wmi_cfr_attach_tlv(wmi_unified_t wmi_handle) { struct wmi_ops *ops = wmi_handle->ops; @@ -341,6 +475,7 @@ void wmi_cfr_attach_tlv(wmi_unified_t wmi_handle) ops->extract_cfr_peer_tx_event_param = extract_cfr_peer_tx_event_param_tlv; ops->extract_cfr_phase_param = extract_cfr_phase_param_tlv; + wmi_cfr_attach_enh_aoa_tlv(ops); wmi_enh_cfr_attach_tlv(wmi_handle); } #endif /* WLAN_CFR_ENABLE */ diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index e803de72c7..d5ab92e3e5 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -22148,6 +22148,10 @@ static void populate_tlv_events_id(WMI_EVT_ID *event_ids) #endif event_ids[wmi_pdev_set_rf_path_resp_eventid] = WMI_PDEV_SET_RF_PATH_RESP_EVENTID; +#ifdef WLAN_RCC_ENHANCED_AOA_SUPPORT + event_ids[wmi_pdev_enhanced_aoa_phasedelta_eventid] = + WMI_PDEV_ENHANCED_AOA_PHASEDELTA_EVENTID; +#endif } #ifdef WLAN_FEATURE_LINK_LAYER_STATS