Loading drivers/platform/msm/ipa/ipa_v3/ipa_i.h +0 −14 Original line number Diff line number Diff line Loading @@ -1017,20 +1017,6 @@ struct ipa3_rx_pkt_wrapper { struct ipa3_sys_context *sys; }; /** * struct ipa_pdn_entry - IPA PDN config table entry * @public_ip: the PDN's public ip * @src_metadata: the PDN's metadata to be replaced for source NAT * @dst_metadata: the PDN's metadata to be replaced for destination NAT * @resrvd: reserved field */ struct ipa_pdn_entry { u32 public_ip; u32 src_metadata; u32 dst_metadata; u32 resrvd; }; /** * struct ipa3_nat_ipv6ct_tmp_mem - NAT/IPv6CT temporary memory * Loading drivers/platform/msm/ipa/ipa_v3/ipa_nat.c +45 −22 Original line number Diff line number Diff line Loading @@ -925,14 +925,21 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) } if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) { struct ipa_pdn_entry *pdn_entries; struct ipahal_nat_pdn_entry pdn_entry; /* store ip in pdn entries cache array */ pdn_entries = ipa3_ctx->nat_mem.pdn_mem.base; pdn_entries[0].public_ip = init->ip_addr; pdn_entries[0].dst_metadata = 0; pdn_entries[0].src_metadata = 0; pdn_entries[0].resrvd = 0; /* store ip in pdn entry cache array */ pdn_entry.public_ip = init->ip_addr; pdn_entry.src_metadata = 0; pdn_entry.dst_metadata = 0; result = ipahal_nat_construct_entry( IPAHAL_NAT_IPV4_PDN, &pdn_entry, ipa3_ctx->nat_mem.pdn_mem.base); if (result) { IPAERR("Fail to construct NAT pdn entry\n"); return result; } IPADBG("Public ip address:0x%x\n", init->ip_addr); } Loading Loading @@ -1090,7 +1097,8 @@ int ipa3_nat_mdfy_pdn(struct ipa_ioc_nat_pdn_entry *mdfy_pdn) struct ipahal_imm_cmd_pyld *cmd_pyld; int result = 0; struct ipa3_nat_mem *nat_ctx = &(ipa3_ctx->nat_mem); struct ipa_pdn_entry *pdn_entries = NULL; struct ipahal_nat_pdn_entry pdn_fields; size_t entry_size; IPADBG("\n"); Loading @@ -1115,27 +1123,42 @@ int ipa3_nat_mdfy_pdn(struct ipa_ioc_nat_pdn_entry *mdfy_pdn) goto bail; } pdn_entries = nat_ctx->pdn_mem.base; /* store ip in pdn entries cache array */ pdn_entries[mdfy_pdn->pdn_index].public_ip = mdfy_pdn->public_ip; pdn_entries[mdfy_pdn->pdn_index].dst_metadata = mdfy_pdn->dst_metadata; pdn_entries[mdfy_pdn->pdn_index].src_metadata = mdfy_pdn->src_metadata; /* store ip in pdn entry cache array */ pdn_fields.public_ip = mdfy_pdn->public_ip; pdn_fields.dst_metadata = mdfy_pdn->dst_metadata; pdn_fields.src_metadata = mdfy_pdn->src_metadata; /* mark tethering bit for remote modem */ if (ipa3_ctx->ipa_hw_type == IPA_HW_v4_1) pdn_entries[mdfy_pdn->pdn_index].src_metadata |= if (ipa3_ctx->ipa_hw_type == IPA_HW_v4_1) { pdn_fields.src_metadata |= IPA_QMAP_TETH_BIT; } /* get size of the entry */ result = ipahal_nat_entry_size( IPAHAL_NAT_IPV4_PDN, &entry_size); if (result) { IPAERR("Failed to retrieve pdn entry size\n"); goto bail; } result = ipahal_nat_construct_entry( IPAHAL_NAT_IPV4_PDN, &pdn_fields, (nat_ctx->pdn_mem.base + (mdfy_pdn->pdn_index)*(entry_size))); if (result) { IPAERR("Fail to construct NAT pdn entry\n"); goto bail; } IPADBG("Modify PDN in index: %d Public ip address:%pI4h\n", mdfy_pdn->pdn_index, &pdn_entries[mdfy_pdn->pdn_index].public_ip); &pdn_fields.public_ip); IPADBG("Modify PDN dst metadata: 0x%x src metadata: 0x%x\n", pdn_entries[mdfy_pdn->pdn_index].dst_metadata, pdn_entries[mdfy_pdn->pdn_index].src_metadata); pdn_fields.dst_metadata, pdn_fields.src_metadata); /* Copy the PDN config table to SRAM */ ipa3_nat_create_modify_pdn_cmd(&mem_cmd, false); Loading drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_nat.c +81 −1 Original line number Diff line number Diff line Loading @@ -225,6 +225,36 @@ static int ipa_nat_ipv6ct_stringify_entry_v_4_0(const void *entry, return length; } static void ipa_nat_ipv4_pdn_construct_entry_v_4_0(const void *fields, u32 *address) { const struct ipahal_nat_pdn_entry *pdn_entry = (const struct ipahal_nat_pdn_entry *)fields; struct ipa_nat_hw_pdn_entry *pdn_entry_address = (struct ipa_nat_hw_pdn_entry *)address; memset(pdn_entry_address, 0, sizeof(struct ipa_nat_hw_pdn_entry)); pdn_entry_address->public_ip = pdn_entry->public_ip; pdn_entry_address->src_metadata = pdn_entry->src_metadata; pdn_entry_address->dst_metadata = pdn_entry->dst_metadata; } static void ipa_nat_ipv4_pdn_parse_entry_v_4_0(void *fields, const u32 *address) { struct ipahal_nat_pdn_entry *pdn_entry = (struct ipahal_nat_pdn_entry *)fields; const struct ipa_nat_hw_pdn_entry *pdn_entry_address = (const struct ipa_nat_hw_pdn_entry *)address; pdn_entry->public_ip = pdn_entry_address->public_ip; pdn_entry->src_metadata = pdn_entry_address->src_metadata; pdn_entry->dst_metadata = pdn_entry_address->dst_metadata; } /* * struct ipahal_nat_obj - H/W information for specific IPA version * @entry_size - CB to get the size of the entry Loading @@ -233,12 +263,16 @@ static int ipa_nat_ipv6ct_stringify_entry_v_4_0(const void *entry, * Validity criterium depends on entry type. E.g. for NAT base table * Entry need to be with valid protocol and enabled. * @stringify_entry - CB to create string that represents an entry * @construct_entry - CB to create NAT entry using the given fields * @parse_entry - CB to parse NAT entry to the given fields structure */ struct ipahal_nat_obj { size_t (*entry_size)(void); bool (*is_entry_zeroed)(const void *entry); bool (*is_entry_valid)(const void *entry); int (*stringify_entry)(const void *entry, char *buff, size_t buff_size); void (*construct_entry)(const void *fields, u32 *address); void (*parse_entry)(void *fields, const u32 *address); }; /* Loading Loading @@ -276,7 +310,9 @@ static struct ipahal_nat_obj ipahal_nat_objs[IPA_HW_MAX][IPA_NAT_MAX] = { ipa_nat_ipv4_pdn_entry_size_v_4_0, ipa_nat_ipv4_is_pdn_entry_zeroed_v_4_0, ipa_nat_ipv4_is_pdn_entry_valid_v_4_0, ipa_nat_ipv4_pdn_stringify_entry_v_4_0 ipa_nat_ipv4_pdn_stringify_entry_v_4_0, ipa_nat_ipv4_pdn_construct_entry_v_4_0, ipa_nat_ipv4_pdn_parse_entry_v_4_0 }, [IPA_HW_v4_0][IPAHAL_NAT_IPV6CT] = { ipa_nat_ipv6ct_entry_size_v_4_0, Loading Loading @@ -436,3 +472,47 @@ int ipahal_nat_stringify_entry(enum ipahal_nat_type nat_type, void *entry, return result; } int ipahal_nat_construct_entry(enum ipahal_nat_type nat_type, const void *fields, void *address) { struct ipahal_nat_obj *nat_obj_ptr; if (WARN(address == NULL || fields == NULL, "NULL pointer received\n")) return -EINVAL; if (WARN(nat_type < 0 || nat_type >= IPA_NAT_MAX, "requested NAT type %d is invalid\n", nat_type)) return -EINVAL; IPAHAL_DBG("Create %s entry using given fields\n", ipahal_nat_type_str(nat_type)); nat_obj_ptr = &ipahal_nat_objs[ipahal_ctx->hw_type][nat_type]; nat_obj_ptr->construct_entry(fields, address); return 0; } int ipahal_nat_parse_entry(enum ipahal_nat_type nat_type, void *fields, const void *address) { struct ipahal_nat_obj *nat_obj_ptr; if (WARN(address == NULL || fields == NULL, "NULL pointer received\n")) return -EINVAL; if (WARN(nat_type < 0 || nat_type >= IPA_NAT_MAX, "requested NAT type %d is invalid\n", nat_type)) return -EINVAL; IPAHAL_DBG("Get the parsed values for NAT type=%s\n", ipahal_nat_type_str(nat_type)); nat_obj_ptr = &ipahal_nat_objs[ipahal_ctx->hw_type][nat_type]; nat_obj_ptr->parse_entry(fields, address); return 0; } drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_nat.h +31 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,18 @@ enum ipahal_nat_type { IPA_NAT_MAX }; /** * struct ipahal_nat_pdn_entry - IPA PDN config table entry * @public_ip: the PDN's public ip * @src_metadata: the PDN's metadata to be replaced for source NAT * @dst_metadata: the PDN's metadata to be replaced for destination NAT */ struct ipahal_nat_pdn_entry { u32 public_ip; u32 src_metadata; u32 dst_metadata; }; /* NAT Function APIs */ /* Loading Loading @@ -76,4 +88,23 @@ int ipahal_nat_is_entry_valid(enum ipahal_nat_type nat_type, void *entry, int ipahal_nat_stringify_entry(enum ipahal_nat_type nat_type, void *entry, char *buff, size_t buff_size); /* * ipahal_nat_construct_entry() - Create NAT entry using the given fields * @nat_type: [in] The type of the NAT entry * @fields: [in] The fields need to be written in the entry * @address: [in] The address of the memory need to be written */ int ipahal_nat_construct_entry(enum ipahal_nat_type nat_type, void const *fields, void *address); /* * ipahal_nat_parse_entry() - Parse NAT entry to the given fields structure * @nat_type: [in] The type of the NAT entry * @fields: [in] The fields need to be parsed from the entry * @address: [in] The address of the memory need to be parsed */ int ipahal_nat_parse_entry(enum ipahal_nat_type nat_type, void *fields, const void *address); #endif /* _IPAHAL_NAT_H_ */ Loading
drivers/platform/msm/ipa/ipa_v3/ipa_i.h +0 −14 Original line number Diff line number Diff line Loading @@ -1017,20 +1017,6 @@ struct ipa3_rx_pkt_wrapper { struct ipa3_sys_context *sys; }; /** * struct ipa_pdn_entry - IPA PDN config table entry * @public_ip: the PDN's public ip * @src_metadata: the PDN's metadata to be replaced for source NAT * @dst_metadata: the PDN's metadata to be replaced for destination NAT * @resrvd: reserved field */ struct ipa_pdn_entry { u32 public_ip; u32 src_metadata; u32 dst_metadata; u32 resrvd; }; /** * struct ipa3_nat_ipv6ct_tmp_mem - NAT/IPv6CT temporary memory * Loading
drivers/platform/msm/ipa/ipa_v3/ipa_nat.c +45 −22 Original line number Diff line number Diff line Loading @@ -925,14 +925,21 @@ int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init) } if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) { struct ipa_pdn_entry *pdn_entries; struct ipahal_nat_pdn_entry pdn_entry; /* store ip in pdn entries cache array */ pdn_entries = ipa3_ctx->nat_mem.pdn_mem.base; pdn_entries[0].public_ip = init->ip_addr; pdn_entries[0].dst_metadata = 0; pdn_entries[0].src_metadata = 0; pdn_entries[0].resrvd = 0; /* store ip in pdn entry cache array */ pdn_entry.public_ip = init->ip_addr; pdn_entry.src_metadata = 0; pdn_entry.dst_metadata = 0; result = ipahal_nat_construct_entry( IPAHAL_NAT_IPV4_PDN, &pdn_entry, ipa3_ctx->nat_mem.pdn_mem.base); if (result) { IPAERR("Fail to construct NAT pdn entry\n"); return result; } IPADBG("Public ip address:0x%x\n", init->ip_addr); } Loading Loading @@ -1090,7 +1097,8 @@ int ipa3_nat_mdfy_pdn(struct ipa_ioc_nat_pdn_entry *mdfy_pdn) struct ipahal_imm_cmd_pyld *cmd_pyld; int result = 0; struct ipa3_nat_mem *nat_ctx = &(ipa3_ctx->nat_mem); struct ipa_pdn_entry *pdn_entries = NULL; struct ipahal_nat_pdn_entry pdn_fields; size_t entry_size; IPADBG("\n"); Loading @@ -1115,27 +1123,42 @@ int ipa3_nat_mdfy_pdn(struct ipa_ioc_nat_pdn_entry *mdfy_pdn) goto bail; } pdn_entries = nat_ctx->pdn_mem.base; /* store ip in pdn entries cache array */ pdn_entries[mdfy_pdn->pdn_index].public_ip = mdfy_pdn->public_ip; pdn_entries[mdfy_pdn->pdn_index].dst_metadata = mdfy_pdn->dst_metadata; pdn_entries[mdfy_pdn->pdn_index].src_metadata = mdfy_pdn->src_metadata; /* store ip in pdn entry cache array */ pdn_fields.public_ip = mdfy_pdn->public_ip; pdn_fields.dst_metadata = mdfy_pdn->dst_metadata; pdn_fields.src_metadata = mdfy_pdn->src_metadata; /* mark tethering bit for remote modem */ if (ipa3_ctx->ipa_hw_type == IPA_HW_v4_1) pdn_entries[mdfy_pdn->pdn_index].src_metadata |= if (ipa3_ctx->ipa_hw_type == IPA_HW_v4_1) { pdn_fields.src_metadata |= IPA_QMAP_TETH_BIT; } /* get size of the entry */ result = ipahal_nat_entry_size( IPAHAL_NAT_IPV4_PDN, &entry_size); if (result) { IPAERR("Failed to retrieve pdn entry size\n"); goto bail; } result = ipahal_nat_construct_entry( IPAHAL_NAT_IPV4_PDN, &pdn_fields, (nat_ctx->pdn_mem.base + (mdfy_pdn->pdn_index)*(entry_size))); if (result) { IPAERR("Fail to construct NAT pdn entry\n"); goto bail; } IPADBG("Modify PDN in index: %d Public ip address:%pI4h\n", mdfy_pdn->pdn_index, &pdn_entries[mdfy_pdn->pdn_index].public_ip); &pdn_fields.public_ip); IPADBG("Modify PDN dst metadata: 0x%x src metadata: 0x%x\n", pdn_entries[mdfy_pdn->pdn_index].dst_metadata, pdn_entries[mdfy_pdn->pdn_index].src_metadata); pdn_fields.dst_metadata, pdn_fields.src_metadata); /* Copy the PDN config table to SRAM */ ipa3_nat_create_modify_pdn_cmd(&mem_cmd, false); Loading
drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_nat.c +81 −1 Original line number Diff line number Diff line Loading @@ -225,6 +225,36 @@ static int ipa_nat_ipv6ct_stringify_entry_v_4_0(const void *entry, return length; } static void ipa_nat_ipv4_pdn_construct_entry_v_4_0(const void *fields, u32 *address) { const struct ipahal_nat_pdn_entry *pdn_entry = (const struct ipahal_nat_pdn_entry *)fields; struct ipa_nat_hw_pdn_entry *pdn_entry_address = (struct ipa_nat_hw_pdn_entry *)address; memset(pdn_entry_address, 0, sizeof(struct ipa_nat_hw_pdn_entry)); pdn_entry_address->public_ip = pdn_entry->public_ip; pdn_entry_address->src_metadata = pdn_entry->src_metadata; pdn_entry_address->dst_metadata = pdn_entry->dst_metadata; } static void ipa_nat_ipv4_pdn_parse_entry_v_4_0(void *fields, const u32 *address) { struct ipahal_nat_pdn_entry *pdn_entry = (struct ipahal_nat_pdn_entry *)fields; const struct ipa_nat_hw_pdn_entry *pdn_entry_address = (const struct ipa_nat_hw_pdn_entry *)address; pdn_entry->public_ip = pdn_entry_address->public_ip; pdn_entry->src_metadata = pdn_entry_address->src_metadata; pdn_entry->dst_metadata = pdn_entry_address->dst_metadata; } /* * struct ipahal_nat_obj - H/W information for specific IPA version * @entry_size - CB to get the size of the entry Loading @@ -233,12 +263,16 @@ static int ipa_nat_ipv6ct_stringify_entry_v_4_0(const void *entry, * Validity criterium depends on entry type. E.g. for NAT base table * Entry need to be with valid protocol and enabled. * @stringify_entry - CB to create string that represents an entry * @construct_entry - CB to create NAT entry using the given fields * @parse_entry - CB to parse NAT entry to the given fields structure */ struct ipahal_nat_obj { size_t (*entry_size)(void); bool (*is_entry_zeroed)(const void *entry); bool (*is_entry_valid)(const void *entry); int (*stringify_entry)(const void *entry, char *buff, size_t buff_size); void (*construct_entry)(const void *fields, u32 *address); void (*parse_entry)(void *fields, const u32 *address); }; /* Loading Loading @@ -276,7 +310,9 @@ static struct ipahal_nat_obj ipahal_nat_objs[IPA_HW_MAX][IPA_NAT_MAX] = { ipa_nat_ipv4_pdn_entry_size_v_4_0, ipa_nat_ipv4_is_pdn_entry_zeroed_v_4_0, ipa_nat_ipv4_is_pdn_entry_valid_v_4_0, ipa_nat_ipv4_pdn_stringify_entry_v_4_0 ipa_nat_ipv4_pdn_stringify_entry_v_4_0, ipa_nat_ipv4_pdn_construct_entry_v_4_0, ipa_nat_ipv4_pdn_parse_entry_v_4_0 }, [IPA_HW_v4_0][IPAHAL_NAT_IPV6CT] = { ipa_nat_ipv6ct_entry_size_v_4_0, Loading Loading @@ -436,3 +472,47 @@ int ipahal_nat_stringify_entry(enum ipahal_nat_type nat_type, void *entry, return result; } int ipahal_nat_construct_entry(enum ipahal_nat_type nat_type, const void *fields, void *address) { struct ipahal_nat_obj *nat_obj_ptr; if (WARN(address == NULL || fields == NULL, "NULL pointer received\n")) return -EINVAL; if (WARN(nat_type < 0 || nat_type >= IPA_NAT_MAX, "requested NAT type %d is invalid\n", nat_type)) return -EINVAL; IPAHAL_DBG("Create %s entry using given fields\n", ipahal_nat_type_str(nat_type)); nat_obj_ptr = &ipahal_nat_objs[ipahal_ctx->hw_type][nat_type]; nat_obj_ptr->construct_entry(fields, address); return 0; } int ipahal_nat_parse_entry(enum ipahal_nat_type nat_type, void *fields, const void *address) { struct ipahal_nat_obj *nat_obj_ptr; if (WARN(address == NULL || fields == NULL, "NULL pointer received\n")) return -EINVAL; if (WARN(nat_type < 0 || nat_type >= IPA_NAT_MAX, "requested NAT type %d is invalid\n", nat_type)) return -EINVAL; IPAHAL_DBG("Get the parsed values for NAT type=%s\n", ipahal_nat_type_str(nat_type)); nat_obj_ptr = &ipahal_nat_objs[ipahal_ctx->hw_type][nat_type]; nat_obj_ptr->parse_entry(fields, address); return 0; }
drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_nat.h +31 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,18 @@ enum ipahal_nat_type { IPA_NAT_MAX }; /** * struct ipahal_nat_pdn_entry - IPA PDN config table entry * @public_ip: the PDN's public ip * @src_metadata: the PDN's metadata to be replaced for source NAT * @dst_metadata: the PDN's metadata to be replaced for destination NAT */ struct ipahal_nat_pdn_entry { u32 public_ip; u32 src_metadata; u32 dst_metadata; }; /* NAT Function APIs */ /* Loading Loading @@ -76,4 +88,23 @@ int ipahal_nat_is_entry_valid(enum ipahal_nat_type nat_type, void *entry, int ipahal_nat_stringify_entry(enum ipahal_nat_type nat_type, void *entry, char *buff, size_t buff_size); /* * ipahal_nat_construct_entry() - Create NAT entry using the given fields * @nat_type: [in] The type of the NAT entry * @fields: [in] The fields need to be written in the entry * @address: [in] The address of the memory need to be written */ int ipahal_nat_construct_entry(enum ipahal_nat_type nat_type, void const *fields, void *address); /* * ipahal_nat_parse_entry() - Parse NAT entry to the given fields structure * @nat_type: [in] The type of the NAT entry * @fields: [in] The fields need to be parsed from the entry * @address: [in] The address of the memory need to be parsed */ int ipahal_nat_parse_entry(enum ipahal_nat_type nat_type, void *fields, const void *address); #endif /* _IPAHAL_NAT_H_ */