Browse Source

ipa: Adding support for IP_PACKET_INIT_EX IMM

Adding support for new IMM: IP_PACKET_INIT_EX
The new IMM enables different fields configuration,
extending the older IP_PACKET_INIT.

Change-Id: Icac62d09d4694ab5634fda41579c9de8e4c3afc3
Signed-off-by: Ilia Lin <[email protected]>
Ilia Lin 4 years ago
parent
commit
b5a39c2051

+ 97 - 18
drivers/platform/msm/ipa/ipa_v3/ipa.c

@@ -120,6 +120,9 @@ static void ipa_gsi_notify_cb(struct gsi_per_notify *notify);
 
 static int ipa3_attach_to_smmu(void);
 static int ipa3_alloc_pkt_init(void);
+static int ipa_alloc_pkt_init_ex(void);
+static void ipa3_free_pkt_init(void);
+static void ipa3_free_pkt_init_ex(void);
 
 static void ipa3_load_ipa_fw(struct work_struct *work);
 static DECLARE_WORK(ipa3_fw_loading_work, ipa3_load_ipa_fw);
@@ -6750,7 +6753,14 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,
 	if (result) {
 		IPAERR("Failed to alloc pkt_init payload\n");
 		result = -ENODEV;
-		goto fail_allok_pkt_init;
+		goto fail_alloc_pkt_init;
+	}
+
+	result = ipa_alloc_pkt_init_ex();
+	if (result) {
+		IPAERR("Failed to alloc pkt_init_ex payload\n");
+		result = -ENODEV;
+		goto fail_alloc_pkt_init_ex;
 	}
 
 	if (ipa3_ctx->ipa_hw_type >= IPA_HW_v3_5)
@@ -6957,9 +6967,12 @@ fail_setup_apps_pipes:
 fail_register_device:
 	ipa3_destroy_flt_tbl_idrs();
 fail_init_interrupts:
-	 ipa3_remove_interrupt_handler(IPA_TX_SUSPEND_IRQ);
-	 ipa3_interrupts_destroy(ipa3_res.ipa_irq, &ipa3_ctx->master_pdev->dev);
-fail_allok_pkt_init:
+	ipa3_remove_interrupt_handler(IPA_TX_SUSPEND_IRQ);
+	ipa3_interrupts_destroy(ipa3_res.ipa_irq, &ipa3_ctx->master_pdev->dev);
+	ipa3_free_pkt_init_ex();
+fail_alloc_pkt_init_ex:
+	ipa3_free_pkt_init();
+fail_alloc_pkt_init:
 	ipa3_nat_ipv6ct_destroy_devices();
 fail_nat_ipv6ct_init_dev:
 	ipa3_free_coal_close_frame();
@@ -7425,7 +7438,7 @@ int ipa3_tz_unlock_reg(struct ipa_tz_unlock_reg_info *reg_info, u16 num_regs)
 
 static int ipa3_alloc_pkt_init(void)
 {
-	struct ipa_mem_buffer mem;
+	struct ipa_mem_buffer *mem = &ipa3_ctx->pkt_init_mem;
 	struct ipahal_imm_cmd_pyld *cmd_pyld;
 	struct ipahal_imm_cmd_ip_packet_init cmd = {0};
 	int i;
@@ -7438,17 +7451,16 @@ static int ipa3_alloc_pkt_init(void)
 	}
 	ipa3_ctx->pkt_init_imm_opcode = cmd_pyld->opcode;
 
-	mem.size = cmd_pyld->len * ipa3_ctx->ipa_num_pipes;
-	mem.base = dma_alloc_coherent(ipa3_ctx->pdev, mem.size,
-		&mem.phys_base, GFP_KERNEL);
-	if (!mem.base) {
-		IPAERR("failed to alloc DMA buff of size %d\n", mem.size);
-		ipahal_destroy_imm_cmd(cmd_pyld);
+	mem->size = cmd_pyld->len * ipa3_ctx->ipa_num_pipes;
+	ipahal_destroy_imm_cmd(cmd_pyld);
+	mem->base = dma_alloc_coherent(ipa3_ctx->pdev, mem->size,
+		&mem->phys_base, GFP_KERNEL);
+	if (!mem->base) {
+		IPAERR("failed to alloc DMA buff of size %d\n", mem->size);
 		return -ENOMEM;
 	}
-	ipahal_destroy_imm_cmd(cmd_pyld);
 
-	memset(mem.base, 0, mem.size);
+	memset(mem->base, 0, mem->size);
 	for (i = 0; i < ipa3_ctx->ipa_num_pipes; i++) {
 		cmd.destination_pipe_index = i;
 		cmd_pyld = ipahal_construct_imm_cmd(IPA_IMM_CMD_IP_PACKET_INIT,
@@ -7456,14 +7468,81 @@ static int ipa3_alloc_pkt_init(void)
 		if (!cmd_pyld) {
 			IPAERR("failed to construct IMM cmd\n");
 			dma_free_coherent(ipa3_ctx->pdev,
-				mem.size,
-				mem.base,
-				mem.phys_base);
+				mem->size,
+				mem->base,
+				mem->phys_base);
 			return -ENOMEM;
 		}
-		memcpy(mem.base + i * cmd_pyld->len, cmd_pyld->data,
+		memcpy(mem->base + i * cmd_pyld->len, cmd_pyld->data,
 			cmd_pyld->len);
-		ipa3_ctx->pkt_init_imm[i] = mem.phys_base + i * cmd_pyld->len;
+		ipa3_ctx->pkt_init_imm[i] = mem->phys_base + i * cmd_pyld->len;
+		ipahal_destroy_imm_cmd(cmd_pyld);
+	}
+
+	return 0;
+}
+
+static void ipa3_free_pkt_init(void)
+{
+	dma_free_coherent(ipa3_ctx->pdev, ipa3_ctx->pkt_init_mem.size,
+		ipa3_ctx->pkt_init_mem.base,
+		ipa3_ctx->pkt_init_mem.phys_base);
+}
+
+static void ipa3_free_pkt_init_ex(void)
+{
+	dma_free_coherent(ipa3_ctx->pdev, ipa3_ctx->pkt_init_ex_mem.size,
+		ipa3_ctx->pkt_init_ex_mem.base,
+		ipa3_ctx->pkt_init_ex_mem.phys_base);
+}
+
+static int ipa_alloc_pkt_init_ex(void)
+{
+	struct ipa_mem_buffer *mem = &ipa3_ctx->pkt_init_ex_mem;
+	struct ipahal_imm_cmd_pyld *cmd_pyld;
+	struct ipahal_imm_cmd_ip_packet_init_ex cmd = {0};
+	int i;
+
+	cmd_pyld = ipahal_construct_imm_cmd(IPA_IMM_CMD_IP_PACKET_INIT_EX,
+		&cmd, false);
+	if (!cmd_pyld) {
+		IPAERR("failed to construct IMM cmd\n");
+		return -ENOMEM;
+	}
+	ipa3_ctx->pkt_init_ex_imm_opcode = cmd_pyld->opcode;
+
+	mem->size = cmd_pyld->len * ipa3_ctx->ipa_num_pipes;
+	ipahal_destroy_imm_cmd(cmd_pyld);
+	mem->base = dma_alloc_coherent(ipa3_ctx->pdev, mem->size,
+		&mem->phys_base, GFP_KERNEL);
+	if (!mem->base) {
+		IPAERR("failed to alloc DMA buff of size %d\n", mem->size);
+		return -ENOMEM;
+	}
+
+	memset(mem->base, 0, mem->size);
+	for (i = 0; i < ipa3_ctx->ipa_num_pipes; i++) {
+		cmd.frag_disable = true;
+		cmd.nat_disable = true;
+		cmd.filter_disable = true;
+		cmd.route_disable = true;
+		cmd.hdr_removal_insertion_disable = false;
+		cmd.cs_disable = false;
+		cmd.flt_retain_hdr = true;
+		cmd.rt_retain_hdr = true;
+		cmd.rt_pipe_dest_idx = i;
+		cmd_pyld = ipahal_construct_imm_cmd(IPA_IMM_CMD_IP_PACKET_INIT_EX,
+			&cmd, false);
+		if (!cmd_pyld) {
+			IPAERR("failed to construct IMM cmd\n");
+			dma_free_coherent(ipa3_ctx->pdev,
+				mem->size,
+				mem->base,
+				mem->phys_base);
+			return -ENOMEM;
+		}
+		memcpy(mem->base + i * cmd_pyld->len, cmd_pyld->data, cmd_pyld->len);
+		ipa3_ctx->pkt_init_ex_imm[i] = mem->phys_base + i * cmd_pyld->len;
 		ipahal_destroy_imm_cmd(cmd_pyld);
 	}
 

+ 4 - 0
drivers/platform/msm/ipa/ipa_v3/ipa_i.h

@@ -2200,6 +2200,10 @@ struct ipa3_context {
 	u32 ipa_wdi3_5g_holb_timeout;
 	bool is_wdi3_tx1_needed;
 	bool ipa_endp_delay_wa_v2;
+	dma_addr_t pkt_init_ex_imm[IPA5_MAX_NUM_PIPES];
+	u32 pkt_init_ex_imm_opcode;
+	struct ipa_mem_buffer pkt_init_mem;
+	struct ipa_mem_buffer pkt_init_ex_mem;
 };
 
 struct ipa3_plat_drv_res {

+ 54 - 1
drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c

@@ -28,7 +28,8 @@ static const char *ipahal_imm_cmd_name_to_str[IPA_IMM_CMD_MAX] = {
 	__stringify(IPA_IMM_CMD_IP_PACKET_TAG_STATUS),
 	__stringify(IPA_IMM_CMD_DMA_TASK_32B_ADDR),
 	__stringify(IPA_IMM_CMD_TABLE_DMA),
-	__stringify(IPA_IMM_CMD_IP_V6_CT_INIT)
+	__stringify(IPA_IMM_CMD_IP_V6_CT_INIT),
+	__stringify(IPA_IMM_CMD_IP_PACKET_INIT_EX),
 };
 
 static const char *ipahal_pkt_status_exception_to_str
@@ -364,6 +365,55 @@ static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_ip_packet_init_v_5_0(
 	return pyld;
 }
 
+static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_ip_packet_init_ex(
+	enum ipahal_imm_cmd_name cmd, const void *params, bool is_atomic_ctx)
+{
+	struct ipahal_imm_cmd_pyld *pyld;
+	struct ipa_imm_cmd_hw_ip_packet_init_ex *data;
+	struct ipahal_imm_cmd_ip_packet_init_ex *packet_init_ex_params =
+		(struct ipahal_imm_cmd_ip_packet_init_ex *)params;
+
+	pyld = IPAHAL_MEM_ALLOC(sizeof(*pyld) + sizeof(*data), is_atomic_ctx);
+	if (unlikely(!pyld)) {
+		IPAHAL_ERR("kzalloc err\n");
+		return pyld;
+	}
+	pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
+	pyld->len = sizeof(*data);
+	data = (struct ipa_imm_cmd_hw_ip_packet_init_ex *)pyld->data;
+
+	data->frag_disable = packet_init_ex_params->frag_disable;
+	data->filter_disable = packet_init_ex_params->filter_disable;
+	data->nat_disable = packet_init_ex_params->nat_disable;
+	data->route_disable = packet_init_ex_params->route_disable;
+	data->hdr_removal_insertion_disable =
+	packet_init_ex_params->hdr_removal_insertion_disable;
+	data->cs_disable = packet_init_ex_params->cs_disable;
+	data->quota_tethering_stats_disable =
+	packet_init_ex_params->quota_tethering_stats_disable;
+	data->flt_rt_tbl_idx = packet_init_ex_params->flt_rt_tbl_idx;
+	data->flt_stats_cnt_idx = packet_init_ex_params->flt_stats_cnt_idx;
+	data->flt_priority = packet_init_ex_params->flt_priority;
+	data->flt_close_aggr_irq_mod =
+	packet_init_ex_params->flt_close_aggr_irq_mod;
+	data->flt_rule_id = packet_init_ex_params->flt_rule_id;
+	data->flt_action = packet_init_ex_params->flt_action;
+	data->flt_pdn_idx = packet_init_ex_params->flt_pdn_idx;
+	data->flt_set_metadata = packet_init_ex_params->flt_set_metadata;
+	data->flt_retain_hdr = packet_init_ex_params->flt_retain_hdr;
+	data->rt_pipe_dest_idx = packet_init_ex_params->rt_pipe_dest_idx;
+	data->rt_stats_cnt_idx = packet_init_ex_params->rt_stats_cnt_idx;
+	data->rt_priority = packet_init_ex_params->rt_priority;
+	data->rt_close_aggr_irq_mod = packet_init_ex_params->rt_close_aggr_irq_mod;
+	data->rt_rule_id = packet_init_ex_params->rt_rule_id;
+	data->rt_hdr_offset = packet_init_ex_params->rt_hdr_offset;
+	data->rt_proc_ctx = packet_init_ex_params->rt_proc_ctx;
+	data->rt_retain_hdr = packet_init_ex_params->rt_retain_hdr;
+	data->rt_system = packet_init_ex_params->rt_system;
+
+	return pyld;
+}
+
 static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_nat_dma(
 	enum ipahal_imm_cmd_name cmd, const void *params, bool is_atomic_ctx)
 {
@@ -741,6 +791,9 @@ static struct ipahal_imm_cmd_obj
 	[IPA_HW_v5_0][IPA_IMM_CMD_IP_PACKET_INIT] = {
 		ipa_imm_cmd_construct_ip_packet_init_v_5_0,
 		16},
+	[IPA_HW_v5_0][IPA_IMM_CMD_IP_PACKET_INIT_EX] = {
+		ipa_imm_cmd_construct_ip_packet_init_ex,
+		18},
 };
 
 /*

+ 43 - 0
drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h

@@ -31,6 +31,7 @@ enum ipahal_imm_cmd_name {
 	IPA_IMM_CMD_DMA_TASK_32B_ADDR,
 	IPA_IMM_CMD_TABLE_DMA,
 	IPA_IMM_CMD_IP_V6_CT_INIT,
+	IPA_IMM_CMD_IP_PACKET_INIT_EX,
 	IPA_IMM_CMD_MAX,
 };
 
@@ -229,6 +230,48 @@ struct ipahal_imm_cmd_ip_packet_init {
 	u32 destination_pipe_index;
 };
 
+/*
+ * struct ipahal_imm_cmd_ip_packet_init_ex - IP_PACKET_INIT_EX cmd payload
+ * @frag_disable: true - disabled. overrides IPA_ENDP_CONFIG_n:FRAG_OFFLOAD_EN
+ * @filter_disable: true - disabled, false - enabled
+ * @nat_disable: true - disabled, false - enabled
+ * @route_disable: true - disabled, false - enabled
+ * @hdr_removal_insertion_disable: true - disabled, false - enabled
+ * @cs_disable: true - disabled, false - enabled
+ * @quota_tethering_stats_disable: true - disabled, false - enabled
+ * fields @flt_rt_tbl_idx - @flt_retain_hdr are a logical software translation
+ * of ipa5_0_flt_rule_hw_hdr.
+ * fields @rt_pipe_dest_idx - @rt_system are a logical software translation
+ * ipa5_0_rt_rule_hw_hdr
+ */
+struct ipahal_imm_cmd_ip_packet_init_ex {
+	bool frag_disable;
+	bool filter_disable;
+	bool nat_disable;
+	bool route_disable;
+	bool hdr_removal_insertion_disable;
+	bool cs_disable;
+	bool quota_tethering_stats_disable;
+	u8 flt_rt_tbl_idx;
+	u8 flt_stats_cnt_idx;
+	u8 flt_priority;
+	bool flt_close_aggr_irq_mod;
+	u16 flt_rule_id ;
+	u8 flt_action;
+	u8 flt_pdn_idx;
+	bool flt_set_metadata;
+	bool flt_retain_hdr;
+	u8 rt_pipe_dest_idx;
+	u8 rt_stats_cnt_idx;
+	u8 rt_priority;
+	bool rt_close_aggr_irq_mod;
+	u16 rt_rule_id;
+	u16 rt_hdr_offset;
+	bool rt_proc_ctx;
+	bool rt_retain_hdr;
+	bool rt_system;
+};
+
 /*
  * enum ipa_pipeline_clear_option - Values for pipeline clear waiting options
  * @IPAHAL_HPS_CLEAR: Wait for HPS clear. All queues except high priority queue

+ 46 - 0
drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h

@@ -367,6 +367,52 @@ struct ipa_imm_cmd_hw_ip_packet_init_v_5_0 {
     u64 rsv1 : 56;
 };
 
+/*
+ * struct ipa_imm_cmd_hw_ip_packet_init_ex - IP_PACKET_INIT_EX command payload
+ *  in H/W format for IPA v5_0.
+ * @frag_disable: 1 - disabled. overrides IPA_ENDP_CONFIG_n:FRAG_OFFLOAD_EN
+ * @filter_disable: 1 - disabled, 0 enabled
+ * @nat_disable: 1 - disabled, 0 enabled
+ * @route_disable: 1 - disabled, 0 enabled
+ * @hdr_removal_insertion_disable: 1 - disabled, 0 enabled
+ * @cs_disable: 1 - disabled, 0 enabled
+ * @quota_tethering_stats_disable: 1 - disabled, 0 enabled
+ * fields @flt_rt_tbl_idx - @rsvd4 are a copy of ipa5_0_flt_rule_hw_hdr
+ * fields @rt_pipe_dest_idx - @rt_system are a copy of ipa5_0_rt_rule_hw_hdr
+ */
+struct ipa_imm_cmd_hw_ip_packet_init_ex {
+    u64 rsvd1 : 16;
+    u64 frag_disable : 1;
+    u64 filter_disable : 1;
+    u64 nat_disable : 1;
+    u64 route_disable : 1;
+    u64 hdr_removal_insertion_disable : 1;
+    u64 cs_disable : 1;
+    u64 quota_tethering_stats_disable : 1;
+    u64 rsvd2 : 9;
+	u64 flt_rt_tbl_idx : 8;
+	u64 flt_stats_cnt_idx : 8;
+	u64 flt_priority : 8;
+	u64 rsvd3 : 1;
+	u64 flt_close_aggr_irq_mod : 1;
+	u64 flt_rule_id : 10;
+	u64 flt_action : 5;
+	u64 flt_pdn_idx : 4;
+	u64 flt_set_metadata : 1;
+	u64 flt_retain_hdr : 1;
+	u64 rsvd4 : 1;
+	u64 rt_pipe_dest_idx : 8;
+	u64 rt_stats_cnt_idx : 8;
+	u64 rt_priority : 8;
+	u64 rt_rsvd : 1;
+	u64 rt_close_aggr_irq_mod : 1;
+	u64 rt_rule_id : 10;
+	u64 rt_hdr_offset : 9;
+	u64 rt_proc_ctx : 1;
+	u64 rt_retain_hdr : 1;
+	u64 rt_system : 1;
+} __packed;
+
 /*
  * struct ipa_imm_cmd_hw_register_write - REGISTER_WRITE command payload
  *  in H/W format.