linux/drivers/net/ipa/ipa_qmi_msg.c
Alex Elder 530f9216a9 soc: qcom: ipa: AP/modem communications
This patch implements two forms of out-of-band communication between
the AP and modem.

  - QMI is a mechanism that allows clients running on the AP
    interact with services running on the modem (and vice-versa).
    The AP IPA driver uses QMI to communicate with the corresponding
    IPA driver resident on the modem, to agree on parameters used
    with the IPA hardware and to ensure both sides are ready before
    entering operational mode.

  - SMP2P is a more primitive mechanism available for the modem and
    AP to communicate with each other.  It provides a means for either
    the AP or modem to interrupt the other, and furthermore, to provide
    32 bits worth of information.  The IPA driver uses SMP2P to tell
    the modem what the state of the IPA clock was in the event of a
    crash.  This allows the modem to safely access the IPA hardware
    (or avoid doing so) when a crash occurs, for example, to access
    information within the IPA hardware.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-03-08 22:07:10 -07:00

664 lines
17 KiB
C

// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
* Copyright (C) 2018-2020 Linaro Ltd.
*/
#include <linux/stddef.h>
#include <linux/soc/qcom/qmi.h>
#include "ipa_qmi_msg.h"
/* QMI message structure definition for struct ipa_indication_register_req */
struct qmi_elem_info ipa_indication_register_req_ei[] = {
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_indication_register_req,
master_driver_init_complete_valid),
.tlv_type = 0x10,
.offset = offsetof(struct ipa_indication_register_req,
master_driver_init_complete_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_indication_register_req,
master_driver_init_complete),
.tlv_type = 0x10,
.offset = offsetof(struct ipa_indication_register_req,
master_driver_init_complete),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_indication_register_req,
data_usage_quota_reached_valid),
.tlv_type = 0x11,
.offset = offsetof(struct ipa_indication_register_req,
data_usage_quota_reached_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_indication_register_req,
data_usage_quota_reached),
.tlv_type = 0x11,
.offset = offsetof(struct ipa_indication_register_req,
data_usage_quota_reached),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_indication_register_req,
ipa_mhi_ready_ind_valid),
.tlv_type = 0x11,
.offset = offsetof(struct ipa_indication_register_req,
ipa_mhi_ready_ind_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_indication_register_req,
ipa_mhi_ready_ind),
.tlv_type = 0x11,
.offset = offsetof(struct ipa_indication_register_req,
ipa_mhi_ready_ind),
},
{
.data_type = QMI_EOTI,
},
};
/* QMI message structure definition for struct ipa_indication_register_rsp */
struct qmi_elem_info ipa_indication_register_rsp_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_indication_register_rsp,
rsp),
.tlv_type = 0x02,
.offset = offsetof(struct ipa_indication_register_rsp,
rsp),
.ei_array = qmi_response_type_v01_ei,
},
{
.data_type = QMI_EOTI,
},
};
/* QMI message structure definition for struct ipa_driver_init_complete_req */
struct qmi_elem_info ipa_driver_init_complete_req_ei[] = {
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_driver_init_complete_req,
status),
.tlv_type = 0x01,
.offset = offsetof(struct ipa_driver_init_complete_req,
status),
},
{
.data_type = QMI_EOTI,
},
};
/* QMI message structure definition for struct ipa_driver_init_complete_rsp */
struct qmi_elem_info ipa_driver_init_complete_rsp_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_driver_init_complete_rsp,
rsp),
.tlv_type = 0x02,
.elem_size = offsetof(struct ipa_driver_init_complete_rsp,
rsp),
.ei_array = qmi_response_type_v01_ei,
},
{
.data_type = QMI_EOTI,
},
};
/* QMI message structure definition for struct ipa_init_complete_ind */
struct qmi_elem_info ipa_init_complete_ind_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_complete_ind,
status),
.tlv_type = 0x02,
.elem_size = offsetof(struct ipa_init_complete_ind,
status),
.ei_array = qmi_response_type_v01_ei,
},
{
.data_type = QMI_EOTI,
},
};
/* QMI message structure definition for struct ipa_mem_bounds */
struct qmi_elem_info ipa_mem_bounds_ei[] = {
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_mem_bounds, start),
.offset = offsetof(struct ipa_mem_bounds, start),
},
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_mem_bounds, end),
.offset = offsetof(struct ipa_mem_bounds, end),
},
{
.data_type = QMI_EOTI,
},
};
/* QMI message structure definition for struct ipa_mem_array */
struct qmi_elem_info ipa_mem_array_ei[] = {
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_mem_array, start),
.offset = offsetof(struct ipa_mem_array, start),
},
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_mem_array, count),
.offset = offsetof(struct ipa_mem_array, count),
},
{
.data_type = QMI_EOTI,
},
};
/* QMI message structure definition for struct ipa_mem_range */
struct qmi_elem_info ipa_mem_range_ei[] = {
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_mem_range, start),
.offset = offsetof(struct ipa_mem_range, start),
},
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_mem_range, size),
.offset = offsetof(struct ipa_mem_range, size),
},
{
.data_type = QMI_EOTI,
},
};
/* QMI message structure definition for struct ipa_init_modem_driver_req */
struct qmi_elem_info ipa_init_modem_driver_req_ei[] = {
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
platform_type_valid),
.tlv_type = 0x10,
.elem_size = offsetof(struct ipa_init_modem_driver_req,
platform_type_valid),
},
{
.data_type = QMI_SIGNED_4_BYTE_ENUM,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
platform_type),
.tlv_type = 0x10,
.offset = offsetof(struct ipa_init_modem_driver_req,
platform_type),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
hdr_tbl_info_valid),
.tlv_type = 0x11,
.offset = offsetof(struct ipa_init_modem_driver_req,
hdr_tbl_info_valid),
},
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
hdr_tbl_info),
.tlv_type = 0x11,
.offset = offsetof(struct ipa_init_modem_driver_req,
hdr_tbl_info),
.ei_array = ipa_mem_bounds_ei,
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v4_route_tbl_info_valid),
.tlv_type = 0x12,
.offset = offsetof(struct ipa_init_modem_driver_req,
v4_route_tbl_info_valid),
},
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v4_route_tbl_info),
.tlv_type = 0x12,
.offset = offsetof(struct ipa_init_modem_driver_req,
v4_route_tbl_info),
.ei_array = ipa_mem_array_ei,
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v6_route_tbl_info_valid),
.tlv_type = 0x13,
.offset = offsetof(struct ipa_init_modem_driver_req,
v6_route_tbl_info_valid),
},
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v6_route_tbl_info),
.tlv_type = 0x13,
.offset = offsetof(struct ipa_init_modem_driver_req,
v6_route_tbl_info),
.ei_array = ipa_mem_array_ei,
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v4_filter_tbl_start_valid),
.tlv_type = 0x14,
.offset = offsetof(struct ipa_init_modem_driver_req,
v4_filter_tbl_start_valid),
},
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v4_filter_tbl_start),
.tlv_type = 0x14,
.offset = offsetof(struct ipa_init_modem_driver_req,
v4_filter_tbl_start),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v6_filter_tbl_start_valid),
.tlv_type = 0x15,
.offset = offsetof(struct ipa_init_modem_driver_req,
v6_filter_tbl_start_valid),
},
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v6_filter_tbl_start),
.tlv_type = 0x15,
.offset = offsetof(struct ipa_init_modem_driver_req,
v6_filter_tbl_start),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
modem_mem_info_valid),
.tlv_type = 0x16,
.offset = offsetof(struct ipa_init_modem_driver_req,
modem_mem_info_valid),
},
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
modem_mem_info),
.tlv_type = 0x16,
.offset = offsetof(struct ipa_init_modem_driver_req,
modem_mem_info),
.ei_array = ipa_mem_range_ei,
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
ctrl_comm_dest_end_pt_valid),
.tlv_type = 0x17,
.offset = offsetof(struct ipa_init_modem_driver_req,
ctrl_comm_dest_end_pt_valid),
},
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
ctrl_comm_dest_end_pt),
.tlv_type = 0x17,
.offset = offsetof(struct ipa_init_modem_driver_req,
ctrl_comm_dest_end_pt),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
skip_uc_load_valid),
.tlv_type = 0x18,
.offset = offsetof(struct ipa_init_modem_driver_req,
skip_uc_load_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
skip_uc_load),
.tlv_type = 0x18,
.offset = offsetof(struct ipa_init_modem_driver_req,
skip_uc_load),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
hdr_proc_ctx_tbl_info_valid),
.tlv_type = 0x19,
.offset = offsetof(struct ipa_init_modem_driver_req,
hdr_proc_ctx_tbl_info_valid),
},
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
hdr_proc_ctx_tbl_info),
.tlv_type = 0x19,
.offset = offsetof(struct ipa_init_modem_driver_req,
hdr_proc_ctx_tbl_info),
.ei_array = ipa_mem_bounds_ei,
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
zip_tbl_info_valid),
.tlv_type = 0x1a,
.offset = offsetof(struct ipa_init_modem_driver_req,
zip_tbl_info_valid),
},
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
zip_tbl_info),
.tlv_type = 0x1a,
.offset = offsetof(struct ipa_init_modem_driver_req,
zip_tbl_info),
.ei_array = ipa_mem_bounds_ei,
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v4_hash_route_tbl_info_valid),
.tlv_type = 0x1b,
.offset = offsetof(struct ipa_init_modem_driver_req,
v4_hash_route_tbl_info_valid),
},
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v4_hash_route_tbl_info),
.tlv_type = 0x1b,
.offset = offsetof(struct ipa_init_modem_driver_req,
v4_hash_route_tbl_info),
.ei_array = ipa_mem_array_ei,
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v6_hash_route_tbl_info_valid),
.tlv_type = 0x1c,
.offset = offsetof(struct ipa_init_modem_driver_req,
v6_hash_route_tbl_info_valid),
},
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v6_hash_route_tbl_info),
.tlv_type = 0x1c,
.offset = offsetof(struct ipa_init_modem_driver_req,
v6_hash_route_tbl_info),
.ei_array = ipa_mem_array_ei,
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v4_hash_filter_tbl_start_valid),
.tlv_type = 0x1d,
.offset = offsetof(struct ipa_init_modem_driver_req,
v4_hash_filter_tbl_start_valid),
},
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v4_hash_filter_tbl_start),
.tlv_type = 0x1d,
.offset = offsetof(struct ipa_init_modem_driver_req,
v4_hash_filter_tbl_start),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v6_hash_filter_tbl_start_valid),
.tlv_type = 0x1e,
.offset = offsetof(struct ipa_init_modem_driver_req,
v6_hash_filter_tbl_start_valid),
},
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
v6_hash_filter_tbl_start),
.tlv_type = 0x1e,
.offset = offsetof(struct ipa_init_modem_driver_req,
v6_hash_filter_tbl_start),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
hw_stats_quota_base_addr_valid),
.tlv_type = 0x1f,
.offset = offsetof(struct ipa_init_modem_driver_req,
hw_stats_quota_base_addr_valid),
},
{
.data_type = QMI_SIGNED_4_BYTE_ENUM,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
hw_stats_quota_base_addr),
.tlv_type = 0x1f,
.offset = offsetof(struct ipa_init_modem_driver_req,
hw_stats_quota_base_addr),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
hw_stats_quota_size_valid),
.tlv_type = 0x1f,
.offset = offsetof(struct ipa_init_modem_driver_req,
hw_stats_quota_size_valid),
},
{
.data_type = QMI_SIGNED_4_BYTE_ENUM,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
hw_stats_quota_size),
.tlv_type = 0x1f,
.offset = offsetof(struct ipa_init_modem_driver_req,
hw_stats_quota_size),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
hw_stats_drop_size_valid),
.tlv_type = 0x1f,
.offset = offsetof(struct ipa_init_modem_driver_req,
hw_stats_drop_size_valid),
},
{
.data_type = QMI_SIGNED_4_BYTE_ENUM,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_req,
hw_stats_drop_size),
.tlv_type = 0x1f,
.offset = offsetof(struct ipa_init_modem_driver_req,
hw_stats_drop_size),
},
{
.data_type = QMI_EOTI,
},
};
/* QMI message structure definition for struct ipa_init_modem_driver_rsp */
struct qmi_elem_info ipa_init_modem_driver_rsp_ei[] = {
{
.data_type = QMI_STRUCT,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_rsp,
rsp),
.tlv_type = 0x02,
.offset = offsetof(struct ipa_init_modem_driver_rsp,
rsp),
.ei_array = qmi_response_type_v01_ei,
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_rsp,
ctrl_comm_dest_end_pt_valid),
.tlv_type = 0x10,
.offset = offsetof(struct ipa_init_modem_driver_rsp,
ctrl_comm_dest_end_pt_valid),
},
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_rsp,
ctrl_comm_dest_end_pt),
.tlv_type = 0x10,
.offset = offsetof(struct ipa_init_modem_driver_rsp,
ctrl_comm_dest_end_pt),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_rsp,
default_end_pt_valid),
.tlv_type = 0x11,
.offset = offsetof(struct ipa_init_modem_driver_rsp,
default_end_pt_valid),
},
{
.data_type = QMI_UNSIGNED_4_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_rsp,
default_end_pt),
.tlv_type = 0x11,
.offset = offsetof(struct ipa_init_modem_driver_rsp,
default_end_pt),
},
{
.data_type = QMI_OPT_FLAG,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_rsp,
modem_driver_init_pending_valid),
.tlv_type = 0x12,
.offset = offsetof(struct ipa_init_modem_driver_rsp,
modem_driver_init_pending_valid),
},
{
.data_type = QMI_UNSIGNED_1_BYTE,
.elem_len = 1,
.elem_size =
sizeof_field(struct ipa_init_modem_driver_rsp,
modem_driver_init_pending),
.tlv_type = 0x12,
.offset = offsetof(struct ipa_init_modem_driver_rsp,
modem_driver_init_pending),
},
{
.data_type = QMI_EOTI,
},
};