فهرست منبع

msm: ipa: add NAT table move QMI messages

Add NAT table move request and response messages. On
QMI request from Modem send message to IPACM to move
NAT table from HYBRID mode to DDR only and vice versa.
Add IOCTL to allow IPACM to send indication to modem
about NAT table move complete.

Change-Id: I0c0031be7309bdf81e201dd41227e2d802e6e7b0
Signed-off-by: Amir Levy <[email protected]>
Amir Levy 3 سال پیش
والد
کامیت
7aa6f5f716

+ 105 - 1
drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -417,6 +417,67 @@ static void ipa3_handle_mhi_vote_req(struct qmi_handle *qmi_handle,
 		IPAWANDBG("Finished senting QMI_IPA_MHI_CLK_VOTE_RESP_V01\n");
 }
 
+static void ipa3_qmi_msg_free_cb(void *buff, u32 len, u32 type)
+{
+	kfree(buff);
+}
+
+static void ipa3_handle_move_nat_req(struct qmi_handle *qmi_handle,
+	struct sockaddr_qrtr *sq,
+	struct qmi_txn *txn,
+	const void *decoded_msg)
+{
+	struct ipa_move_nat_req_msg_v01 *move_req, *req_data;
+	struct ipa_move_nat_resp_msg_v01 resp;
+	struct ipa_msg_meta msg_meta;
+	int rc;
+
+	move_req = (struct ipa_move_nat_req_msg_v01 *)decoded_msg;
+	IPAWANDBG("Received IPA_MOVE_NAT_REQ_MSG_V01(%s)\n",
+		move_req->nat_move_direction == QMI_IPA_MOVE_NAT_TO_DDR_V01 ?
+	"TO_DDR" : "TO_SRAM");
+
+	memset(&resp, 0, sizeof(resp));
+	resp.resp.result = IPA_QMI_RESULT_SUCCESS_V01;
+
+	req_data = kzalloc(sizeof(struct ipa_move_nat_req_msg_v01),
+		GFP_KERNEL);
+	if (!req_data) {
+		IPAWANERR("allocation failed\n");
+		resp.resp.result = IPA_QMI_RESULT_FAILURE_V01;
+		resp.resp.error = IPA_QMI_ERR_NO_MEMORY_V01;
+		goto send_resp;
+	}
+
+	memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
+	msg_meta.msg_type = IPA_MOVE_NAT_TABLE;
+	msg_meta.msg_len = sizeof(struct ipa_move_nat_req_msg_v01);
+
+	req_data->nat_move_direction = move_req->nat_move_direction;
+
+	rc = ipa_send_msg(&msg_meta, req_data, ipa3_qmi_msg_free_cb);
+	if (rc) {
+		IPAWANERR("ipa_send_msg failed: %d, notify Q6\n", rc);
+		resp.resp.result = IPA_QMI_RESULT_FAILURE_V01;
+	}
+send_resp:
+	IPAWANDBG("qmi_snd_rsp: result %d, err %d\n",
+		resp.resp.result, resp.resp.error);
+
+	rc = qmi_send_response(qmi_handle, sq, txn,
+		QMI_IPA_MOVE_NAT_RESP_V01,
+		IPA_MOVE_NAT_RESP_MSG_V01_MAX_MSG_LEN,
+		ipa_move_nat_resp_msg_v01_ei,
+		&resp);
+
+	if (rc < 0)
+		IPAWANERR("QMI_IPA_MOVE_NAT_RESP_V01 failed\n");
+	else
+		IPAWANDBG(
+			"Finished sending QMI_IPA_MOVE_NAT_RESP_V01, res %d\n"
+		, resp.resp.result);
+}
+
 static void ipa3_a5_svc_disconnect_cb(struct qmi_handle *qmi,
 	unsigned int node, unsigned int port)
 {
@@ -1452,6 +1513,42 @@ int ipa3_qmi_filter_notify_send(
 		resp.resp.error, "ipa_fltr_installed_notif_resp");
 }
 
+/*sending nat table move result indication to modem */
+int rmnet_ipa3_notify_nat_move_res(bool failure)
+{
+	int rc;
+	struct ipa_move_nat_table_complt_ind_msg_v01 ind;
+
+	IPAWANDBG("send nat table move indication to modem (%d)\n",
+		failure);
+	memset(&ind, 0, sizeof(struct
+		ipa_move_nat_table_complt_ind_msg_v01));
+	if (!failure)
+		ind.nat_table_move_status.result =
+		IPA_QMI_RESULT_SUCCESS_V01;
+	else
+		ind.nat_table_move_status.result =
+		IPA_QMI_RESULT_FAILURE_V01;
+
+	if (unlikely(!ipa3_svc_handle)) {
+		IPAWANERR("Invalid svc handle.Ignore sending ind.\n");
+		return -EFAULT;
+	}
+
+	rc = qmi_send_indication(ipa3_svc_handle,
+		&ipa3_qmi_ctx->client_sq,
+		QMI_IPA_MOVE_NAT_COMPLETE_IND_V01,
+		QMI_IPA_NAT_TABLE_MOVE_COMPLETE_IND_MAX_MSG_LEN_V01,
+		ipa_move_nat_table_complt_ind_msg_v01_ei,
+		&ind);
+	if (rc)
+		IPAWANERR("qmi indication not succesfull %d\n", rc);
+	else
+		IPAWANDBG("qmi indication sent succesfully\n");
+
+	return rc;
+}
+
 static void ipa3_q6_clnt_quota_reached_ind_cb(struct qmi_handle *handle,
 	struct sockaddr_qrtr *sq,
 	struct qmi_txn *txn,
@@ -1763,6 +1860,13 @@ static struct qmi_msg_handler server_handlers[] = {
 		.decoded_size = sizeof(struct ipa_mhi_clk_vote_req_msg_v01),
 		.fn = ipa3_handle_mhi_vote_req,
 	},
+	{
+		.type = QMI_REQUEST,
+		.msg_id = QMI_IPA_MOVE_NAT_REQ_V01,
+		.ei = ipa_move_nat_req_msg_v01_ei,
+		.decoded_size = sizeof(struct ipa_move_nat_req_msg_v01),
+		.fn = ipa3_handle_move_nat_req,
+	},
 
 };
 

+ 12 - 1
drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h

@@ -220,6 +220,9 @@ extern struct qmi_elem_info ipa_add_offload_connection_resp_msg_v01_ei[];
 extern struct qmi_elem_info ipa_remove_offload_connection_req_msg_v01_ei[];
 extern struct qmi_elem_info ipa_remove_offload_connection_resp_msg_v01_ei[];
 extern struct qmi_elem_info ipa_bw_change_ind_msg_v01_ei[];
+extern struct qmi_elem_info ipa_move_nat_req_msg_v01_ei[];
+extern struct qmi_elem_info ipa_move_nat_resp_msg_v01_ei[];
+extern struct qmi_elem_info ipa_move_nat_table_complt_ind_msg_v01_ei[];
 
 /**
  * struct ipa3_rmnet_context - IPA rmnet context
@@ -359,6 +362,9 @@ int ipa3_qmi_send_endp_desc_indication(
 
 int ipa3_qmi_send_mhi_cleanup_request(struct ipa_mhi_cleanup_req_msg_v01 *req);
 
+/* sending nat table move result indication to modem */
+int rmnet_ipa3_notify_nat_move_res(bool success);
+
 void ipa3_qmi_init(void);
 
 void ipa3_qmi_cleanup(void);
@@ -378,7 +384,7 @@ static inline int ipa3_qmi_service_init(uint32_t wan_platform_type)
 
 static inline void ipa3_qmi_service_exit(void) { }
 
-/* sending filter-install-request to modem*/
+/* sending filter-install-request to modem */
 static inline int ipa3_qmi_filter_request_send(
 	struct ipa_install_fltr_rule_req_msg_v01 *req)
 {
@@ -521,6 +527,11 @@ static inline int ipa3_qmi_send_mhi_cleanup_request(
 	return -EPERM;
 }
 
+static int rmnet_ipa3_notify_nat_move_res(bool success)
+{
+	return -EPERM
+}
+
 static inline int ipa3_wwan_set_modem_perf_profile(
 	int throughput)
 {

+ 57 - 1
drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service_v01.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, 2021 The Linux Foundation. All rights reserved.
  */
 
 #include <linux/ipa_qmi_service_v01.h>
@@ -1499,6 +1499,25 @@ struct qmi_elem_info ipa3_master_driver_init_complt_ind_msg_data_v01_ei[] = {
 	},
 };
 
+struct qmi_elem_info ipa_move_nat_table_complt_ind_msg_v01_ei[] = {
+	{
+		.data_type = QMI_STRUCT,
+		.elem_len = 1,
+		.elem_size = sizeof(struct qmi_response_type_v01),
+		.array_type = NO_ARRAY,
+		.tlv_type = 0x02,
+		.offset = offsetof(struct
+		ipa_move_nat_table_complt_ind_msg_v01,
+			nat_table_move_status),
+		.ei_array = qmi_response_type_v01_ei,
+	},
+	{
+		.data_type = QMI_EOTI,
+		.array_type = NO_ARRAY,
+		.tlv_type = QMI_COMMON_TLV_TYPE,
+	},
+};
+
 static struct qmi_elem_info ipa_filter_rule_req2_type_v01_ei[] = {
 	{
 		.data_type      = QMI_UNSIGNED_2_BYTE,
@@ -5354,4 +5373,41 @@ struct qmi_elem_info ipa_bw_change_ind_msg_v01_ei[] = {
 		.tlv_type       = QMI_COMMON_TLV_TYPE,
 
 	},
+};
+
+struct qmi_elem_info ipa_move_nat_req_msg_v01_ei[] = {
+	{
+		.data_type = QMI_UNSIGNED_4_BYTE,
+		.elem_len = 1,
+		.elem_size = sizeof(uint32_t),
+		.array_type = NO_ARRAY,
+		.tlv_type = 0x01,
+		.offset = offsetof(
+			struct ipa_move_nat_req_msg_v01,
+			nat_move_direction),
+	},
+	{
+		.data_type = QMI_EOTI,
+		.array_type = NO_ARRAY,
+		.tlv_type = QMI_COMMON_TLV_TYPE,
+	},
+};
+
+struct qmi_elem_info ipa_move_nat_resp_msg_v01_ei[] = {
+	{
+		.data_type = QMI_STRUCT,
+		.elem_len = 1,
+		.elem_size = sizeof(struct qmi_response_type_v01),
+		.array_type = NO_ARRAY,
+		.tlv_type = 0x02,
+		.offset = offsetof(
+			struct ipa_move_nat_resp_msg_v01,
+			resp),
+		.ei_array = qmi_response_type_v01_ei,
+	},
+	{
+		.data_type = QMI_EOTI,
+		.array_type = NO_ARRAY,
+		.tlv_type = QMI_COMMON_TLV_TYPE,
+	},
 };

+ 8 - 0
drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c

@@ -509,6 +509,14 @@ static long ipa3_wan_ioctl(struct file *filp,
 			break;
 		}
 		break;
+	case WAN_IOC_NOTIFY_NAT_MOVE_RES:
+		IPAWANDBG_LOW("got WAN_IOC_NOTIFY_NAT_MOVE_RES :>>>\n");
+		if (rmnet_ipa3_notify_nat_move_res(arg)) {
+			IPAWANERR("WAN_IOC_NOTIFY_NAT_MOVE_RES failed\n");
+			retval = -EFAULT;
+			break;
+		}
+		break;
 
 	case WAN_IOC_GET_WAN_MTU:
 		IPAWANDBG_LOW("got WAN_IOC_GET_WAN_MTU :>>>\n");