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

This commit is contained in:
qctecmdr 2020-01-08 16:06:59 -08:00 • committed by Gerrit - the friendly Code Review server
commit 3512d1a673
4 changed files with 176 additions and 53 deletions

View file

@ -2804,8 +2804,14 @@ begin:
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);

View file

@ -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,46 +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;
@ -968,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;
@ -984,12 +1026,9 @@ 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);
IPA_PKT_STATUS_SET_MSK(0x4, IPAHAL_PKT_STATUS_MASK_NAT_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));

View file

@ -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;
};
/*

View file

@ -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