Parcourir la source

qcacmn: Add enhanced AoA support

WMI changes to support enhanced AoA for CFR

CRs-Fixed: 3553719
Change-Id: Ic09940d3ce7d4eaed81e666b0c891294a82bc4bb
Shwetha G K il y a 1 an
Parent
commit
923e2c3f6d

+ 13 - 0
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_ */

+ 17 - 0
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

+ 11 - 0
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,

+ 28 - 0
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 */

+ 136 - 1
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 */

+ 4 - 0
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