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

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

msm: ipa: add a thin parsing option for status packets



In the LAN rx data path the status packet was parsed twice
but in the second time it parsed not all the info was needed.
So we added a function that is tailored for that scenario
to improve performance.

Acked-by: default avatarTal Gelbard <tgelbard@qti.qualcomm.com>
Change-Id: I8a1755ba62cee4147941b5949c2b223fe76415b2
Signed-off-by: default avatarAmir Levy <alevy@codeaurora.org>
parent d976e318
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -3210,13 +3210,13 @@ static void ipa3_free_skb_rx(struct sk_buff *skb)
void ipa3_lan_rx_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
{
	struct sk_buff *rx_skb = (struct sk_buff *)data;
	struct ipahal_pkt_status status;
	struct ipahal_pkt_status_thin status;
	struct ipa3_ep_context *ep;
	unsigned int src_pipe;
	u32 metadata;
	u8 ucp;

	ipahal_pkt_status_parse(rx_skb->data, &status);
	ipahal_pkt_status_parse_thin(rx_skb->data, &status);
	src_pipe = status.endp_src_idx;
	metadata = status.metadata;
	ucp = status.ucp;
+108 −35
Original line number Diff line number Diff line
@@ -863,11 +863,53 @@ struct ipahal_imm_cmd_pyld *ipahal_construct_nop_imm_cmd(
	(status->status_mask |= \
		((hw_status->status_mask & (__hw_bit_msk) ? 1 : 0) << (__shft)))

static enum ipahal_pkt_status_exception pkt_status_parse_exception(
	bool is_ipv6, u64 exception)
{
	enum ipahal_pkt_status_exception exception_type = 0;

	switch (exception) {
	case 0:
		exception_type = IPAHAL_PKT_STATUS_EXCEPTION_NONE;
		break;
	case 1:
		exception_type = IPAHAL_PKT_STATUS_EXCEPTION_DEAGGR;
		break;
	case 4:
		exception_type = IPAHAL_PKT_STATUS_EXCEPTION_IPTYPE;
		break;
	case 8:
		exception_type = IPAHAL_PKT_STATUS_EXCEPTION_PACKET_LENGTH;
		break;
	case 16:
		exception_type = IPAHAL_PKT_STATUS_EXCEPTION_FRAG_RULE_MISS;
		break;
	case 32:
		exception_type = IPAHAL_PKT_STATUS_EXCEPTION_SW_FILT;
		break;
	case 64:
		if (is_ipv6)
			exception_type = IPAHAL_PKT_STATUS_EXCEPTION_IPV6CT;
		else
			exception_type = IPAHAL_PKT_STATUS_EXCEPTION_NAT;
		break;
	case 229:
		exception_type = IPAHAL_PKT_STATUS_EXCEPTION_CSUM;
		break;
	default:
		IPAHAL_ERR("unsupported Status Exception type 0x%x\n",
			exception);
		WARN_ON(1);
	}

	return exception_type;
}


static void ipa_pkt_status_parse(
	const void *unparsed_status, struct ipahal_pkt_status *status)
{
	enum ipahal_pkt_status_opcode opcode = 0;
	enum ipahal_pkt_status_exception exception_type = 0;
	bool is_ipv6;

	struct ipa_pkt_status_hw *hw_status =
@@ -945,40 +987,8 @@ static void ipa_pkt_status_parse(
		IPAHAL_ERR_RL("unsupported Status NAT type 0x%x\n",
			hw_status->nat_type);
	}

	switch (hw_status->exception) {
	case 0:
		exception_type = IPAHAL_PKT_STATUS_EXCEPTION_NONE;
		break;
	case 1:
		exception_type = IPAHAL_PKT_STATUS_EXCEPTION_DEAGGR;
		break;
	case 4:
		exception_type = IPAHAL_PKT_STATUS_EXCEPTION_IPTYPE;
		break;
	case 8:
		exception_type = IPAHAL_PKT_STATUS_EXCEPTION_PACKET_LENGTH;
		break;
	case 16:
		exception_type = IPAHAL_PKT_STATUS_EXCEPTION_FRAG_RULE_MISS;
		break;
	case 32:
		exception_type = IPAHAL_PKT_STATUS_EXCEPTION_SW_FILT;
		break;
	case 64:
		if (is_ipv6)
			exception_type = IPAHAL_PKT_STATUS_EXCEPTION_IPV6CT;
		else
			exception_type = IPAHAL_PKT_STATUS_EXCEPTION_NAT;
		break;
	case 229:
		exception_type = IPAHAL_PKT_STATUS_EXCEPTION_CSUM;
		break;
	default:
		IPAHAL_ERR_RL("unsupported Status Exception type 0x%x\n",
	status->exception = pkt_status_parse_exception(is_ipv6,
						hw_status->exception);
	}
	status->exception = exception_type;

	IPA_PKT_STATUS_SET_MSK(0x1, IPAHAL_PKT_STATUS_MASK_FRAG_PROCESS_SHFT);
	IPA_PKT_STATUS_SET_MSK(0x2, IPAHAL_PKT_STATUS_MASK_FILT_PROCESS_SHFT);
@@ -1002,16 +1012,50 @@ static void ipa_pkt_status_parse(
	status->status_mask &= 0xFFFF;
}

/*
 * ipa_pkt_status_parse_thin() - Parse some of the packet status fields
 * for specific usage in the LAN rx data path where parsing needs to be done
 * but only for specific fields.
 * @unparsed_status: Pointer to H/W format of the packet status as read from HW
 * @status: Pointer to pre-allocated buffer where the parsed info will be
 * stored
 */
static void ipa_pkt_status_parse_thin(const void *unparsed_status,
	struct ipahal_pkt_status_thin *status)
{
	struct ipa_pkt_status_hw *hw_status =
		(struct ipa_pkt_status_hw *)unparsed_status;
	bool is_ipv6;

	is_ipv6 = (hw_status->status_mask & 0x80) ? false : true;
	if (!unparsed_status || !status) {
		IPAHAL_ERR("Input Error: unparsed_status=%pK status=%pK\n",
			unparsed_status, status);
		return;
	}

	IPAHAL_DBG_LOW("Parse Thin Status Packet\n");
	status->metadata = hw_status->metadata;
	status->endp_src_idx = hw_status->endp_src_idx;
	status->ucp = hw_status->ucp;
	status->exception = pkt_status_parse_exception(is_ipv6,
						hw_status->exception);
}

/*
 * struct ipahal_pkt_status_obj - Pakcet Status H/W information for
 *  specific IPA version
 * @size: H/W size of the status packet
 * @parse: CB that parses the H/W packet status into the abstracted structure
 * @parse_thin: light weight CB that parses only some of the fields for
 * data path optimization
 */
struct ipahal_pkt_status_obj {
	u32 size;
	void (*parse)(const void *unparsed_status,
		struct ipahal_pkt_status *status);
	void (*parse_thin)(const void *unparsed_status,
			struct ipahal_pkt_status_thin *status);
};

/*
@@ -1027,6 +1071,7 @@ static struct ipahal_pkt_status_obj ipahal_pkt_status_objs[IPA_HW_MAX] = {
	[IPA_HW_v3_0] = {
		IPA3_0_PKT_STATUS_SIZE,
		ipa_pkt_status_parse,
		ipa_pkt_status_parse_thin,
		},
};

@@ -1050,6 +1095,8 @@ static int ipahal_pkt_status_init(enum ipa_hw_type ipa_hw_type)
	/*
	 * Since structure alignment is implementation dependent,
	 * add test to avoid different and incompatible data layouts.
	 * If test fails it also means that ipahal_pkt_status_parse_thin
	 * need to be checked.
	 *
	 * In case new H/W has different size or structure of status packet,
	 * add a compile time validty check for it like below (as well as
@@ -1082,6 +1129,12 @@ static int ipahal_pkt_status_init(enum ipa_hw_type ipa_hw_type)
				  i+1);
				WARN_ON(1);
			}
			if (!ipahal_pkt_status_objs[i+1].parse_thin) {
				IPAHAL_ERR(
				  "Packet Status without Parse_thin func ipa_ver=%d\n",
				  i+1);
				WARN_ON(1);
			}
		}
	}

@@ -1116,6 +1169,26 @@ void ipahal_pkt_status_parse(const void *unparsed_status,
		status);
}

/*
 * ipahal_pkt_status_parse_thin() - Similar to iphal_pkt_status_parse,
 * the difference is it only parses some of the status packet fields
 * used for TP optimization.
 * @unparsed_status: Pointer to H/W format of the packet status as read from H/W
 * @status: Pointer to pre-allocated buffer where the parsed info will be stored
 */
void ipahal_pkt_status_parse_thin(const void *unparsed_status,
	struct ipahal_pkt_status_thin *status)
{
	if (!unparsed_status || !status) {
		IPAHAL_ERR("Input Error: unparsed_status=%pK status=%pK\n",
			unparsed_status, status);
		return;
	}
	IPAHAL_DBG_LOW("Parse_thin Status Packet\n");
	ipahal_pkt_status_objs[ipahal_ctx->hw_type].parse_thin(unparsed_status,
				status);
}

/*
 * ipahal_pkt_status_exception_str() - returns string represents exception type
 * @exception: [in] The exception type
+26 −0
Original line number Diff line number Diff line
@@ -588,6 +588,21 @@ struct ipahal_pkt_status {
	u8 frag_rule;
};

/*
 * struct ipahal_pkt_status_thin - this struct is used to parse only
 *  a few fields from the status packet, needed for LAN optimization.
 * @exception: The first exception that took place.
 * @metadata: meta data value used by packet
 * @endp_src_idx: Source end point index.
 * @ucp: UC Processing flag
 */
struct ipahal_pkt_status_thin {
	enum ipahal_pkt_status_exception exception;
	u32 metadata;
	u8 endp_src_idx;
	bool ucp;
};

/*
 * ipahal_pkt_status_get_size() - Get H/W size of packet status
 */
@@ -601,6 +616,17 @@ u32 ipahal_pkt_status_get_size(void);
void ipahal_pkt_status_parse(const void *unparsed_status,
	struct ipahal_pkt_status *status);

/*
 * ipahal_pkt_status_parse_thin() - Parse some of the packet status fields
 * for specific usage in the LAN rx data path where parsing needs to be done
 * but only for specific fields.
 * @unparsed_status: Pointer to H/W format of the packet status as read from HW
 * @status: Pointer to pre-allocated buffer where the parsed info will be
 * stored
 */
void ipahal_pkt_status_parse_thin(const void *unparsed_status,
	struct ipahal_pkt_status_thin *status);

/*
 * ipahal_pkt_status_exception_str() - returns string represents exception type
 * @exception: [in] The exception type