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

Commit d59d06ba authored by Amir Levy's avatar Amir Levy Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: Add support for pdn in hal



Add new support for pdn in ipa-hal.
Create new API for pdn on ipa-hal nat.

Change-Id: I21fd3e187663b09362db194b5d71770fbe72a074
Acked-by: default avatarMichal Amsterdam <mamsterd@qti.qualcomm.com>
Signed-off-by: default avatarAmir Levy <alevy@codeaurora.org>
parent e6c311a9
Loading
Loading
Loading
Loading
+0 −14
Original line number Diff line number Diff line
@@ -1006,20 +1006,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
 *
+45 −22
Original line number Diff line number Diff line
@@ -917,14 +917,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);
	}
@@ -1082,7 +1089,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");

@@ -1107,27 +1115,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);
+81 −1
Original line number Diff line number Diff line
@@ -218,6 +218,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
@@ -226,12 +256,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);
};

/*
@@ -269,7 +303,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,
@@ -429,3 +465,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;
}
+31 −0
Original line number Diff line number Diff line
@@ -20,6 +20,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 */

/*
@@ -69,4 +81,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_ */