Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88dd3e81 authored by Utkarsh Saxena's avatar Utkarsh Saxena Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: Remove usage of stack memory



When stack memory is provided to IPA HW as part of
descriptor it can lead to cache alignment issues.
Make changes to use heap memory whereever applicable.

Change-Id: I666f98cf2ec45a4743db0ab7bc6d2df821cce84a
Acked-by: default avatarChaitanya Pratapa <cpratapa@qti.qualcomm.com>
Signed-off-by: default avatarSridhar Ancha <sancha@codeaurora.org>
Signed-off-by: default avatarUtkarsh Saxena <usaxena@codeaurora.org>
parent bed4cbb7
Loading
Loading
Loading
Loading
+139 −54
Original line number Original line Diff line number Diff line
@@ -1581,7 +1581,7 @@ static int ipa_setup_exception_path(void)
static int ipa_init_smem_region(int memory_region_size,
static int ipa_init_smem_region(int memory_region_size,
				int memory_region_offset)
				int memory_region_offset)
{
{
	struct ipa_hw_imm_cmd_dma_shared_mem cmd;
	struct ipa_hw_imm_cmd_dma_shared_mem *cmd = NULL;
	struct ipa_desc desc;
	struct ipa_desc desc;
	struct ipa_mem_buffer mem;
	struct ipa_mem_buffer mem;
	int rc;
	int rc;
@@ -1590,7 +1590,6 @@ static int ipa_init_smem_region(int memory_region_size,
		return 0;
		return 0;


	memset(&desc, 0, sizeof(desc));
	memset(&desc, 0, sizeof(desc));
	memset(&cmd, 0, sizeof(cmd));
	memset(&mem, 0, sizeof(mem));
	memset(&mem, 0, sizeof(mem));


	mem.size = memory_region_size;
	mem.size = memory_region_size;
@@ -1602,13 +1601,22 @@ static int ipa_init_smem_region(int memory_region_size,
	}
	}


	memset(mem.base, 0, mem.size);
	memset(mem.base, 0, mem.size);
	cmd.size = mem.size;

	cmd.system_addr = mem.phys_base;
	cmd = kzalloc(sizeof(*cmd),
	cmd.local_addr = ipa_ctx->smem_restricted_bytes +
		GFP_KERNEL);
	if (cmd == NULL) {
		IPAERR("Failed to alloc immediate command object\n");
		rc = -ENOMEM;
		goto fail_send_cmd;
	}

	cmd->size = mem.size;
	cmd->system_addr = mem.phys_base;
	cmd->local_addr = ipa_ctx->smem_restricted_bytes +
		memory_region_offset;
		memory_region_offset;
	desc.opcode = IPA_DMA_SHARED_MEM;
	desc.opcode = IPA_DMA_SHARED_MEM;
	desc.pyld = &cmd;
	desc.pyld = cmd;
	desc.len = sizeof(cmd);
	desc.len = sizeof(*cmd);
	desc.type = IPA_IMM_CMD_DESC;
	desc.type = IPA_IMM_CMD_DESC;


	rc = ipa_send_cmd(1, &desc);
	rc = ipa_send_cmd(1, &desc);
@@ -1617,6 +1625,8 @@ static int ipa_init_smem_region(int memory_region_size,
		rc = -EFAULT;
		rc = -EFAULT;
	}
	}


	kfree(cmd);
fail_send_cmd:
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base,
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base,
		mem.phys_base);
		mem.phys_base);


@@ -2153,7 +2163,7 @@ int _ipa_init_sram_v2(void)
{
{
	u32 *ipa_sram_mmio;
	u32 *ipa_sram_mmio;
	unsigned long phys_addr;
	unsigned long phys_addr;
	struct ipa_hw_imm_cmd_dma_shared_mem cmd = {0};
	struct ipa_hw_imm_cmd_dma_shared_mem *cmd = NULL;
	struct ipa_desc desc = {0};
	struct ipa_desc desc = {0};
	struct ipa_mem_buffer mem;
	struct ipa_mem_buffer mem;
	int rc = 0;
	int rc = 0;
@@ -2193,11 +2203,18 @@ int _ipa_init_sram_v2(void)
	}
	}
	memset(mem.base, 0, mem.size);
	memset(mem.base, 0, mem.size);


	cmd.size = mem.size;
	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	cmd.system_addr = mem.phys_base;
	if (cmd == NULL) {
	cmd.local_addr = IPA_STATUS_CLEAR_OFST;
		IPAERR("Failed to alloc immediate command object\n");
		rc = -ENOMEM;
		goto fail_send_cmd;
	}

	cmd->size = mem.size;
	cmd->system_addr = mem.phys_base;
	cmd->local_addr = IPA_STATUS_CLEAR_OFST;
	desc.opcode = IPA_DMA_SHARED_MEM;
	desc.opcode = IPA_DMA_SHARED_MEM;
	desc.pyld = &cmd;
	desc.pyld = (void *)cmd;
	desc.len = sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
	desc.len = sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
	desc.type = IPA_IMM_CMD_DESC;
	desc.type = IPA_IMM_CMD_DESC;


@@ -2206,6 +2223,8 @@ int _ipa_init_sram_v2(void)
		rc = -EFAULT;
		rc = -EFAULT;
	}
	}


	kfree(cmd);
fail_send_cmd:
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	return rc;
	return rc;
}
}
@@ -2294,7 +2313,7 @@ int _ipa_init_hdr_v2(void)
{
{
	struct ipa_desc desc = { 0 };
	struct ipa_desc desc = { 0 };
	struct ipa_mem_buffer mem;
	struct ipa_mem_buffer mem;
	struct ipa_hdr_init_local cmd;
	struct ipa_hdr_init_local *cmd = NULL;
	int rc = 0;
	int rc = 0;


	mem.size = IPA_MEM_PART(modem_hdr_size) + IPA_MEM_PART(apps_hdr_size);
	mem.size = IPA_MEM_PART(modem_hdr_size) + IPA_MEM_PART(apps_hdr_size);
@@ -2306,13 +2325,20 @@ int _ipa_init_hdr_v2(void)
	}
	}
	memset(mem.base, 0, mem.size);
	memset(mem.base, 0, mem.size);


	cmd.hdr_table_src_addr = mem.phys_base;
	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	cmd.size_hdr_table = mem.size;
	if (cmd == NULL) {
	cmd.hdr_table_dst_addr = ipa_ctx->smem_restricted_bytes +
		IPAERR("Failed to alloc header init command object\n");
		rc = -ENOMEM;
		goto fail_send_cmd;
	}

	cmd->hdr_table_src_addr = mem.phys_base;
	cmd->size_hdr_table = mem.size;
	cmd->hdr_table_dst_addr = ipa_ctx->smem_restricted_bytes +
		IPA_MEM_PART(modem_hdr_ofst);
		IPA_MEM_PART(modem_hdr_ofst);


	desc.opcode = IPA_HDR_INIT_LOCAL;
	desc.opcode = IPA_HDR_INIT_LOCAL;
	desc.pyld = &cmd;
	desc.pyld = (void *)cmd;
	desc.len = sizeof(struct ipa_hdr_init_local);
	desc.len = sizeof(struct ipa_hdr_init_local);
	desc.type = IPA_IMM_CMD_DESC;
	desc.type = IPA_IMM_CMD_DESC;
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);
@@ -2322,6 +2348,8 @@ int _ipa_init_hdr_v2(void)
		rc = -EFAULT;
		rc = -EFAULT;
	}
	}


	kfree(cmd);
fail_send_cmd:
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	return rc;
	return rc;
}
}
@@ -2330,8 +2358,8 @@ int _ipa_init_hdr_v2_5(void)
{
{
	struct ipa_desc desc = { 0 };
	struct ipa_desc desc = { 0 };
	struct ipa_mem_buffer mem;
	struct ipa_mem_buffer mem;
	struct ipa_hdr_init_local cmd = { 0 };
	struct ipa_hdr_init_local *cmd = NULL;
	struct ipa_hw_imm_cmd_dma_shared_mem dma_cmd = { 0 };
	struct ipa_hw_imm_cmd_dma_shared_mem *dma_cmd = NULL;


	mem.size = IPA_MEM_PART(modem_hdr_size) + IPA_MEM_PART(apps_hdr_size);
	mem.size = IPA_MEM_PART(modem_hdr_size) + IPA_MEM_PART(apps_hdr_size);
	mem.base = dma_alloc_coherent(ipa_ctx->pdev, mem.size, &mem.phys_base,
	mem.base = dma_alloc_coherent(ipa_ctx->pdev, mem.size, &mem.phys_base,
@@ -2342,25 +2370,34 @@ int _ipa_init_hdr_v2_5(void)
	}
	}
	memset(mem.base, 0, mem.size);
	memset(mem.base, 0, mem.size);


	cmd.hdr_table_src_addr = mem.phys_base;
	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	cmd.size_hdr_table = mem.size;
	if (cmd == NULL) {
	cmd.hdr_table_dst_addr = ipa_ctx->smem_restricted_bytes +
		IPAERR("Failed to alloc header init command object\n");
		dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base,
			mem.phys_base);
		return -ENOMEM;
	}

	cmd->hdr_table_src_addr = mem.phys_base;
	cmd->size_hdr_table = mem.size;
	cmd->hdr_table_dst_addr = ipa_ctx->smem_restricted_bytes +
		IPA_MEM_PART(modem_hdr_ofst);
		IPA_MEM_PART(modem_hdr_ofst);


	desc.opcode = IPA_HDR_INIT_LOCAL;
	desc.opcode = IPA_HDR_INIT_LOCAL;
	desc.pyld = &cmd;
	desc.pyld = (void *)cmd;
	desc.len = sizeof(struct ipa_hdr_init_local);
	desc.len = sizeof(struct ipa_hdr_init_local);
	desc.type = IPA_IMM_CMD_DESC;
	desc.type = IPA_IMM_CMD_DESC;
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);


	if (ipa_send_cmd(1, &desc)) {
	if (ipa_send_cmd(1, &desc)) {
		IPAERR("fail to send immediate command\n");
		IPAERR("fail to send immediate command\n");
		dma_free_coherent(ipa_ctx->pdev,
		kfree(cmd);
			mem.size, mem.base,
		dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base,
			mem.phys_base);
			mem.phys_base);
		return -EFAULT;
		return -EFAULT;
	}
	}


	kfree(cmd);
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);


	mem.size = IPA_MEM_PART(modem_hdr_proc_ctx_size) +
	mem.size = IPA_MEM_PART(modem_hdr_proc_ctx_size) +
@@ -2374,18 +2411,29 @@ int _ipa_init_hdr_v2_5(void)
	memset(mem.base, 0, mem.size);
	memset(mem.base, 0, mem.size);
	memset(&desc, 0, sizeof(desc));
	memset(&desc, 0, sizeof(desc));


	dma_cmd.system_addr = mem.phys_base;
	dma_cmd = kzalloc(sizeof(*dma_cmd), GFP_KERNEL);
	dma_cmd.local_addr = ipa_ctx->smem_restricted_bytes +
	if (dma_cmd == NULL) {
		IPAERR("Failed to alloc immediate command object\n");
		dma_free_coherent(ipa_ctx->pdev,
			mem.size,
			mem.base,
			mem.phys_base);
		return -ENOMEM;
	}

	dma_cmd->system_addr = mem.phys_base;
	dma_cmd->local_addr = ipa_ctx->smem_restricted_bytes +
		IPA_MEM_PART(modem_hdr_proc_ctx_ofst);
		IPA_MEM_PART(modem_hdr_proc_ctx_ofst);
	dma_cmd.size = mem.size;
	dma_cmd->size = mem.size;
	desc.opcode = IPA_DMA_SHARED_MEM;
	desc.opcode = IPA_DMA_SHARED_MEM;
	desc.pyld = &dma_cmd;
	desc.pyld = (void *)dma_cmd;
	desc.len = sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
	desc.len = sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
	desc.type = IPA_IMM_CMD_DESC;
	desc.type = IPA_IMM_CMD_DESC;
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);


	if (ipa_send_cmd(1, &desc)) {
	if (ipa_send_cmd(1, &desc)) {
		IPAERR("fail to send immediate command\n");
		IPAERR("fail to send immediate command\n");
		kfree(dma_cmd);
		dma_free_coherent(ipa_ctx->pdev,
		dma_free_coherent(ipa_ctx->pdev,
			mem.size,
			mem.size,
			mem.base,
			mem.base,
@@ -2395,8 +2443,9 @@ int _ipa_init_hdr_v2_5(void)


	ipa_write_reg(ipa_ctx->mmio,
	ipa_write_reg(ipa_ctx->mmio,
		IPA_LOCAL_PKT_PROC_CNTXT_BASE_OFST,
		IPA_LOCAL_PKT_PROC_CNTXT_BASE_OFST,
		dma_cmd.local_addr);
		dma_cmd->local_addr);


	kfree(dma_cmd);
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);


	return 0;
	return 0;
@@ -2412,7 +2461,7 @@ int _ipa_init_rt4_v2(void)
{
{
	struct ipa_desc desc = { 0 };
	struct ipa_desc desc = { 0 };
	struct ipa_mem_buffer mem;
	struct ipa_mem_buffer mem;
	struct ipa_ip_v4_routing_init v4_cmd;
	struct ipa_ip_v4_routing_init *v4_cmd = NULL;
	u32 *entry;
	u32 *entry;
	int i;
	int i;
	int rc = 0;
	int rc = 0;
@@ -2437,15 +2486,22 @@ int _ipa_init_rt4_v2(void)
		entry++;
		entry++;
	}
	}


	v4_cmd = kzalloc(sizeof(*v4_cmd), GFP_KERNEL);
	if (v4_cmd == NULL) {
		IPAERR("Failed to alloc v4 routing init command object\n");
		rc = -ENOMEM;
		goto fail_send_cmd;
	}

	desc.opcode = IPA_IP_V4_ROUTING_INIT;
	desc.opcode = IPA_IP_V4_ROUTING_INIT;
	v4_cmd.ipv4_rules_addr = mem.phys_base;
	v4_cmd->ipv4_rules_addr = mem.phys_base;
	v4_cmd.size_ipv4_rules = mem.size;
	v4_cmd->size_ipv4_rules = mem.size;
	v4_cmd.ipv4_addr = ipa_ctx->smem_restricted_bytes +
	v4_cmd->ipv4_addr = ipa_ctx->smem_restricted_bytes +
		IPA_MEM_PART(v4_rt_ofst);
		IPA_MEM_PART(v4_rt_ofst);
	IPADBG("putting Routing IPv4 rules to phys 0x%x",
	IPADBG("putting Routing IPv4 rules to phys 0x%x",
				v4_cmd.ipv4_addr);
				v4_cmd->ipv4_addr);


	desc.pyld = &v4_cmd;
	desc.pyld = (void *)v4_cmd;
	desc.len = sizeof(struct ipa_ip_v4_routing_init);
	desc.len = sizeof(struct ipa_ip_v4_routing_init);
	desc.type = IPA_IMM_CMD_DESC;
	desc.type = IPA_IMM_CMD_DESC;
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);
@@ -2455,6 +2511,8 @@ int _ipa_init_rt4_v2(void)
		rc = -EFAULT;
		rc = -EFAULT;
	}
	}


	kfree(v4_cmd);
fail_send_cmd:
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	return rc;
	return rc;
}
}
@@ -2463,7 +2521,7 @@ int _ipa_init_rt6_v2(void)
{
{
	struct ipa_desc desc = { 0 };
	struct ipa_desc desc = { 0 };
	struct ipa_mem_buffer mem;
	struct ipa_mem_buffer mem;
	struct ipa_ip_v6_routing_init v6_cmd;
	struct ipa_ip_v6_routing_init *v6_cmd = NULL;
	u32 *entry;
	u32 *entry;
	int i;
	int i;
	int rc = 0;
	int rc = 0;
@@ -2488,15 +2546,22 @@ int _ipa_init_rt6_v2(void)
		entry++;
		entry++;
	}
	}


	v6_cmd = kzalloc(sizeof(*v6_cmd), GFP_KERNEL);
	if (v6_cmd == NULL) {
		IPAERR("Failed to alloc v6 routing init command object\n");
		rc = -ENOMEM;
		goto fail_send_cmd;
	}

	desc.opcode = IPA_IP_V6_ROUTING_INIT;
	desc.opcode = IPA_IP_V6_ROUTING_INIT;
	v6_cmd.ipv6_rules_addr = mem.phys_base;
	v6_cmd->ipv6_rules_addr = mem.phys_base;
	v6_cmd.size_ipv6_rules = mem.size;
	v6_cmd->size_ipv6_rules = mem.size;
	v6_cmd.ipv6_addr = ipa_ctx->smem_restricted_bytes +
	v6_cmd->ipv6_addr = ipa_ctx->smem_restricted_bytes +
		IPA_MEM_PART(v6_rt_ofst);
		IPA_MEM_PART(v6_rt_ofst);
	IPADBG("putting Routing IPv6 rules to phys 0x%x",
	IPADBG("putting Routing IPv6 rules to phys 0x%x",
				v6_cmd.ipv6_addr);
				v6_cmd->ipv6_addr);


	desc.pyld = &v6_cmd;
	desc.pyld = (void *)v6_cmd;
	desc.len = sizeof(struct ipa_ip_v6_routing_init);
	desc.len = sizeof(struct ipa_ip_v6_routing_init);
	desc.type = IPA_IMM_CMD_DESC;
	desc.type = IPA_IMM_CMD_DESC;
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);
@@ -2506,6 +2571,8 @@ int _ipa_init_rt6_v2(void)
		rc = -EFAULT;
		rc = -EFAULT;
	}
	}


	kfree(v6_cmd);
fail_send_cmd:
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	return rc;
	return rc;
}
}
@@ -2514,7 +2581,7 @@ int _ipa_init_flt4_v2(void)
{
{
	struct ipa_desc desc = { 0 };
	struct ipa_desc desc = { 0 };
	struct ipa_mem_buffer mem;
	struct ipa_mem_buffer mem;
	struct ipa_ip_v4_filter_init v4_cmd;
	struct ipa_ip_v4_filter_init *v4_cmd = NULL;
	u32 *entry;
	u32 *entry;
	int i;
	int i;
	int rc = 0;
	int rc = 0;
@@ -2537,15 +2604,22 @@ int _ipa_init_flt4_v2(void)
		entry++;
		entry++;
	}
	}


	v4_cmd = kzalloc(sizeof(*v4_cmd), GFP_KERNEL);
	if (v4_cmd == NULL) {
		IPAERR("Failed to alloc v4 fliter init command object\n");
		rc = -ENOMEM;
		goto fail_send_cmd;
	}

	desc.opcode = IPA_IP_V4_FILTER_INIT;
	desc.opcode = IPA_IP_V4_FILTER_INIT;
	v4_cmd.ipv4_rules_addr = mem.phys_base;
	v4_cmd->ipv4_rules_addr = mem.phys_base;
	v4_cmd.size_ipv4_rules = mem.size;
	v4_cmd->size_ipv4_rules = mem.size;
	v4_cmd.ipv4_addr = ipa_ctx->smem_restricted_bytes +
	v4_cmd->ipv4_addr = ipa_ctx->smem_restricted_bytes +
		IPA_MEM_PART(v4_flt_ofst);
		IPA_MEM_PART(v4_flt_ofst);
	IPADBG("putting Filtering IPv4 rules to phys 0x%x",
	IPADBG("putting Filtering IPv4 rules to phys 0x%x",
				v4_cmd.ipv4_addr);
				v4_cmd->ipv4_addr);


	desc.pyld = &v4_cmd;
	desc.pyld = (void *)v4_cmd;
	desc.len = sizeof(struct ipa_ip_v4_filter_init);
	desc.len = sizeof(struct ipa_ip_v4_filter_init);
	desc.type = IPA_IMM_CMD_DESC;
	desc.type = IPA_IMM_CMD_DESC;
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);
@@ -2555,6 +2629,8 @@ int _ipa_init_flt4_v2(void)
		rc = -EFAULT;
		rc = -EFAULT;
	}
	}


	kfree(v4_cmd);
fail_send_cmd:
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	return rc;
	return rc;
}
}
@@ -2563,7 +2639,7 @@ int _ipa_init_flt6_v2(void)
{
{
	struct ipa_desc desc = { 0 };
	struct ipa_desc desc = { 0 };
	struct ipa_mem_buffer mem;
	struct ipa_mem_buffer mem;
	struct ipa_ip_v6_filter_init v6_cmd;
	struct ipa_ip_v6_filter_init *v6_cmd = NULL;
	u32 *entry;
	u32 *entry;
	int i;
	int i;
	int rc = 0;
	int rc = 0;
@@ -2586,15 +2662,22 @@ int _ipa_init_flt6_v2(void)
		entry++;
		entry++;
	}
	}


	v6_cmd = kzalloc(sizeof(*v6_cmd), GFP_KERNEL);
	if (v6_cmd == NULL) {
		IPAERR("Failed to alloc v6 fliter init command object\n");
		rc = -ENOMEM;
		goto fail_send_cmd;
	}

	desc.opcode = IPA_IP_V6_FILTER_INIT;
	desc.opcode = IPA_IP_V6_FILTER_INIT;
	v6_cmd.ipv6_rules_addr = mem.phys_base;
	v6_cmd->ipv6_rules_addr = mem.phys_base;
	v6_cmd.size_ipv6_rules = mem.size;
	v6_cmd->size_ipv6_rules = mem.size;
	v6_cmd.ipv6_addr = ipa_ctx->smem_restricted_bytes +
	v6_cmd->ipv6_addr = ipa_ctx->smem_restricted_bytes +
		IPA_MEM_PART(v6_flt_ofst);
		IPA_MEM_PART(v6_flt_ofst);
	IPADBG("putting Filtering IPv6 rules to phys 0x%x",
	IPADBG("putting Filtering IPv6 rules to phys 0x%x",
				v6_cmd.ipv6_addr);
				v6_cmd->ipv6_addr);


	desc.pyld = &v6_cmd;
	desc.pyld = (void *)v6_cmd;
	desc.len = sizeof(struct ipa_ip_v6_filter_init);
	desc.len = sizeof(struct ipa_ip_v6_filter_init);
	desc.type = IPA_IMM_CMD_DESC;
	desc.type = IPA_IMM_CMD_DESC;
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);
	IPA_DUMP_BUFF(mem.base, mem.phys_base, mem.size);
@@ -2604,6 +2687,8 @@ int _ipa_init_flt6_v2(void)
		rc = -EFAULT;
		rc = -EFAULT;
	}
	}


	kfree(v6_cmd);
fail_send_cmd:
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base, mem.phys_base);
	return rc;
	return rc;
}
}
+111 −47
Original line number Original line Diff line number Diff line
@@ -266,8 +266,8 @@ int __ipa_commit_hdr_v2(void)
{
{
	struct ipa_desc desc = { 0 };
	struct ipa_desc desc = { 0 };
	struct ipa_mem_buffer mem;
	struct ipa_mem_buffer mem;
	struct ipa_hdr_init_system cmd;
	struct ipa_hdr_init_system *cmd = NULL;
	struct ipa_hw_imm_cmd_dma_shared_mem dma_cmd;
	struct ipa_hw_imm_cmd_dma_shared_mem *dma_cmd = NULL;
	int rc = -EFAULT;
	int rc = -EFAULT;


	if (ipa_generate_hdr_hw_tbl(&mem)) {
	if (ipa_generate_hdr_hw_tbl(&mem)) {
@@ -279,14 +279,21 @@ int __ipa_commit_hdr_v2(void)
		if (mem.size > IPA_MEM_PART(apps_hdr_size)) {
		if (mem.size > IPA_MEM_PART(apps_hdr_size)) {
			IPAERR("tbl too big, needed %d avail %d\n", mem.size,
			IPAERR("tbl too big, needed %d avail %d\n", mem.size,
				IPA_MEM_PART(apps_hdr_size));
				IPA_MEM_PART(apps_hdr_size));
			goto end;
			goto fail_send_cmd;
		} else {
		} else {
			dma_cmd.system_addr = mem.phys_base;
			dma_cmd = kzalloc(sizeof(*dma_cmd), GFP_ATOMIC);
			dma_cmd.size = mem.size;
			if (dma_cmd == NULL) {
			dma_cmd.local_addr = ipa_ctx->smem_restricted_bytes +
				IPAERR("fail to alloc immediate cmd\n");
				rc = -ENOMEM;
				goto fail_send_cmd;
			}

			dma_cmd->system_addr = mem.phys_base;
			dma_cmd->size = mem.size;
			dma_cmd->local_addr = ipa_ctx->smem_restricted_bytes +
				IPA_MEM_PART(apps_hdr_ofst);
				IPA_MEM_PART(apps_hdr_ofst);
			desc.opcode = IPA_DMA_SHARED_MEM;
			desc.opcode = IPA_DMA_SHARED_MEM;
			desc.pyld = &dma_cmd;
			desc.pyld = (void *)dma_cmd;
			desc.len =
			desc.len =
				sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
				sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
		}
		}
@@ -294,11 +301,17 @@ int __ipa_commit_hdr_v2(void)
		if (mem.size > IPA_MEM_PART(apps_hdr_size_ddr)) {
		if (mem.size > IPA_MEM_PART(apps_hdr_size_ddr)) {
			IPAERR("tbl too big, needed %d avail %d\n", mem.size,
			IPAERR("tbl too big, needed %d avail %d\n", mem.size,
				IPA_MEM_PART(apps_hdr_size_ddr));
				IPA_MEM_PART(apps_hdr_size_ddr));
			goto end;
			goto fail_send_cmd;
		} else {
		} else {
			cmd.hdr_table_addr = mem.phys_base;
			cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
			if (cmd == NULL) {
				IPAERR("fail to alloc hdr init cmd\n");
				rc = -ENOMEM;
				goto fail_send_cmd;
			}
			cmd->hdr_table_addr = mem.phys_base;
			desc.opcode = IPA_HDR_INIT_SYSTEM;
			desc.opcode = IPA_HDR_INIT_SYSTEM;
			desc.pyld = &cmd;
			desc.pyld = (void *)cmd;
			desc.len = sizeof(struct ipa_hdr_init_system);
			desc.len = sizeof(struct ipa_hdr_init_system);
		}
		}
	}
	}
@@ -311,6 +324,10 @@ int __ipa_commit_hdr_v2(void)
	else
	else
		rc = 0;
		rc = 0;


	kfree(dma_cmd);
	kfree(cmd);

fail_send_cmd:
	if (ipa_ctx->hdr_tbl_lcl) {
	if (ipa_ctx->hdr_tbl_lcl) {
		dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base,
		dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base,
				mem.phys_base);
				mem.phys_base);
@@ -322,6 +339,9 @@ int __ipa_commit_hdr_v2(void)
						ipa_ctx->hdr_mem.base,
						ipa_ctx->hdr_mem.base,
						ipa_ctx->hdr_mem.phys_base);
						ipa_ctx->hdr_mem.phys_base);
			ipa_ctx->hdr_mem = mem;
			ipa_ctx->hdr_mem = mem;
		} else {
			dma_free_coherent(ipa_ctx->pdev, mem.size, mem.base,
					mem.phys_base);
		}
		}
	}
	}


@@ -335,10 +355,10 @@ int __ipa_commit_hdr_v2_5(void)
	struct ipa_mem_buffer hdr_mem;
	struct ipa_mem_buffer hdr_mem;
	struct ipa_mem_buffer ctx_mem;
	struct ipa_mem_buffer ctx_mem;
	struct ipa_mem_buffer aligned_ctx_mem;
	struct ipa_mem_buffer aligned_ctx_mem;
	struct ipa_hdr_init_system hdr_init_cmd = {0};
	struct ipa_hdr_init_system *hdr_init_cmd = NULL;
	struct ipa_hw_imm_cmd_dma_shared_mem dma_cmd_hdr = {0};
	struct ipa_hw_imm_cmd_dma_shared_mem *dma_cmd_hdr = NULL;
	struct ipa_hw_imm_cmd_dma_shared_mem dma_cmd_ctx = {0};
	struct ipa_hw_imm_cmd_dma_shared_mem *dma_cmd_ctx = NULL;
	struct ipa_register_write reg_write_cmd = {0};
	struct ipa_register_write *reg_write_cmd = NULL;
	int rc = -EFAULT;
	int rc = -EFAULT;
	u32 proc_ctx_size;
	u32 proc_ctx_size;
	u32 proc_ctx_ofst;
	u32 proc_ctx_ofst;
@@ -361,15 +381,21 @@ int __ipa_commit_hdr_v2_5(void)
		if (hdr_mem.size > IPA_MEM_PART(apps_hdr_size)) {
		if (hdr_mem.size > IPA_MEM_PART(apps_hdr_size)) {
			IPAERR("tbl too big needed %d avail %d\n", hdr_mem.size,
			IPAERR("tbl too big needed %d avail %d\n", hdr_mem.size,
				IPA_MEM_PART(apps_hdr_size));
				IPA_MEM_PART(apps_hdr_size));
			goto end;
			goto fail_send_cmd1;
		} else {
		} else {
			dma_cmd_hdr.system_addr = hdr_mem.phys_base;
			dma_cmd_hdr = kzalloc(sizeof(*dma_cmd_hdr), GFP_ATOMIC);
			dma_cmd_hdr.size = hdr_mem.size;
			if (dma_cmd_hdr == NULL) {
			dma_cmd_hdr.local_addr =
				IPAERR("fail to alloc immediate cmd\n");
				rc = -ENOMEM;
				goto fail_send_cmd1;
			}
			dma_cmd_hdr->system_addr = hdr_mem.phys_base;
			dma_cmd_hdr->size = hdr_mem.size;
			dma_cmd_hdr->local_addr =
				ipa_ctx->smem_restricted_bytes +
				ipa_ctx->smem_restricted_bytes +
				IPA_MEM_PART(apps_hdr_ofst);
				IPA_MEM_PART(apps_hdr_ofst);
			desc[0].opcode = IPA_DMA_SHARED_MEM;
			desc[0].opcode = IPA_DMA_SHARED_MEM;
			desc[0].pyld = &dma_cmd_hdr;
			desc[0].pyld = (void *)dma_cmd_hdr;
			desc[0].len =
			desc[0].len =
				sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
				sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
		}
		}
@@ -377,11 +403,18 @@ int __ipa_commit_hdr_v2_5(void)
		if (hdr_mem.size > IPA_MEM_PART(apps_hdr_size_ddr)) {
		if (hdr_mem.size > IPA_MEM_PART(apps_hdr_size_ddr)) {
			IPAERR("tbl too big needed %d avail %d\n", hdr_mem.size,
			IPAERR("tbl too big needed %d avail %d\n", hdr_mem.size,
				IPA_MEM_PART(apps_hdr_size_ddr));
				IPA_MEM_PART(apps_hdr_size_ddr));
			goto end;
			goto fail_send_cmd1;
		} else {
		} else {
			hdr_init_cmd.hdr_table_addr = hdr_mem.phys_base;
			hdr_init_cmd = kzalloc(sizeof(*hdr_init_cmd),
				GFP_ATOMIC);
			if (hdr_init_cmd == NULL) {
				IPAERR("fail to alloc immediate cmd\n");
				rc = -ENOMEM;
				goto fail_send_cmd1;
			}
			hdr_init_cmd->hdr_table_addr = hdr_mem.phys_base;
			desc[0].opcode = IPA_HDR_INIT_SYSTEM;
			desc[0].opcode = IPA_HDR_INIT_SYSTEM;
			desc[0].pyld = &hdr_init_cmd;
			desc[0].pyld = (void *)hdr_init_cmd;
			desc[0].len = sizeof(struct ipa_hdr_init_system);
			desc[0].len = sizeof(struct ipa_hdr_init_system);
		}
		}
	}
	}
@@ -395,15 +428,22 @@ int __ipa_commit_hdr_v2_5(void)
			IPAERR("tbl too big needed %d avail %d\n",
			IPAERR("tbl too big needed %d avail %d\n",
				aligned_ctx_mem.size,
				aligned_ctx_mem.size,
				proc_ctx_size);
				proc_ctx_size);
			goto end;
			goto fail_send_cmd1;
		} else {
		} else {
			dma_cmd_ctx.system_addr = aligned_ctx_mem.phys_base;
			dma_cmd_ctx = kzalloc(sizeof(*dma_cmd_ctx),
			dma_cmd_ctx.size = aligned_ctx_mem.size;
				GFP_ATOMIC);
			dma_cmd_ctx.local_addr =
			if (dma_cmd_ctx == NULL) {
				IPAERR("fail to alloc immediate cmd\n");
				rc = -ENOMEM;
				goto fail_send_cmd1;
			}
			dma_cmd_ctx->system_addr = aligned_ctx_mem.phys_base;
			dma_cmd_ctx->size = aligned_ctx_mem.size;
			dma_cmd_ctx->local_addr =
				ipa_ctx->smem_restricted_bytes +
				ipa_ctx->smem_restricted_bytes +
				proc_ctx_ofst;
				proc_ctx_ofst;
			desc[1].opcode = IPA_DMA_SHARED_MEM;
			desc[1].opcode = IPA_DMA_SHARED_MEM;
			desc[1].pyld = &dma_cmd_ctx;
			desc[1].pyld = (void *)dma_cmd_ctx;
			desc[1].len =
			desc[1].len =
				sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
				sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
		}
		}
@@ -413,15 +453,23 @@ int __ipa_commit_hdr_v2_5(void)
			IPAERR("tbl too big, needed %d avail %d\n",
			IPAERR("tbl too big, needed %d avail %d\n",
				aligned_ctx_mem.size,
				aligned_ctx_mem.size,
				proc_ctx_size_ddr);
				proc_ctx_size_ddr);
			goto end;
			goto fail_send_cmd1;
		} else {
		} else {
			reg_write_cmd.offset = IPA_SYS_PKT_PROC_CNTXT_BASE_OFST;
			reg_write_cmd = kzalloc(sizeof(*reg_write_cmd),
			reg_write_cmd.value = aligned_ctx_mem.phys_base;
				GFP_ATOMIC);
			reg_write_cmd.value_mask =
			if (reg_write_cmd == NULL) {
				IPAERR("fail to alloc immediate cmd\n");
				rc = -ENOMEM;
				goto fail_send_cmd1;
			}
			reg_write_cmd->offset =
				IPA_SYS_PKT_PROC_CNTXT_BASE_OFST;
			reg_write_cmd->value = aligned_ctx_mem.phys_base;
			reg_write_cmd->value_mask =
				~(IPA_HDR_PROC_CTX_TABLE_ALIGNMENT_BYTE - 1);
				~(IPA_HDR_PROC_CTX_TABLE_ALIGNMENT_BYTE - 1);
			desc[1].pyld = &reg_write_cmd;
			desc[1].pyld = (void *)reg_write_cmd;
			desc[1].opcode = IPA_REGISTER_WRITE;
			desc[1].opcode = IPA_REGISTER_WRITE;
			desc[1].len = sizeof(reg_write_cmd);
			desc[1].len = sizeof(*reg_write_cmd);
		}
		}
	}
	}
	desc[1].type = IPA_IMM_CMD_DESC;
	desc[1].type = IPA_IMM_CMD_DESC;
@@ -432,22 +480,16 @@ int __ipa_commit_hdr_v2_5(void)
	else
	else
		rc = 0;
		rc = 0;


	if (ipa_ctx->hdr_tbl_lcl) {
fail_send_cmd1:
		dma_free_coherent(ipa_ctx->pdev, hdr_mem.size, hdr_mem.base,

			hdr_mem.phys_base);
	kfree(dma_cmd_hdr);
	} else {
	kfree(hdr_init_cmd);
		if (!rc) {
	kfree(dma_cmd_ctx);
			if (ipa_ctx->hdr_mem.phys_base)
	kfree(reg_write_cmd);
				dma_free_coherent(ipa_ctx->pdev,
				ipa_ctx->hdr_mem.size,
				ipa_ctx->hdr_mem.base,
				ipa_ctx->hdr_mem.phys_base);
			ipa_ctx->hdr_mem = hdr_mem;
		}
	}


	if (ipa_ctx->hdr_proc_ctx_tbl_lcl) {
	if (ipa_ctx->hdr_proc_ctx_tbl_lcl) {
		dma_free_coherent(ipa_ctx->pdev, ctx_mem.size, ctx_mem.base,
		dma_free_coherent(ipa_ctx->pdev, ctx_mem.size,
			ctx_mem.base,
			ctx_mem.phys_base);
			ctx_mem.phys_base);
	} else {
	} else {
		if (!rc) {
		if (!rc) {
@@ -457,9 +499,31 @@ int __ipa_commit_hdr_v2_5(void)
					ipa_ctx->hdr_proc_ctx_mem.base,
					ipa_ctx->hdr_proc_ctx_mem.base,
					ipa_ctx->hdr_proc_ctx_mem.phys_base);
					ipa_ctx->hdr_proc_ctx_mem.phys_base);
			ipa_ctx->hdr_proc_ctx_mem = ctx_mem;
			ipa_ctx->hdr_proc_ctx_mem = ctx_mem;
		} else {
			dma_free_coherent(ipa_ctx->pdev, ctx_mem.size,
				ctx_mem.base,
				ctx_mem.phys_base);
		}
		}
	}
	}


	if (ipa_ctx->hdr_tbl_lcl) {
		dma_free_coherent(ipa_ctx->pdev, hdr_mem.size,
			hdr_mem.base,
			hdr_mem.phys_base);
	} else {
		if (!rc) {
			if (ipa_ctx->hdr_mem.phys_base)
				dma_free_coherent(ipa_ctx->pdev,
				ipa_ctx->hdr_mem.size,
				ipa_ctx->hdr_mem.base,
				ipa_ctx->hdr_mem.phys_base);
			ipa_ctx->hdr_mem = hdr_mem;
		} else {
			dma_free_coherent(ipa_ctx->pdev, hdr_mem.size,
				hdr_mem.base,
				hdr_mem.phys_base);
		}
	}
end:
end:
	return rc;
	return rc;
}
}
+34 −13
Original line number Original line Diff line number Diff line
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -693,8 +693,8 @@ int __ipa_commit_rt_v2(enum ipa_ip_type ip)
	struct ipa_desc desc[2];
	struct ipa_desc desc[2];
	struct ipa_mem_buffer body;
	struct ipa_mem_buffer body;
	struct ipa_mem_buffer head;
	struct ipa_mem_buffer head;
	struct ipa_hw_imm_cmd_dma_shared_mem cmd1 = {0};
	struct ipa_hw_imm_cmd_dma_shared_mem *cmd1 = NULL;
	struct ipa_hw_imm_cmd_dma_shared_mem cmd2 = {0};
	struct ipa_hw_imm_cmd_dma_shared_mem *cmd2 = NULL;
	u16 avail;
	u16 avail;
	u32 num_modem_rt_index;
	u32 num_modem_rt_index;
	int rc = 0;
	int rc = 0;
@@ -744,34 +744,50 @@ int __ipa_commit_rt_v2(enum ipa_ip_type ip)
		goto fail_send_cmd;
		goto fail_send_cmd;
	}
	}


	cmd1.size = head.size;
	cmd1 = kzalloc(sizeof(struct ipa_hw_imm_cmd_dma_shared_mem),
	cmd1.system_addr = head.phys_base;
		GFP_KERNEL);
	cmd1.local_addr = local_addr1;
	if (cmd1 == NULL) {
		IPAERR("Failed to alloc immediate command object\n");
		rc = -ENOMEM;
		goto fail_send_cmd;
	}

	cmd1->size = head.size;
	cmd1->system_addr = head.phys_base;
	cmd1->local_addr = local_addr1;
	desc[0].opcode = IPA_DMA_SHARED_MEM;
	desc[0].opcode = IPA_DMA_SHARED_MEM;
	desc[0].pyld = &cmd1;
	desc[0].pyld = (void *)cmd1;
	desc[0].len = sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
	desc[0].len = sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
	desc[0].type = IPA_IMM_CMD_DESC;
	desc[0].type = IPA_IMM_CMD_DESC;


	if (lcl) {
	if (lcl) {
		cmd2.size = body.size;
		cmd2 = kzalloc(sizeof(struct ipa_hw_imm_cmd_dma_shared_mem),
		cmd2.system_addr = body.phys_base;
			GFP_KERNEL);
		cmd2.local_addr = local_addr2;
		if (cmd2 == NULL) {
			IPAERR("Failed to alloc immediate command object\n");
			rc = -ENOMEM;
			goto fail_send_cmd1;
		}

		cmd2->size = body.size;
		cmd2->system_addr = body.phys_base;
		cmd2->local_addr = local_addr2;


		desc[1].opcode = IPA_DMA_SHARED_MEM;
		desc[1].opcode = IPA_DMA_SHARED_MEM;
		desc[1].pyld = &cmd2;
		desc[1].pyld = (void *)cmd2;
		desc[1].len = sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
		desc[1].len = sizeof(struct ipa_hw_imm_cmd_dma_shared_mem);
		desc[1].type = IPA_IMM_CMD_DESC;
		desc[1].type = IPA_IMM_CMD_DESC;


		if (ipa_send_cmd(2, desc)) {
		if (ipa_send_cmd(2, desc)) {
			IPAERR("fail to send immediate command\n");
			IPAERR("fail to send immediate command\n");
			rc = -EFAULT;
			rc = -EFAULT;
			goto fail_send_cmd;
			goto fail_send_cmd2;
		}
		}
	} else {
	} else {
		if (ipa_send_cmd(1, desc)) {
		if (ipa_send_cmd(1, desc)) {
			IPAERR("fail to send immediate command\n");
			IPAERR("fail to send immediate command\n");
			rc = -EFAULT;
			rc = -EFAULT;
			goto fail_send_cmd;
			goto fail_send_cmd1;
		}
		}
	}
	}


@@ -782,6 +798,11 @@ int __ipa_commit_rt_v2(enum ipa_ip_type ip)
		IPA_DUMP_BUFF(body.base, body.phys_base, body.size);
		IPA_DUMP_BUFF(body.base, body.phys_base, body.size);
	}
	}
	__ipa_reap_sys_rt_tbls(ip);
	__ipa_reap_sys_rt_tbls(ip);

fail_send_cmd2:
	kfree(cmd2);
fail_send_cmd1:
	kfree(cmd1);
fail_send_cmd:
fail_send_cmd:
	dma_free_coherent(ipa_ctx->pdev, head.size, head.base, head.phys_base);
	dma_free_coherent(ipa_ctx->pdev, head.size, head.base, head.phys_base);
	if (body.size)
	if (body.size)
+2 −0
Original line number Original line Diff line number Diff line
@@ -322,11 +322,13 @@ struct ipahal_imm_cmd_dma_task_32b_addr {
/*
/*
 * struct ipahal_imm_cmd_pyld - Immediate cmd payload information
 * struct ipahal_imm_cmd_pyld - Immediate cmd payload information
 * @len: length of the buffer
 * @len: length of the buffer
 * @reserved: padding bytes to make data buffer aligned
 * @data: buffer contains the immediate command payload. Buffer goes
 * @data: buffer contains the immediate command payload. Buffer goes
 *  back to back with this structure
 *  back to back with this structure
 */
 */
struct ipahal_imm_cmd_pyld {
struct ipahal_imm_cmd_pyld {
	u16 len;
	u16 len;
	u16 reserved;
	u8 data[0];
	u8 data[0];
};
};