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

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

msm: ipa3: Adapt the FnR rules parameters to IPAv3



IPAv3 has different filtering and routing rules parameters
structure. The equations bits were changed and order of the
parameters were changed. Some new Extra words fields holding
the equations offsets introduced as well.
The Masked-Equal-128 equation parameters format changed
compared to previous IPA versions.

Change-Id: I3c022ba353387630971b8643e8f9d76b047ec200
Signed-off-by: default avatarGhanim Fodi <gfodi@codeaurora.org>
Signed-off-by: default avatarAmir Levy <alevy@codeaurora.org>
parent bf8b35e2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1068,6 +1068,7 @@ int ipa3_setup_dflt_rt_tables(void)
	rt_rule_entry->at_rear = 1;
	rt_rule_entry->rule.dst = IPA_CLIENT_APPS_LAN_CONS;
	rt_rule_entry->rule.hdr_hdl = ipa3_ctx->excp_hdr_hdl;
	rt_rule_entry->rule.retain_hdr = 1;

	if (ipa3_add_rt_rule(rt_rule)) {
		IPAERR("fail to add dflt v4 rule\n");
+141 −93
Original line number Diff line number Diff line
@@ -23,6 +23,31 @@
	(IPA_RULE_HASHABLE):(IPA_RULE_NON_HASHABLE) \
	)

static int ipa3_calc_extra_wrd_bytes(
	const struct ipa_ipfltri_rule_eq *attrib)
{
	int num = 0;

	if (attrib->tos_eq_present)
		num++;
	if (attrib->protocol_eq_present)
		num++;
	if (attrib->tc_eq_present)
		num++;
	num += attrib->num_offset_meq_128;
	num += attrib->num_offset_meq_32;
	num += attrib->num_ihl_offset_meq_32;
	num += attrib->num_ihl_offset_range_16;
	if (attrib->ihl_offset_eq_32_present)
		num++;
	if (attrib->ihl_offset_eq_16_present)
		num++;

	IPADBG("extra bytes number %d\n", num);

	return num;
}

static int ipa3_generate_hw_rule_from_eq(
		const struct ipa_ipfltri_rule_eq *attrib, u8 **buf)
{
@@ -31,127 +56,149 @@ static int ipa3_generate_hw_rule_from_eq(
	int num_ihl_offset_meq_32 = attrib->num_ihl_offset_meq_32;
	int num_offset_meq_128 = attrib->num_offset_meq_128;
	int i;
	int extra_bytes;
	u8 *extra;
	u8 *rest;

	extra_bytes = ipa3_calc_extra_wrd_bytes(attrib);
	/* only 3 eq does not have extra word param, 13 out of 16 is the number
	 * of equations that needs extra word param*/
	if (extra_bytes > 13) {
		IPAERR("too much extra bytes\n");
		return -EPERM;
	} else if (extra_bytes > IPA_HW_TBL_HDR_WIDTH) {
		/* two extra words */
		extra = *buf;
		rest = *buf + IPA_HW_TBL_HDR_WIDTH * 2;
	} else if (extra_bytes > 0) {
		/* single exra word */
		extra = *buf;
		rest = *buf + IPA_HW_TBL_HDR_WIDTH;
	} else {
		/* no extra words */
		extra = NULL;
		rest = *buf;
	}

	if (attrib->tos_eq_present)
		extra = ipa3_write_8(attrib->tos_eq, extra);

	if (attrib->tos_eq_present) {
		*buf = ipa3_write_8(attrib->tos_eq, *buf);
		*buf = ipa3_pad_to_32(*buf);
	if (attrib->protocol_eq_present)
		extra = ipa3_write_8(attrib->protocol_eq, extra);

	if (attrib->tc_eq_present)
		extra = ipa3_write_8(attrib->tc_eq, extra);

	if (num_offset_meq_128) {
		extra = ipa3_write_8(attrib->offset_meq_128[0].offset, extra);
		for (i = 0; i < 8; i++)
			rest = ipa3_write_8(attrib->offset_meq_128[0].mask[i],
				rest);
		for (i = 0; i < 8; i++)
			rest = ipa3_write_8(attrib->offset_meq_128[0].value[i],
				rest);
		for (i = 8; i < 16; i++)
			rest = ipa3_write_8(attrib->offset_meq_128[0].mask[i],
				rest);
		for (i = 8; i < 16; i++)
			rest = ipa3_write_8(attrib->offset_meq_128[0].value[i],
				rest);
		num_offset_meq_128--;
	}

	if (attrib->protocol_eq_present) {
		*buf = ipa3_write_8(attrib->protocol_eq, *buf);
		*buf = ipa3_pad_to_32(*buf);
	if (num_offset_meq_128) {
		extra = ipa3_write_8(attrib->offset_meq_128[1].offset, extra);
		for (i = 0; i < 8; i++)
			rest = ipa3_write_8(attrib->offset_meq_128[1].mask[i],
				rest);
		for (i = 0; i < 8; i++)
			rest = ipa3_write_8(attrib->offset_meq_128[1].value[i],
				rest);
		for (i = 8; i < 16; i++)
			rest = ipa3_write_8(attrib->offset_meq_128[1].mask[i],
				rest);
		for (i = 8; i < 16; i++)
			rest = ipa3_write_8(attrib->offset_meq_128[1].value[i],
				rest);
		num_offset_meq_128--;
	}

	if (num_offset_meq_32) {
		*buf = ipa3_write_8(attrib->offset_meq_32[0].offset, *buf);
		*buf = ipa3_write_32(attrib->offset_meq_32[0].mask, *buf);
		*buf = ipa3_write_32(attrib->offset_meq_32[0].value, *buf);
		*buf = ipa3_pad_to_32(*buf);
		extra = ipa3_write_8(attrib->offset_meq_32[0].offset, extra);
		rest = ipa3_write_32(attrib->offset_meq_32[0].mask, rest);
		rest = ipa3_write_32(attrib->offset_meq_32[0].value, rest);
		num_offset_meq_32--;
	}

	if (num_offset_meq_32) {
		*buf = ipa3_write_8(attrib->offset_meq_32[1].offset, *buf);
		*buf = ipa3_write_32(attrib->offset_meq_32[1].mask, *buf);
		*buf = ipa3_write_32(attrib->offset_meq_32[1].value, *buf);
		*buf = ipa3_pad_to_32(*buf);
		extra = ipa3_write_8(attrib->offset_meq_32[1].offset, extra);
		rest = ipa3_write_32(attrib->offset_meq_32[1].mask, rest);
		rest = ipa3_write_32(attrib->offset_meq_32[1].value, rest);
		num_offset_meq_32--;
	}

	if (num_ihl_offset_range_16) {
		*buf = ipa3_write_8(attrib->ihl_offset_range_16[0].offset,
				*buf);
		*buf = ipa3_write_16(attrib->ihl_offset_range_16[0].range_high,
				*buf);
		*buf = ipa3_write_16(attrib->ihl_offset_range_16[0].range_low,
				*buf);
		*buf = ipa3_pad_to_32(*buf);
		num_ihl_offset_range_16--;
	}

	if (num_ihl_offset_range_16) {
		*buf = ipa3_write_8(attrib->ihl_offset_range_16[1].offset,
				*buf);
		*buf = ipa3_write_16(attrib->ihl_offset_range_16[1].range_high,
				*buf);
		*buf = ipa3_write_16(attrib->ihl_offset_range_16[1].range_low,
				*buf);
		*buf = ipa3_pad_to_32(*buf);
		num_ihl_offset_range_16--;
	}

	if (attrib->ihl_offset_eq_16_present) {
		*buf = ipa3_write_8(attrib->ihl_offset_eq_16.offset, *buf);
		*buf = ipa3_write_16(attrib->ihl_offset_eq_16.value, *buf);
		*buf = ipa3_pad_to_32(*buf);
	}
	if (num_ihl_offset_meq_32) {
		extra = ipa3_write_8(attrib->ihl_offset_meq_32[0].offset,
		extra);

	if (attrib->ihl_offset_eq_32_present) {
		*buf = ipa3_write_8(attrib->ihl_offset_eq_32.offset, *buf);
		*buf = ipa3_write_32(attrib->ihl_offset_eq_32.value, *buf);
		*buf = ipa3_pad_to_32(*buf);
		rest = ipa3_write_32(attrib->ihl_offset_meq_32[0].mask, rest);
		rest = ipa3_write_32(attrib->ihl_offset_meq_32[0].value, rest);
		num_ihl_offset_meq_32--;
	}

	if (num_ihl_offset_meq_32) {
		*buf = ipa3_write_8(attrib->ihl_offset_meq_32[0].offset, *buf);
		*buf = ipa3_write_32(attrib->ihl_offset_meq_32[0].mask, *buf);
		*buf = ipa3_write_32(attrib->ihl_offset_meq_32[0].value, *buf);
		*buf = ipa3_pad_to_32(*buf);
		extra = ipa3_write_8(attrib->ihl_offset_meq_32[1].offset,
		extra);

		rest = ipa3_write_32(attrib->ihl_offset_meq_32[1].mask, rest);
		rest = ipa3_write_32(attrib->ihl_offset_meq_32[1].value, rest);
		num_ihl_offset_meq_32--;
	}

	/* TODO check layout of 16 byte mask and value */
	if (num_offset_meq_128) {
		*buf = ipa3_write_8(attrib->offset_meq_128[0].offset, *buf);
		for (i = 0; i < 16; i++)
			*buf = ipa3_write_8(attrib->offset_meq_128[0].mask[i],
					*buf);
		for (i = 0; i < 16; i++)
			*buf = ipa3_write_8(attrib->offset_meq_128[0].value[i],
					*buf);
		*buf = ipa3_pad_to_32(*buf);
		num_offset_meq_128--;
	if (attrib->metadata_meq32_present) {
		rest = ipa3_write_32(attrib->metadata_meq32.mask, rest);
		rest = ipa3_write_32(attrib->metadata_meq32.value, rest);
	}

	if (num_offset_meq_128) {
		*buf = ipa3_write_8(attrib->offset_meq_128[1].offset, *buf);
		for (i = 0; i < 16; i++)
			*buf = ipa3_write_8(attrib->offset_meq_128[1].mask[i],
					*buf);
		for (i = 0; i < 16; i++)
			*buf = ipa3_write_8(attrib->offset_meq_128[1].value[i],
					*buf);
		*buf = ipa3_pad_to_32(*buf);
		num_offset_meq_128--;
	}
	if (num_ihl_offset_range_16) {
		extra = ipa3_write_8(attrib->ihl_offset_range_16[0].offset,
		extra);

	if (attrib->tc_eq_present) {
		*buf = ipa3_write_8(attrib->tc_eq, *buf);
		*buf = ipa3_pad_to_32(*buf);
		rest = ipa3_write_16(attrib->ihl_offset_range_16[0].range_high,
				rest);
		rest = ipa3_write_16(attrib->ihl_offset_range_16[0].range_low,
				rest);
		num_ihl_offset_range_16--;
	}

	if (attrib->fl_eq_present) {
		*buf = ipa3_write_32(attrib->fl_eq, *buf);
		*buf = ipa3_pad_to_32(*buf);
	if (num_ihl_offset_range_16) {
		extra = ipa3_write_8(attrib->ihl_offset_range_16[1].offset,
		extra);

		rest = ipa3_write_16(attrib->ihl_offset_range_16[1].range_high,
				rest);
		rest = ipa3_write_16(attrib->ihl_offset_range_16[1].range_low,
				rest);
		num_ihl_offset_range_16--;
	}

	if (num_ihl_offset_meq_32) {
		*buf = ipa3_write_8(attrib->ihl_offset_meq_32[1].offset, *buf);
		*buf = ipa3_write_32(attrib->ihl_offset_meq_32[1].mask, *buf);
		*buf = ipa3_write_32(attrib->ihl_offset_meq_32[1].value, *buf);
		*buf = ipa3_pad_to_32(*buf);
		num_ihl_offset_meq_32--;
	if (attrib->ihl_offset_eq_32_present) {
		extra = ipa3_write_8(attrib->ihl_offset_eq_32.offset, extra);
		rest = ipa3_write_32(attrib->ihl_offset_eq_32.value, rest);
	}

	if (attrib->metadata_meq32_present) {
		*buf = ipa3_write_8(attrib->metadata_meq32.offset, *buf);
		*buf = ipa3_write_32(attrib->metadata_meq32.mask, *buf);
		*buf = ipa3_write_32(attrib->metadata_meq32.value, *buf);
		*buf = ipa3_pad_to_32(*buf);
	if (attrib->ihl_offset_eq_16_present) {
		extra = ipa3_write_8(attrib->ihl_offset_eq_16.offset, extra);
		rest = ipa3_write_16(attrib->ihl_offset_eq_16.value, rest);
		rest = ipa3_write_16(0, rest);
	}

	if (attrib->ipv4_frag_eq_present)
		*buf = ipa3_pad_to_32(*buf);
	if (attrib->fl_eq_present)
		rest = ipa3_write_32(attrib->fl_eq & 0xFFFFF, rest);

	extra = ipa3_pad_to_64(extra);
	rest = ipa3_pad_to_64(rest);
	*buf = rest;

	return 0;
}
@@ -1427,7 +1474,10 @@ void ipa3_install_dflt_flt_rules(u32 ipa_ep_idx)
	struct ipa3_ep_context *ep = &ipa3_ctx->ep[ipa_ep_idx];
	struct ipa_flt_rule rule;

	if (!ipa_is_ep_support_flt(ipa_ep_idx)) {
		IPAERR("cannot add flt rules to non filtering pipe");
		return;
	}

	memset(&rule, 0, sizeof(rule));

@@ -1452,8 +1502,6 @@ void ipa3_delete_dflt_flt_rules(u32 ipa_ep_idx)
{
	struct ipa3_ep_context *ep = &ipa3_ctx->ep[ipa_ep_idx];

	return;

	mutex_lock(&ipa3_ctx->lock);
	if (ep->dflt_flt4_rule_hdl) {
		__ipa_del_flt_rule(ep->dflt_flt4_rule_hdl);
+14 −13
Original line number Diff line number Diff line
@@ -81,19 +81,19 @@

#define IPA_TOS_EQ			BIT(0)
#define IPA_PROTOCOL_EQ			BIT(1)
#define IPA_OFFSET_MEQ32_0		BIT(2)
#define IPA_OFFSET_MEQ32_1		BIT(3)
#define IPA_IHL_OFFSET_RANGE16_0	BIT(4)
#define IPA_IHL_OFFSET_RANGE16_1	BIT(5)
#define IPA_IHL_OFFSET_EQ_16		BIT(6)
#define IPA_IHL_OFFSET_EQ_32		BIT(7)
#define IPA_IHL_OFFSET_MEQ32_0		BIT(8)
#define IPA_OFFSET_MEQ128_0		BIT(9)
#define IPA_OFFSET_MEQ128_1		BIT(10)
#define IPA_TC_EQ			BIT(11)
#define IPA_FL_EQ			BIT(12)
#define IPA_IHL_OFFSET_MEQ32_1		BIT(13)
#define IPA_METADATA_COMPARE		BIT(14)
#define IPA_TC_EQ			BIT(2)
#define IPA_OFFSET_MEQ128_0		BIT(3)
#define IPA_OFFSET_MEQ128_1		BIT(4)
#define IPA_OFFSET_MEQ32_0		BIT(5)
#define IPA_OFFSET_MEQ32_1		BIT(6)
#define IPA_IHL_OFFSET_MEQ32_0		BIT(7)
#define IPA_IHL_OFFSET_MEQ32_1		BIT(8)
#define IPA_METADATA_COMPARE		BIT(9)
#define IPA_IHL_OFFSET_RANGE16_0	BIT(10)
#define IPA_IHL_OFFSET_RANGE16_1	BIT(11)
#define IPA_IHL_OFFSET_EQ_32		BIT(12)
#define IPA_IHL_OFFSET_EQ_16		BIT(13)
#define IPA_FL_EQ			BIT(14)
#define IPA_IS_FRAG			BIT(15)

#define IPA_HDR_BIN0 0
@@ -1810,6 +1810,7 @@ u8 *ipa3_write_32(u32 w, u8 *dest);
u8 *ipa3_write_16(u16 hw, u8 *dest);
u8 *ipa3_write_8(u8 b, u8 *dest);
u8 *ipa3_pad_to_32(u8 *dest);
u8 *ipa3_pad_to_64(u8 *dest);
int ipa3_init_hw(void);
struct ipa3_rt_tbl *__ipa3_find_rt_tbl(enum ipa_ip_type ip, const char *name);
int ipa3_set_single_ndp_per_mbim(bool);
+632 −525

File changed.

Preview size limit exceeded, changes collapsed.