Loading drivers/platform/msm/ipa/ipa_i.h +4 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. * * 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 Loading Loading @@ -698,6 +698,9 @@ struct ipa_nat_mem { u32 size_base_tables; u32 size_expansion_tables; u32 public_ip_addr; void *tmp_vaddr; dma_addr_t tmp_dma_handle; bool is_tmp_mem; }; /** Loading drivers/platform/msm/ipa/ipa_nat.c +112 −26 Original line number Diff line number Diff line /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. * * 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 Loading @@ -23,6 +23,7 @@ #define IPA_NAT_SYSTEM_MEMORY 0 #define IPA_NAT_SHARED_MEMORY 1 #define IPA_NAT_TEMP_MEM_SIZE 128 static int ipa_nat_vma_fault_remap( struct vm_area_struct *vma, struct vm_fault *vmf) Loading Loading @@ -113,6 +114,31 @@ static const struct file_operations ipa_nat_fops = { .mmap = ipa_nat_mmap }; /** * allocate_temp_nat_memory() - Allocates temp nat memory * * Called during nat table delete */ void allocate_temp_nat_memory(void) { struct ipa_nat_mem *nat_ctx = &(ipa_ctx->nat_mem); int gfp_flags = GFP_KERNEL | __GFP_ZERO; nat_ctx->tmp_vaddr = dma_alloc_coherent(ipa_ctx->pdev, IPA_NAT_TEMP_MEM_SIZE, &nat_ctx->tmp_dma_handle, gfp_flags); if (nat_ctx->tmp_vaddr == NULL) { IPAERR("Temp Memory alloc failed\n"); nat_ctx->is_tmp_mem = false; return; } nat_ctx->is_tmp_mem = true; IPADBG("IPA NAT allocated temp memory successfully\n"); return; } /** * create_nat_device() - Create the NAT device * Loading Loading @@ -167,6 +193,7 @@ int create_nat_device(void) MINOR(nat_ctx->dev_num)); nat_ctx->is_dev = true; allocate_temp_nat_memory(); IPADBG("IPA NAT device created successfully\n"); result = 0; goto bail; Loading Loading @@ -225,6 +252,12 @@ int allocate_nat_device(struct ipa_ioc_nat_alloc_mem *mem) goto bail; } if (nat_ctx->is_dev_init == true) { IPAERR("Device already init\n"); result = 0; goto bail; } if (mem->size <= 0 || nat_ctx->is_dev_init == true) { IPAERR("Invalid Parameters or device is already init\n"); Loading Loading @@ -270,7 +303,8 @@ bail: */ int ipa_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) { struct ipa_desc desc = { 0 }; struct ipa_register_write *reg_write_nop; struct ipa_desc desc[2]; struct ipa_ip_v4_nat_init *cmd; u16 size = sizeof(struct ipa_ip_v4_nat_init); int result; Loading @@ -292,11 +326,31 @@ int ipa_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) goto bail; } memset(&desc, 0, sizeof(desc)); /* NO-OP IC for ensuring that IPA pipeline is empty */ reg_write_nop = kzalloc(sizeof(*reg_write_nop), GFP_KERNEL); if (!reg_write_nop) { IPAERR("no mem\n"); result = -ENOMEM; goto bail; } reg_write_nop->skip_pipeline_clear = 0; reg_write_nop->value_mask = 0x0; desc[0].opcode = IPA_REGISTER_WRITE; desc[0].type = IPA_IMM_CMD_DESC; desc[0].callback = NULL; desc[0].user1 = NULL; desc[0].user2 = 0; desc[0].pyld = (void *)reg_write_nop; desc[0].len = sizeof(*reg_write_nop); cmd = kmalloc(size, GFP_KERNEL); if (!cmd) { IPAERR("Failed to alloc immediate command object\n"); result = -ENOMEM; goto bail; goto free_nop; } if (ipa_ctx->nat_mem.vaddr) { IPADBG("using system memory for nat table\n"); Loading @@ -323,7 +377,7 @@ int ipa_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR("index_expn_offset: 0x%x\n", init->index_expn_offset); result = -EPERM; goto free_cmd; goto free_mem; } cmd->ipv4_rules_addr = ipa_ctx->nat_mem.dma_handle + init->ipv4_rules_offset; Loading Loading @@ -367,18 +421,18 @@ int ipa_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPADBG("Expansion Table size:0x%x\n", cmd->size_expansion_tables); cmd->public_ip_addr = init->ip_addr; IPADBG("Public ip address:0x%x\n", cmd->public_ip_addr); desc.opcode = IPA_IP_V4_NAT_INIT; desc.type = IPA_IMM_CMD_DESC; desc.callback = NULL; desc.user1 = NULL; desc.user2 = 0; desc.pyld = (void *)cmd; desc.len = size; desc[1].opcode = IPA_IP_V4_NAT_INIT; desc[1].type = IPA_IMM_CMD_DESC; desc[1].callback = NULL; desc[1].user1 = NULL; desc[1].user2 = 0; desc[1].pyld = (void *)cmd; desc[1].len = size; IPADBG("posting v4 init command\n"); if (ipa_send_cmd(1, &desc)) { if (ipa_send_cmd(2, desc)) { IPAERR("Fail to send immediate command\n"); result = -EPERM; goto free_cmd; goto free_mem; } ipa_ctx->nat_mem.public_ip_addr = init->ip_addr; Loading Loading @@ -412,8 +466,10 @@ int ipa_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPADBG("return\n"); result = 0; free_cmd: free_mem: kfree(cmd); free_nop: kfree(reg_write_nop); bail: return result; } Loading Loading @@ -518,7 +574,8 @@ void ipa_nat_free_mem_and_device(struct ipa_nat_mem *nat_ctx) */ int ipa_nat_del_cmd(struct ipa_ioc_v4_nat_del *del) { struct ipa_desc desc = { 0 }; struct ipa_register_write *reg_write_nop; struct ipa_desc desc[2]; struct ipa_ip_v4_nat_init *cmd; u16 size = sizeof(struct ipa_ip_v4_nat_init); u8 mem_type = IPA_NAT_SHARED_MEMORY; Loading @@ -526,16 +583,43 @@ int ipa_nat_del_cmd(struct ipa_ioc_v4_nat_del *del) int result; IPADBG("\n"); if (ipa_ctx->nat_mem.is_tmp_mem) { IPAERR("using temp memory during nat del\n"); mem_type = IPA_NAT_SYSTEM_MEMORY; base_addr = ipa_ctx->nat_mem.tmp_dma_handle; } if (del->public_ip_addr == 0) { IPADBG("Bad Parameter\n"); result = -EPERM; goto bail; } memset(&desc, 0, sizeof(desc)); /* NO-OP IC for ensuring that IPA pipeline is empty */ reg_write_nop = kzalloc(sizeof(*reg_write_nop), GFP_KERNEL); if (!reg_write_nop) { IPAERR("no mem\n"); result = -ENOMEM; goto bail; } reg_write_nop->skip_pipeline_clear = 0; reg_write_nop->value_mask = 0x0; desc[0].opcode = IPA_REGISTER_WRITE; desc[0].type = IPA_IMM_CMD_DESC; desc[0].callback = NULL; desc[0].user1 = NULL; desc[0].user2 = 0; desc[0].pyld = (void *)reg_write_nop; desc[0].len = sizeof(*reg_write_nop); cmd = kmalloc(size, GFP_KERNEL); if (cmd == NULL) { IPAERR("Failed to alloc immediate command object\n"); result = -ENOMEM; goto bail; goto free_nop; } cmd->table_index = del->table_index; cmd->ipv4_rules_addr = base_addr; Loading @@ -548,16 +632,16 @@ int ipa_nat_del_cmd(struct ipa_ioc_v4_nat_del *del) cmd->index_table_expansion_addr_type = mem_type; cmd->size_base_tables = 0; cmd->size_expansion_tables = 0; cmd->public_ip_addr = del->public_ip_addr; desc.opcode = IPA_IP_V4_NAT_INIT; desc.type = IPA_IMM_CMD_DESC; desc.callback = NULL; desc.user1 = NULL; desc.user2 = 0; desc.pyld = (void *)cmd; desc.len = size; if (ipa_send_cmd(1, &desc)) { cmd->public_ip_addr = 0; desc[1].opcode = IPA_IP_V4_NAT_INIT; desc[1].type = IPA_IMM_CMD_DESC; desc[1].callback = NULL; desc[1].user1 = NULL; desc[1].user2 = 0; desc[1].pyld = (void *)cmd; desc[1].len = size; if (ipa_send_cmd(2, desc)) { IPAERR("Fail to send immediate command\n"); result = -EPERM; goto free_mem; Loading @@ -576,6 +660,8 @@ int ipa_nat_del_cmd(struct ipa_ioc_v4_nat_del *del) result = 0; free_mem: kfree(cmd); free_nop: kfree(reg_write_nop); bail: return result; } Loading
drivers/platform/msm/ipa/ipa_i.h +4 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. * * 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 Loading Loading @@ -698,6 +698,9 @@ struct ipa_nat_mem { u32 size_base_tables; u32 size_expansion_tables; u32 public_ip_addr; void *tmp_vaddr; dma_addr_t tmp_dma_handle; bool is_tmp_mem; }; /** Loading
drivers/platform/msm/ipa/ipa_nat.c +112 −26 Original line number Diff line number Diff line /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. * * 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 Loading @@ -23,6 +23,7 @@ #define IPA_NAT_SYSTEM_MEMORY 0 #define IPA_NAT_SHARED_MEMORY 1 #define IPA_NAT_TEMP_MEM_SIZE 128 static int ipa_nat_vma_fault_remap( struct vm_area_struct *vma, struct vm_fault *vmf) Loading Loading @@ -113,6 +114,31 @@ static const struct file_operations ipa_nat_fops = { .mmap = ipa_nat_mmap }; /** * allocate_temp_nat_memory() - Allocates temp nat memory * * Called during nat table delete */ void allocate_temp_nat_memory(void) { struct ipa_nat_mem *nat_ctx = &(ipa_ctx->nat_mem); int gfp_flags = GFP_KERNEL | __GFP_ZERO; nat_ctx->tmp_vaddr = dma_alloc_coherent(ipa_ctx->pdev, IPA_NAT_TEMP_MEM_SIZE, &nat_ctx->tmp_dma_handle, gfp_flags); if (nat_ctx->tmp_vaddr == NULL) { IPAERR("Temp Memory alloc failed\n"); nat_ctx->is_tmp_mem = false; return; } nat_ctx->is_tmp_mem = true; IPADBG("IPA NAT allocated temp memory successfully\n"); return; } /** * create_nat_device() - Create the NAT device * Loading Loading @@ -167,6 +193,7 @@ int create_nat_device(void) MINOR(nat_ctx->dev_num)); nat_ctx->is_dev = true; allocate_temp_nat_memory(); IPADBG("IPA NAT device created successfully\n"); result = 0; goto bail; Loading Loading @@ -225,6 +252,12 @@ int allocate_nat_device(struct ipa_ioc_nat_alloc_mem *mem) goto bail; } if (nat_ctx->is_dev_init == true) { IPAERR("Device already init\n"); result = 0; goto bail; } if (mem->size <= 0 || nat_ctx->is_dev_init == true) { IPAERR("Invalid Parameters or device is already init\n"); Loading Loading @@ -270,7 +303,8 @@ bail: */ int ipa_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) { struct ipa_desc desc = { 0 }; struct ipa_register_write *reg_write_nop; struct ipa_desc desc[2]; struct ipa_ip_v4_nat_init *cmd; u16 size = sizeof(struct ipa_ip_v4_nat_init); int result; Loading @@ -292,11 +326,31 @@ int ipa_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) goto bail; } memset(&desc, 0, sizeof(desc)); /* NO-OP IC for ensuring that IPA pipeline is empty */ reg_write_nop = kzalloc(sizeof(*reg_write_nop), GFP_KERNEL); if (!reg_write_nop) { IPAERR("no mem\n"); result = -ENOMEM; goto bail; } reg_write_nop->skip_pipeline_clear = 0; reg_write_nop->value_mask = 0x0; desc[0].opcode = IPA_REGISTER_WRITE; desc[0].type = IPA_IMM_CMD_DESC; desc[0].callback = NULL; desc[0].user1 = NULL; desc[0].user2 = 0; desc[0].pyld = (void *)reg_write_nop; desc[0].len = sizeof(*reg_write_nop); cmd = kmalloc(size, GFP_KERNEL); if (!cmd) { IPAERR("Failed to alloc immediate command object\n"); result = -ENOMEM; goto bail; goto free_nop; } if (ipa_ctx->nat_mem.vaddr) { IPADBG("using system memory for nat table\n"); Loading @@ -323,7 +377,7 @@ int ipa_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPAERR("index_expn_offset: 0x%x\n", init->index_expn_offset); result = -EPERM; goto free_cmd; goto free_mem; } cmd->ipv4_rules_addr = ipa_ctx->nat_mem.dma_handle + init->ipv4_rules_offset; Loading Loading @@ -367,18 +421,18 @@ int ipa_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPADBG("Expansion Table size:0x%x\n", cmd->size_expansion_tables); cmd->public_ip_addr = init->ip_addr; IPADBG("Public ip address:0x%x\n", cmd->public_ip_addr); desc.opcode = IPA_IP_V4_NAT_INIT; desc.type = IPA_IMM_CMD_DESC; desc.callback = NULL; desc.user1 = NULL; desc.user2 = 0; desc.pyld = (void *)cmd; desc.len = size; desc[1].opcode = IPA_IP_V4_NAT_INIT; desc[1].type = IPA_IMM_CMD_DESC; desc[1].callback = NULL; desc[1].user1 = NULL; desc[1].user2 = 0; desc[1].pyld = (void *)cmd; desc[1].len = size; IPADBG("posting v4 init command\n"); if (ipa_send_cmd(1, &desc)) { if (ipa_send_cmd(2, desc)) { IPAERR("Fail to send immediate command\n"); result = -EPERM; goto free_cmd; goto free_mem; } ipa_ctx->nat_mem.public_ip_addr = init->ip_addr; Loading Loading @@ -412,8 +466,10 @@ int ipa_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) IPADBG("return\n"); result = 0; free_cmd: free_mem: kfree(cmd); free_nop: kfree(reg_write_nop); bail: return result; } Loading Loading @@ -518,7 +574,8 @@ void ipa_nat_free_mem_and_device(struct ipa_nat_mem *nat_ctx) */ int ipa_nat_del_cmd(struct ipa_ioc_v4_nat_del *del) { struct ipa_desc desc = { 0 }; struct ipa_register_write *reg_write_nop; struct ipa_desc desc[2]; struct ipa_ip_v4_nat_init *cmd; u16 size = sizeof(struct ipa_ip_v4_nat_init); u8 mem_type = IPA_NAT_SHARED_MEMORY; Loading @@ -526,16 +583,43 @@ int ipa_nat_del_cmd(struct ipa_ioc_v4_nat_del *del) int result; IPADBG("\n"); if (ipa_ctx->nat_mem.is_tmp_mem) { IPAERR("using temp memory during nat del\n"); mem_type = IPA_NAT_SYSTEM_MEMORY; base_addr = ipa_ctx->nat_mem.tmp_dma_handle; } if (del->public_ip_addr == 0) { IPADBG("Bad Parameter\n"); result = -EPERM; goto bail; } memset(&desc, 0, sizeof(desc)); /* NO-OP IC for ensuring that IPA pipeline is empty */ reg_write_nop = kzalloc(sizeof(*reg_write_nop), GFP_KERNEL); if (!reg_write_nop) { IPAERR("no mem\n"); result = -ENOMEM; goto bail; } reg_write_nop->skip_pipeline_clear = 0; reg_write_nop->value_mask = 0x0; desc[0].opcode = IPA_REGISTER_WRITE; desc[0].type = IPA_IMM_CMD_DESC; desc[0].callback = NULL; desc[0].user1 = NULL; desc[0].user2 = 0; desc[0].pyld = (void *)reg_write_nop; desc[0].len = sizeof(*reg_write_nop); cmd = kmalloc(size, GFP_KERNEL); if (cmd == NULL) { IPAERR("Failed to alloc immediate command object\n"); result = -ENOMEM; goto bail; goto free_nop; } cmd->table_index = del->table_index; cmd->ipv4_rules_addr = base_addr; Loading @@ -548,16 +632,16 @@ int ipa_nat_del_cmd(struct ipa_ioc_v4_nat_del *del) cmd->index_table_expansion_addr_type = mem_type; cmd->size_base_tables = 0; cmd->size_expansion_tables = 0; cmd->public_ip_addr = del->public_ip_addr; desc.opcode = IPA_IP_V4_NAT_INIT; desc.type = IPA_IMM_CMD_DESC; desc.callback = NULL; desc.user1 = NULL; desc.user2 = 0; desc.pyld = (void *)cmd; desc.len = size; if (ipa_send_cmd(1, &desc)) { cmd->public_ip_addr = 0; desc[1].opcode = IPA_IP_V4_NAT_INIT; desc[1].type = IPA_IMM_CMD_DESC; desc[1].callback = NULL; desc[1].user1 = NULL; desc[1].user2 = 0; desc[1].pyld = (void *)cmd; desc[1].len = size; if (ipa_send_cmd(2, desc)) { IPAERR("Fail to send immediate command\n"); result = -EPERM; goto free_mem; Loading @@ -576,6 +660,8 @@ int ipa_nat_del_cmd(struct ipa_ioc_v4_nat_del *del) result = 0; free_mem: kfree(cmd); free_nop: kfree(reg_write_nop); bail: return result; }