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

Commit 35b057b8 authored by Ashok Vuyyuru's avatar Ashok Vuyyuru
Browse files

msm: ipa3: Fix to ignore frag status packet in lan consumer pipe



Since lan payload is handler not handling the frag status packets,
add changes to ignore frag status packet in lan payload handler.

Change-Id: I6f93d29a009c023f0ab3966b2f73f49e82e2b585
Signed-off-by: default avatarAshok Vuyyuru <avuyyuru@codeaurora.org>
parent 83bf913b
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -2809,8 +2809,14 @@ static int ipa3_lan_rx_pyld_hdlr(struct sk_buff *skb,
		case IPAHAL_PKT_STATUS_OPCODE_PACKET:
		case IPAHAL_PKT_STATUS_OPCODE_SUSPENDED_PACKET:
		case IPAHAL_PKT_STATUS_OPCODE_PACKET_2ND_PASS:
		case IPAHAL_PKT_STATUS_OPCODE_NEW_FRAG_RULE:
			break;
		case IPAHAL_PKT_STATUS_OPCODE_NEW_FRAG_RULE:
			IPAERR_RL("Frag packets received on lan consumer\n");
			IPAERR_RL("STATUS opcode=%d src=%d dst=%d src ip=%x\n",
				status.status_opcode, status.endp_src_idx,
				status.endp_dest_idx, status.src_ip_addr);
			skb_pull(skb, pkt_status_sz);
			continue;
		default:
			IPAERR_RL("unsupported opcode(%d)\n",
				status.status_opcode);
+88 −49
Original line number Diff line number Diff line
@@ -861,7 +861,8 @@ struct ipahal_imm_cmd_pyld *ipahal_construct_nop_imm_cmd(

#define IPA_PKT_STATUS_SET_MSK(__hw_bit_msk, __shft) \
	(status->status_mask |= \
		((hw_status->status_mask & (__hw_bit_msk) ? 1 : 0) << (__shft)))
		((hw_status->ipa_pkt.status_mask & (__hw_bit_msk) ? 1 : 0) \
					<< (__shft)))

static enum ipahal_pkt_status_exception pkt_status_parse_exception(
	bool is_ipv6, u64 exception)
@@ -905,47 +906,81 @@ static enum ipahal_pkt_status_exception pkt_status_parse_exception(
	return exception_type;
}

static void __ipa_parse_gen_pkt(struct ipahal_pkt_status *status,
				const void *unparsed_status)
{
	bool is_ipv6;
	union ipa_pkt_status_hw *hw_status =
		(union ipa_pkt_status_hw *)unparsed_status;

	is_ipv6 = (hw_status->ipa_pkt.status_mask & 0x80) ? false : true;
	status->pkt_len = hw_status->ipa_pkt.pkt_len;
	status->endp_src_idx = hw_status->ipa_pkt.endp_src_idx;
	status->endp_dest_idx = hw_status->ipa_pkt.endp_dest_idx;
	status->metadata = hw_status->ipa_pkt.metadata;
	status->flt_local = hw_status->ipa_pkt.flt_local;
	status->flt_hash = hw_status->ipa_pkt.flt_hash;
	status->flt_global = hw_status->ipa_pkt.flt_hash;
	status->flt_ret_hdr = hw_status->ipa_pkt.flt_ret_hdr;
	status->flt_miss = (hw_status->ipa_pkt.rt_rule_id ==
			IPAHAL_PKT_STATUS_FLTRT_RULE_MISS_ID);
	status->flt_rule_id = hw_status->ipa_pkt.flt_rule_id;
	status->rt_local = hw_status->ipa_pkt.rt_local;
	status->rt_hash = hw_status->ipa_pkt.rt_hash;
	status->ucp = hw_status->ipa_pkt.ucp;
	status->rt_tbl_idx = hw_status->ipa_pkt.rt_tbl_idx;
	status->rt_miss = (hw_status->ipa_pkt.rt_rule_id ==
			IPAHAL_PKT_STATUS_FLTRT_RULE_MISS_ID);
	status->rt_rule_id = hw_status->ipa_pkt.rt_rule_id;
	status->nat_hit = hw_status->ipa_pkt.nat_hit;
	status->nat_entry_idx = hw_status->ipa_pkt.nat_entry_idx;
	status->tag_info = hw_status->ipa_pkt.tag_info;
	status->seq_num = hw_status->ipa_pkt.seq_num;
	status->time_of_day_ctr = hw_status->ipa_pkt.time_of_day_ctr;
	status->hdr_local = hw_status->ipa_pkt.hdr_local;
	status->hdr_offset = hw_status->ipa_pkt.hdr_offset;
	status->frag_hit = hw_status->ipa_pkt.frag_hit;
	status->frag_rule = hw_status->ipa_pkt.frag_rule;
	status->nat_type = hw_status->ipa_pkt.nat_type;

	status->exception = pkt_status_parse_exception(is_ipv6,
			hw_status->ipa_pkt.exception);
}

static void __ipa_parse_frag_pkt(struct ipahal_pkt_status *status,
				const void *unparsed_status)
{
	union ipa_pkt_status_hw *hw_status =
		(union ipa_pkt_status_hw *)unparsed_status;

	status->frag_rule_idx = hw_status->frag_pkt.frag_rule_idx;
	status->tbl_idx = hw_status->frag_pkt.tbl_idx;
	status->src_ip_addr = hw_status->frag_pkt.src_ip_addr;
	status->dest_ip_addr = hw_status->frag_pkt.dest_ip_addr;
	status->protocol = hw_status->frag_pkt.protocol;
	status->ip_id = hw_status->frag_pkt.ip_id;
	status->tlated_ip_addr = hw_status->frag_pkt.tlated_ip_addr;
	status->ip_cksum_diff = hw_status->frag_pkt.ip_cksum_diff;
	status->endp_src_idx = hw_status->frag_pkt.endp_src_idx;
	status->endp_dest_idx = hw_status->frag_pkt.endp_dest_idx;
	status->metadata = hw_status->frag_pkt.metadata;
	status->seq_num = hw_status->frag_pkt.seq_num;
	status->hdr_local = hw_status->frag_pkt.hdr_local;
	status->hdr_offset = hw_status->frag_pkt.hdr_offset;
	status->exception = hw_status->frag_pkt.exception;
	status->nat_type = hw_status->frag_pkt.nat_type;
}

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

	struct ipa_pkt_status_hw *hw_status =
		(struct ipa_pkt_status_hw *)unparsed_status;
	union ipa_pkt_status_hw *hw_status =
		(union ipa_pkt_status_hw *)unparsed_status;

	is_ipv6 = (hw_status->status_mask & 0x80) ? false : true;

	status->pkt_len = hw_status->pkt_len;
	status->endp_src_idx = hw_status->endp_src_idx;
	status->endp_dest_idx = hw_status->endp_dest_idx;
	status->metadata = hw_status->metadata;
	status->flt_local = hw_status->flt_local;
	status->flt_hash = hw_status->flt_hash;
	status->flt_global = hw_status->flt_hash;
	status->flt_ret_hdr = hw_status->flt_ret_hdr;
	status->flt_miss = (hw_status->rt_rule_id ==
		IPAHAL_PKT_STATUS_FLTRT_RULE_MISS_ID);
	status->flt_rule_id = hw_status->flt_rule_id;
	status->rt_local = hw_status->rt_local;
	status->rt_hash = hw_status->rt_hash;
	status->ucp = hw_status->ucp;
	status->rt_tbl_idx = hw_status->rt_tbl_idx;
	status->rt_miss = (hw_status->rt_rule_id ==
		IPAHAL_PKT_STATUS_FLTRT_RULE_MISS_ID);
	status->rt_rule_id = hw_status->rt_rule_id;
	status->nat_hit = hw_status->nat_hit;
	status->nat_entry_idx = hw_status->nat_entry_idx;
	status->tag_info = hw_status->tag_info;
	status->seq_num = hw_status->seq_num;
	status->time_of_day_ctr = hw_status->time_of_day_ctr;
	status->hdr_local = hw_status->hdr_local;
	status->hdr_offset = hw_status->hdr_offset;
	status->frag_hit = hw_status->frag_hit;
	status->frag_rule = hw_status->frag_rule;

	switch (hw_status->status_opcode) {
	switch (hw_status->ipa_pkt.status_opcode) {
	case 0x1:
		opcode = IPAHAL_PKT_STATUS_OPCODE_PACKET;
		break;
@@ -969,11 +1004,17 @@ static void ipa_pkt_status_parse(
		break;
	default:
		IPAHAL_ERR_RL("unsupported Status Opcode 0x%x\n",
			hw_status->status_opcode);
			hw_status->ipa_pkt.status_opcode);
	}

	status->status_opcode = opcode;

	switch (hw_status->nat_type) {
	if (status->status_opcode == IPAHAL_PKT_STATUS_OPCODE_NEW_FRAG_RULE)
		__ipa_parse_frag_pkt(status, unparsed_status);
	else
		__ipa_parse_gen_pkt(status, unparsed_status);

	switch (status->nat_type) {
	case 0:
		status->nat_type = IPAHAL_PKT_STATUS_NAT_NONE;
		break;
@@ -985,10 +1026,8 @@ static void ipa_pkt_status_parse(
		break;
	default:
		IPAHAL_ERR_RL("unsupported Status NAT type 0x%x\n",
			hw_status->nat_type);
			status->nat_type);
	}
	status->exception = pkt_status_parse_exception(is_ipv6,
						hw_status->exception);

	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);
@@ -1023,11 +1062,11 @@ static void ipa_pkt_status_parse(
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;
	union ipa_pkt_status_hw *hw_status =
		(union ipa_pkt_status_hw *)unparsed_status;
	bool is_ipv6;

	is_ipv6 = (hw_status->status_mask & 0x80) ? false : true;
	is_ipv6 = (hw_status->ipa_pkt.status_mask & 0x80) ? false : true;
	if (!unparsed_status || !status) {
		IPAHAL_ERR("Input Error: unparsed_status=%pK status=%pK\n",
			unparsed_status, status);
@@ -1035,11 +1074,11 @@ static void ipa_pkt_status_parse_thin(const void *unparsed_status,
	}

	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->metadata = hw_status->ipa_pkt.metadata;
	status->endp_src_idx = hw_status->ipa_pkt.endp_src_idx;
	status->ucp = hw_status->ipa_pkt.ucp;
	status->exception = pkt_status_parse_exception(is_ipv6,
						hw_status->exception);
						hw_status->ipa_pkt.exception);
}

/*
@@ -1102,7 +1141,7 @@ static int ipahal_pkt_status_init(enum ipa_hw_type ipa_hw_type)
	 * add a compile time validty check for it like below (as well as
	 * the new defines and/or the new strucutre in the internal header).
	 */
	BUILD_BUG_ON(sizeof(struct ipa_pkt_status_hw) !=
	BUILD_BUG_ON(sizeof(union ipa_pkt_status_hw) !=
		IPA3_0_PKT_STATUS_SIZE);

	memset(&zero_obj, 0, sizeof(zero_obj));
+17 −0
Original line number Diff line number Diff line
@@ -555,6 +555,14 @@ enum ipahal_pkt_status_nat_type {
 * @rt_tbl_idx: Index of rt tbl that contains the rule on which was a match
 * @seq_num: Per source endp unique packet sequence number
 * @frag_rule: Frag rule index in H/W frag table in case of frag hit
 * @frag_rule_idx: Frag rule index value.
 * @tbl_idx: Table index valid or not.
 * @src_ip_addr: Source packet IP address.
 * @dest_ip_addr: Destination packet IP address.
 * @protocol: Protocal number.
 * @ip_id: IP packet IP ID number.
 * @tlated_ip_addr: IP address.
 * @ip_cksum_diff: IP packet checksum difference.
 */
struct ipahal_pkt_status {
	u64 tag_info;
@@ -586,6 +594,15 @@ struct ipahal_pkt_status {
	u8 rt_tbl_idx;
	u8 seq_num;
	u8 frag_rule;
	u8 frag_rule_idx;
	bool tbl_idx;
	u32 src_ip_addr;
	u32 dest_ip_addr;
	u8 protocol;
	u16 ip_id;
	u32 tlated_ip_addr;
	u16 ip_cksum_diff;

};

/*
+63 −2
Original line number Diff line number Diff line
@@ -566,7 +566,7 @@ struct ipa_imm_cmd_hw_dma_task_32b_addr {
 * @frag_rule: Frag rule index in H/W frag table in case of frag hit
 * @hw_specific: H/W specific reserved value
 */
struct ipa_pkt_status_hw {
struct ipa_gen_pkt_status_hw {
	u64 status_opcode:8;
	u64 exception:8;
	u64 status_mask:16;
@@ -597,7 +597,68 @@ struct ipa_pkt_status_hw {
	u64 frag_hit:1;
	u64 frag_rule:4;
	u64 hw_specific:16;
};
} __packed;

/*
 * struct ipa_frag_pkt_status_hw - IPA status packet payload in H/W format.
 *  This structure describes the frag status packet H/W structure for the
 *   following statuses: IPA_NEW_FRAG_RULE.
 * @status_opcode: The Type of the status (Opcode).
 * @frag_rule_idx: Frag rule index value.
 * @rsvd1: reserved
 * @tbl_idx: Table index valid or not.
 * @endp_src_idx: Source end point index.
 * @exception: (not bitmask) - the first exception that took place.
 *  In case of exception, src endp and pkt len are always valid.
 * @rsvd2: reserved
 * @seq_num: Packet sequence number.
 * @src_ip_addr: Source packet IP address.
 * @dest_ip_addr: Destination packet IP address.
 * @rsvd3: reserved
 * @nat_type: Defines the type of the NAT operation:
 *	00: No NAT
 *	01: Source NAT
 *	10: Destination NAT
 *	11: Reserved
 * @protocol: Protocal number.
 * @ip_id: IP packet IP ID number.
 * @tlated_ip_addr: IP address.
 * @hdr_local: Header table location flag: In header insertion, was the header
 *  taken from the table resides in local memory? (If no, then system mem)
 * @hdr_offset: Offset of used header in the header table
 * @endp_dest_idx: Destination end point index.
 * @ip_cksum_diff: IP packet checksum difference.
 * @metadata: meta data value used by packet
 * @rsvd4: reserved
 */
struct ipa_frag_pkt_status_hw {
	u64 status_opcode:8;
	u64 frag_rule_idx:4;
	u64 reserved_1:3;
	u64 tbl_idx:1;
	u64 endp_src_idx:5;
	u64 exception:1;
	u64 reserved_2:2;
	u64 seq_num:8;
	u64 src_ip_addr:32;
	u64 dest_ip_addr:32;
	u64 reserved_3:6;
	u64 nat_type:2;
	u64 protocol:8;
	u64 ip_id:16;
	u64 tlated_ip_addr:32;
	u64 hdr_local:1;
	u64 hdr_offset:10;
	u64 endp_dest_idx:5;
	u64 ip_cksum_diff:16;
	u64 metadata:32;
	u64 reserved_4:32;
} __packed;

union ipa_pkt_status_hw {
	struct ipa_gen_pkt_status_hw ipa_pkt;
	struct ipa_frag_pkt_status_hw frag_pkt;
} __packed;

/* Size of H/W Packet Status */
#define IPA3_0_PKT_STATUS_SIZE 32