Browse Source

qcacmn: Add support to send wfa test config to FW

Host add support to send WFA test configs to FW using WMI command
i.e. WMI_WFA_CONFIG_CMDID.

Change-Id: Id9bdec16c69a8c16cb4ce1fac87688023c768ee6
CRs-Fixed: 2772004
Abhishek Ambure 4 years ago
parent
commit
7c64a2c250

+ 12 - 0
wmi/inc/wmi_unified_api.h

@@ -3175,6 +3175,18 @@ QDF_STATUS wmi_extract_sar_cap_service_ready_ext(
 QDF_STATUS wmi_unified_fw_test_cmd(wmi_unified_t wmi_handle,
 				   struct set_fwtest_params *wmi_fwtest);
 
+/**
+ * wmi_unified_wfa_test_cmd() - send wfa test command to fw.
+ * @handle: wmi handle
+ * @wmi_fwtest: wfa test param
+ *
+ * This function send wfa test command to fw.
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_wfa_test_cmd(wmi_unified_t wmi_handle,
+				    struct set_wfatest_params *wmi_wfatest);
+
 /**
  * wmi_unified_peer_rx_reorder_queue_setup_send() - send rx reorder queue
  *      setup command to fw

+ 52 - 0
wmi/inc/wmi_unified_param.h

@@ -2784,6 +2784,58 @@ struct set_fwtest_params {
 	uint32_t value;
 };
 
+/**
+ * enum wfa_test_cmds - WFA test config command
+ * @WFA_CONFIG_RXNE: configure an override for the RSNXE Used
+ * @WFA_CONFIG_CSA: configure the driver to ignore CSA
+ * @WFA_CONFIG_OCV: configure OCI
+ * @WFA_CONFIG_SA_QUERY: configure driver/firmware to ignore SAquery timeout
+ */
+enum wfa_test_cmds {
+	WFA_CONFIG_RXNE,
+	WFA_CONFIG_CSA,
+	WFA_CONFIG_OCV,
+	WFA_CONFIG_SA_QUERY,
+};
+
+/**
+ * enum wmi_host_wfa_config_ocv_frmtype - OCI override frame type
+ * @WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ: SA Query Request frame
+ * @WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP: SA Query Response frame
+ * @WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ: FT Reassociation Req frm
+ * @WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ: FILS Reassoc Req frm
+ */
+enum wmi_host_wfa_config_ocv_frmtype {
+	WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ          = 0x00000001,
+	WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP          = 0x00000002,
+	WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ       = 0x00000004,
+	WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ     = 0x00000008,
+};
+
+/**
+ * struct ocv_wfatest_params - ocv WFA test params
+ * @frame_type: frame type req for OCV config
+ * @freq: frequency to set
+ */
+struct ocv_wfatest_params {
+	uint8_t frame_type;
+	uint32_t freq;
+};
+
+/**
+ * struct set_wfatest_params - WFA test params
+ * @vdev_id: vdev id
+ * @value: wfa test config value
+ * @cmd: WFA test command
+ * @ocv_param: pointer to ocv params
+ */
+struct set_wfatest_params {
+	uint8_t vdev_id;
+	uint32_t value;
+	enum wfa_test_cmds cmd;
+	struct ocv_wfatest_params *ocv_param;
+};
+
 /*
  * msduq_update_params - MSDUQ update param structure
  * @tid_num: TID number

+ 2 - 0
wmi/inc/wmi_unified_priv.h

@@ -1866,6 +1866,8 @@ QDF_STATUS (*send_adfs_ch_cfg_cmd)(wmi_unified_t wmi_handle,
 QDF_STATUS (*send_fw_test_cmd)(wmi_unified_t wmi_handle,
 			       struct set_fwtest_params *wmi_fwtest);
 
+QDF_STATUS (*send_wfa_test_cmd)(wmi_unified_t wmi_handle,
+				struct set_wfatest_params *wmi_wfatest);
 #ifdef WLAN_FEATURE_ACTION_OUI
 QDF_STATUS (*send_action_oui_cmd)(wmi_unified_t wmi_handle,
 				  struct action_oui_request *req);

+ 10 - 0
wmi/src/wmi_unified_api.c

@@ -1006,6 +1006,16 @@ QDF_STATUS wmi_unified_fw_test_cmd(wmi_unified_t wmi_handle,
 
 }
 
+QDF_STATUS wmi_unified_wfa_test_cmd(wmi_unified_t wmi_handle,
+				    struct set_wfatest_params *wmi_wfatest)
+{
+	if (wmi_handle->ops->send_wfa_test_cmd)
+		return wmi_handle->ops->send_wfa_test_cmd(wmi_handle,
+							  wmi_wfatest);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
 QDF_STATUS wmi_unified_unit_test_cmd(wmi_unified_t wmi_handle,
 				     struct wmi_unit_test_cmd *wmi_utest)
 {

+ 178 - 0
wmi/src/wmi_unified_tlv.c

@@ -8085,6 +8085,183 @@ QDF_STATUS send_fw_test_cmd_tlv(wmi_unified_t wmi_handle,
 	return QDF_STATUS_SUCCESS;
 }
 
+static uint16_t wfa_config_param_len(enum wfa_test_cmds config)
+{
+	uint16_t len = 0;
+
+	if (config == WFA_CONFIG_RXNE)
+		len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_rsnxe);
+	else
+		len += WMI_TLV_HDR_SIZE;
+
+	if (config == WFA_CONFIG_CSA)
+		len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_csa);
+	else
+		len += WMI_TLV_HDR_SIZE;
+
+	if (config == WFA_CONFIG_OCV)
+		len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_ocv);
+	else
+		len += WMI_TLV_HDR_SIZE;
+
+	if (config == WFA_CONFIG_SA_QUERY)
+		len += WMI_TLV_HDR_SIZE + sizeof(wmi_wfa_config_saquery);
+	else
+		len += WMI_TLV_HDR_SIZE;
+
+	return len;
+}
+
+/**
+ * wmi_fill_ocv_frame_type() - Fill host ocv frm type into WMI ocv frm type.
+ * @host_frmtype: Host defined OCV frame type
+ * @ocv_frmtype: Pointer to hold WMI OCV frame type
+ *
+ * This function converts and fills host defined OCV frame type into WMI OCV
+ * frame type.
+ *
+ * Return: CDF STATUS
+ */
+static QDF_STATUS
+wmi_fill_ocv_frame_type(uint32_t host_frmtype, uint32_t *ocv_frmtype)
+{
+	switch (host_frmtype) {
+	case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ:
+		*ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_REQ;
+		break;
+
+	case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP:
+		*ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_SAQUERY_RSP;
+		break;
+
+	case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ:
+		*ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FT_REASSOC_REQ;
+		break;
+
+	case WMI_HOST_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ:
+		*ocv_frmtype = WMI_WFA_CONFIG_OCV_FRMTYPE_FILS_REASSOC_REQ;
+		break;
+
+	default:
+		WMI_LOGE("%s: invalid command type cmd %d",
+			 __func__, host_frmtype);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_wfa_test_cmd_tlv() - send wfa test command to fw.
+ * @wmi_handle: wmi handle
+ * @wmi_wfatest: wfa test command
+ *
+ * This function sends wfa test command to fw.
+ *
+ * Return: CDF STATUS
+ */
+static
+QDF_STATUS send_wfa_test_cmd_tlv(wmi_unified_t wmi_handle,
+				 struct set_wfatest_params *wmi_wfatest)
+{
+	wmi_wfa_config_cmd_fixed_param *cmd;
+	wmi_wfa_config_rsnxe *rxne;
+	wmi_wfa_config_csa *csa;
+	wmi_wfa_config_ocv *ocv;
+	wmi_wfa_config_saquery *saquery;
+	wmi_buf_t wmi_buf;
+	uint16_t len = sizeof(*cmd);
+	uint8_t *buf_ptr;
+
+	len += wfa_config_param_len(wmi_wfatest->cmd);
+	wmi_buf = wmi_buf_alloc(wmi_handle, len);
+	if (!wmi_buf)
+		return QDF_STATUS_E_NOMEM;
+
+	cmd = (wmi_wfa_config_cmd_fixed_param *)wmi_buf_data(wmi_buf);
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_wfa_config_cmd_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN(
+					 wmi_wfa_config_cmd_fixed_param));
+
+	cmd->vdev_id = wmi_wfatest->vdev_id;
+	buf_ptr = (uint8_t *)(cmd + 1);
+
+	if (wmi_wfatest->cmd == WFA_CONFIG_RXNE) {
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       sizeof(wmi_wfa_config_rsnxe));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_rsnxe,
+			       WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_rsnxe));
+		rxne = (wmi_wfa_config_rsnxe *)buf_ptr;
+		rxne->rsnxe_param = wmi_wfatest->value;
+		buf_ptr += sizeof(wmi_wfa_config_rsnxe);
+	} else {
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+		buf_ptr += WMI_TLV_HDR_SIZE;
+	}
+
+	if (wmi_wfatest->cmd == WFA_CONFIG_CSA) {
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       sizeof(wmi_wfa_config_csa));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_csa,
+			       WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_csa));
+		csa = (wmi_wfa_config_csa *)buf_ptr;
+		csa->ignore_csa = wmi_wfatest->value;
+		buf_ptr += sizeof(wmi_wfa_config_csa);
+	} else {
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+		buf_ptr += WMI_TLV_HDR_SIZE;
+	}
+
+	if (wmi_wfatest->cmd == WFA_CONFIG_OCV) {
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       sizeof(wmi_wfa_config_ocv));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_ocv,
+			       WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_ocv));
+		ocv = (wmi_wfa_config_ocv *)buf_ptr;
+
+		if (wmi_fill_ocv_frame_type(wmi_wfatest->ocv_param->frame_type,
+					    &ocv->frame_types))
+			goto error;
+
+		ocv->chan_freq = wmi_wfatest->ocv_param->freq;
+		buf_ptr += sizeof(wmi_wfa_config_ocv);
+	} else {
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+		buf_ptr += WMI_TLV_HDR_SIZE;
+	}
+
+	if (wmi_wfatest->cmd == WFA_CONFIG_SA_QUERY) {
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       sizeof(wmi_wfa_config_saquery));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_STRUC_wmi_wfa_config_saquery,
+			       WMITLV_GET_STRUCT_TLVLEN(wmi_wfa_config_saquery));
+
+		saquery = (wmi_wfa_config_saquery *)buf_ptr;
+		saquery->remain_connect_on_saquery_timeout = wmi_wfatest->value;
+	} else {
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, 0);
+		buf_ptr += WMI_TLV_HDR_SIZE;
+	}
+
+	wmi_mtrace(WMI_WFA_CONFIG_CMDID, wmi_wfatest->vdev_id, 0);
+	if (wmi_unified_cmd_send(wmi_handle, wmi_buf, len,
+				 WMI_WFA_CONFIG_CMDID)) {
+		WMI_LOGP("%s: failed to send wfa test command", __func__);
+		goto error;
+	}
+
+	return QDF_STATUS_SUCCESS;
+
+error:
+	wmi_buf_free(wmi_buf);
+	return QDF_STATUS_E_FAILURE;
+}
+
 /**
  * send_unit_test_cmd_tlv() - send unit test command to fw.
  * @wmi_handle: wmi handle
@@ -13917,6 +14094,7 @@ struct wmi_ops tlv_ops =  {
 	.extract_profile_ctx = extract_profile_ctx_tlv,
 	.extract_profile_data = extract_profile_data_tlv,
 	.send_fw_test_cmd = send_fw_test_cmd_tlv,
+	.send_wfa_test_cmd = send_wfa_test_cmd_tlv,
 	.send_power_dbg_cmd = send_power_dbg_cmd_tlv,
 	.extract_service_ready_ext = extract_service_ready_ext_tlv,
 	.extract_service_ready_ext2 = extract_service_ready_ext2_tlv,