mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
Merge "msm: ipa3: Fix to ignore frag status packet in lan consumer pipe"
This commit is contained in:
commit
3512d1a673
4 changed files with 176 additions and 53 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue