Loading drivers/platform/msm/ipa/ipa_v3/ipa.c +0 −6 Original line number Diff line number Diff line Loading @@ -4033,12 +4033,6 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, IPADBG("IPA Driver initialization started\n"); /* * since structure alignment is implementation dependent, add test to * avoid different and incompatible data layouts */ BUILD_BUG_ON(sizeof(struct ipa3_hw_pkt_status) != IPA_PKT_STATUS_SIZE); ipa3_ctx = kzalloc(sizeof(*ipa3_ctx), GFP_KERNEL); if (!ipa3_ctx) { IPAERR(":kzalloc err.\n"); Loading drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +55 −66 Original line number Diff line number Diff line Loading @@ -37,17 +37,6 @@ const char *ipa3_excp_name[] = { __stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_IP), }; const char *ipa3_status_excp_name[] = { __stringify_1(IPA_EXCP_DEAGGR), __stringify_1(IPA_EXCP_REPLICATION), __stringify_1(IPA_EXCP_IP), __stringify_1(IPA_EXCP_IHL), __stringify_1(IPA_EXCP_FRAG_MISS), __stringify_1(IPA_EXCP_SW), __stringify_1(IPA_EXCP_NAT), __stringify_1(IPA_EXCP_NONE), }; const char *ipa3_event_name[] = { __stringify(WLAN_CLIENT_CONNECT), __stringify(WLAN_CLIENT_DISCONNECT), Loading Loading @@ -962,11 +951,11 @@ static ssize_t ipa3_read_stats(struct file *file, char __user *ubuf, ipa3_ctx->stats.flow_disable); cnt += nbytes; for (i = 0; i < MAX_NUM_EXCP; i++) { for (i = 0; i < IPAHAL_PKT_STATUS_EXCEPTION_MAX; i++) { nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, "lan_rx_excp[%u:%20s]=%u\n", i, ipa3_status_excp_name[i], ipahal_pkt_status_exception_str(i), ipa3_ctx->stats.rx_excp_pkts[i]); cnt += nbytes; } Loading Loading @@ -1492,7 +1481,7 @@ static ssize_t ipa3_rm_read_stats(struct file *file, char __user *ubuf, return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); } static void ipa_dump_status(struct ipa3_hw_pkt_status *status) static void ipa_dump_status(struct ipahal_pkt_status *status) { IPA_DUMP_STATUS_FIELD(status_opcode); IPA_DUMP_STATUS_FIELD(exception); Loading @@ -1501,22 +1490,24 @@ static void ipa_dump_status(struct ipa3_hw_pkt_status *status) IPA_DUMP_STATUS_FIELD(endp_src_idx); IPA_DUMP_STATUS_FIELD(endp_dest_idx); IPA_DUMP_STATUS_FIELD(metadata); IPA_DUMP_STATUS_FIELD(filt_local); IPA_DUMP_STATUS_FIELD(filt_hash); IPA_DUMP_STATUS_FIELD(filt_global); IPA_DUMP_STATUS_FIELD(ret_hdr); IPA_DUMP_STATUS_FIELD(filt_rule_id); IPA_DUMP_STATUS_FIELD(route_local); IPA_DUMP_STATUS_FIELD(route_hash); IPA_DUMP_STATUS_FIELD(flt_local); IPA_DUMP_STATUS_FIELD(flt_hash); IPA_DUMP_STATUS_FIELD(flt_global); IPA_DUMP_STATUS_FIELD(flt_ret_hdr); IPA_DUMP_STATUS_FIELD(flt_miss); IPA_DUMP_STATUS_FIELD(flt_rule_id); IPA_DUMP_STATUS_FIELD(rt_local); IPA_DUMP_STATUS_FIELD(rt_hash); IPA_DUMP_STATUS_FIELD(ucp); IPA_DUMP_STATUS_FIELD(route_tbl_idx); IPA_DUMP_STATUS_FIELD(route_rule_id); IPA_DUMP_STATUS_FIELD(rt_tbl_idx); IPA_DUMP_STATUS_FIELD(rt_miss); IPA_DUMP_STATUS_FIELD(rt_rule_id); IPA_DUMP_STATUS_FIELD(nat_hit); IPA_DUMP_STATUS_FIELD(nat_tbl_idx); IPA_DUMP_STATUS_FIELD(nat_entry_idx); IPA_DUMP_STATUS_FIELD(nat_type); pr_err("tag = 0x%llx\n", (u64)status->tag & 0xFFFFFFFFFFFF); pr_err("tag = 0x%llx\n", (u64)status->tag_info & 0xFFFFFFFFFFFF); IPA_DUMP_STATUS_FIELD(seq_num); IPA_DUMP_STATUS_FIELD(time_day_ctr); IPA_DUMP_STATUS_FIELD(time_of_day_ctr); IPA_DUMP_STATUS_FIELD(hdr_local); IPA_DUMP_STATUS_FIELD(hdr_offset); IPA_DUMP_STATUS_FIELD(frag_hit); Loading @@ -1538,8 +1529,6 @@ static ssize_t ipa_status_stats_read(struct file *file, char __user *ubuf, continue; memcpy(stats, ipa3_ctx->ep[i].sys->status_stat, sizeof(*stats)); stats->curr = (stats->curr + IPA_MAX_STATUS_STAT_NUM - 1) % IPA_MAX_STATUS_STAT_NUM; pr_err("Statuses for pipe %d\n", i); for (j = 0; j < IPA_MAX_STATUS_STAT_NUM; j++) { pr_err("curr=%d\n", stats->curr); Loading drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +104 −91 Original line number Diff line number Diff line Loading @@ -2212,7 +2212,8 @@ static int ipa3_lan_rx_pyld_hdlr(struct sk_buff *skb, struct ipa3_sys_context *sys) { int rc = 0; struct ipa3_hw_pkt_status *status; struct ipahal_pkt_status status; u32 pkt_status_sz; struct sk_buff *skb2; int pad_len_byte; int len; Loading Loading @@ -2290,11 +2291,12 @@ static int ipa3_lan_rx_pyld_hdlr(struct sk_buff *skb, } begin: pkt_status_sz = ipahal_pkt_status_get_size(); while (skb->len) { drop_packet = false; IPADBG_LOW("LEN_REM %d\n", skb->len); if (skb->len < IPA_PKT_STATUS_SIZE) { if (skb->len < pkt_status_sz) { WARN_ON(sys->prev_skb != NULL); IPADBG_LOW("status straddles buffer\n"); sys->prev_skb = skb; Loading @@ -2302,43 +2304,47 @@ begin: return rc; } status = (struct ipa3_hw_pkt_status *)skb->data; ipahal_pkt_status_parse(skb->data, &status); IPADBG_LOW("STATUS opcode=%d src=%d dst=%d len=%d\n", status->status_opcode, status->endp_src_idx, status->endp_dest_idx, status->pkt_len); status.status_opcode, status.endp_src_idx, status.endp_dest_idx, status.pkt_len); if (sys->status_stat) { sys->status_stat->status[sys->status_stat->curr] = *status; status; sys->status_stat->curr++; if (sys->status_stat->curr == IPA_MAX_STATUS_STAT_NUM) sys->status_stat->curr = 0; } if ((status->status_opcode & (IPA_HW_STATUS_OPCODE_DROPPED_PACKET | IPA_HW_STATUS_OPCODE_PACKET | IPA_HW_STATUS_OPCODE_SUSPENDED_PACKET | IPA_HW_STATUS_OPCODE_PACKET_2ND_PASS)) == 0) { if ((status.status_opcode != IPAHAL_PKT_STATUS_OPCODE_DROPPED_PACKET) && (status.status_opcode != IPAHAL_PKT_STATUS_OPCODE_PACKET) && (status.status_opcode != IPAHAL_PKT_STATUS_OPCODE_SUSPENDED_PACKET) && (status.status_opcode != IPAHAL_PKT_STATUS_OPCODE_PACKET_2ND_PASS)) { IPAERR("unsupported opcode(%d)\n", status->status_opcode); skb_pull(skb, IPA_PKT_STATUS_SIZE); status.status_opcode); skb_pull(skb, pkt_status_sz); continue; } IPA_STATS_EXCP_CNT(status->exception, IPA_STATS_EXCP_CNT(status.exception, ipa3_ctx->stats.rx_excp_pkts); if (status->endp_dest_idx >= ipa3_ctx->ipa_num_pipes || status->endp_src_idx >= ipa3_ctx->ipa_num_pipes || status->pkt_len > IPA_GENERIC_AGGR_BYTE_LIMIT * 1024) { if (status.endp_dest_idx >= ipa3_ctx->ipa_num_pipes || status.endp_src_idx >= ipa3_ctx->ipa_num_pipes || status.pkt_len > IPA_GENERIC_AGGR_BYTE_LIMIT * 1024) { IPAERR("status fields invalid\n"); WARN_ON(1); BUG(); } if (status->status_mask & IPA_HW_PKT_STATUS_MASK_TAG_VALID) { if (IPAHAL_PKT_STATUS_MASK_FLAG_VAL( IPAHAL_PKT_STATUS_MASK_TAG_VALID_SHFT, &status)) { struct ipa3_tag_completion *comp; IPADBG_LOW("TAG packet arrived\n"); if (status->tag == IPA_COOKIE) { skb_pull(skb, IPA_PKT_STATUS_SIZE); if (status.tag_info == IPA_COOKIE) { skb_pull(skb, pkt_status_sz); if (skb->len < sizeof(comp)) { IPAERR("TAG arrived without packet\n"); return rc; Loading @@ -2351,34 +2357,36 @@ begin: kfree(comp); continue; } else { ptr = tag_to_pointer_wa(status->tag); ptr = tag_to_pointer_wa(status.tag_info); tx_pkt = (struct ipa3_tx_pkt_wrapper *)ptr; IPADBG_LOW("tx_pkt recv = %p\n", tx_pkt); } } if (status->pkt_len == 0) { if (status.pkt_len == 0) { IPADBG_LOW("Skip aggr close status\n"); skb_pull(skb, IPA_PKT_STATUS_SIZE); skb_pull(skb, pkt_status_sz); IPA_STATS_INC_CNT(ipa3_ctx->stats.aggr_close); IPA_STATS_DEC_CNT( ipa3_ctx->stats.rx_excp_pkts[MAX_NUM_EXCP - 1]); IPA_STATS_DEC_CNT(ipa3_ctx->stats.rx_excp_pkts [IPAHAL_PKT_STATUS_EXCEPTION_NONE]); continue; } if (status->endp_dest_idx == (sys->ep - ipa3_ctx->ep)) { if (status.endp_dest_idx == (sys->ep - ipa3_ctx->ep)) { /* RX data */ src_pipe = status->endp_src_idx; src_pipe = status.endp_src_idx; /* * A packet which is received back to the AP after * there was no route match. */ if (!status->exception && status->route_rule_id == IPA_RULE_ID_INVALID) if (status.exception == IPAHAL_PKT_STATUS_EXCEPTION_NONE && status.rt_rule_id == IPA_RULE_ID_INVALID) drop_packet = true; if (skb->len == IPA_PKT_STATUS_SIZE && !status->exception) { if (skb->len == pkt_status_sz && status.exception == IPAHAL_PKT_STATUS_EXCEPTION_NONE) { WARN_ON(sys->prev_skb != NULL); IPADBG_LOW("Ins header in next buffer\n"); sys->prev_skb = skb; Loading @@ -2386,65 +2394,63 @@ begin: return rc; } pad_len_byte = ((status->pkt_len + 3) & ~3) - status->pkt_len; pad_len_byte = ((status.pkt_len + 3) & ~3) - status.pkt_len; len = status->pkt_len + pad_len_byte + len = status.pkt_len + pad_len_byte + IPA_SIZE_DL_CSUM_META_TRAILER; IPADBG_LOW("pad %d pkt_len %d len %d\n", pad_len_byte, status->pkt_len, len); status.pkt_len, len); if (status->exception == IPA_HW_PKT_STATUS_EXCEPTION_DEAGGR) { if (status.exception == IPAHAL_PKT_STATUS_EXCEPTION_DEAGGR) { IPADBG_LOW( "Dropping packet on DeAggr Exception\n"); skb_pull(skb, len + IPA_PKT_STATUS_SIZE); skb_pull(skb, len + pkt_status_sz); continue; } skb2 = ipa3_skb_copy_for_client(skb, status->pkt_len + IPA_PKT_STATUS_SIZE); status.pkt_len + pkt_status_sz); if (likely(skb2)) { if (skb->len < len + IPA_PKT_STATUS_SIZE) { if (skb->len < len + pkt_status_sz) { IPADBG_LOW("SPL skb len %d len %d\n", skb->len, len); sys->prev_skb = skb2; sys->len_rem = len - skb->len + IPA_PKT_STATUS_SIZE; pkt_status_sz; sys->len_pad = pad_len_byte; skb_pull(skb, skb->len); } else { skb_trim(skb2, status->pkt_len + IPA_PKT_STATUS_SIZE); skb_trim(skb2, status.pkt_len + pkt_status_sz); IPADBG_LOW("rx avail for %d\n", status->endp_dest_idx); status.endp_dest_idx); if (drop_packet) dev_kfree_skb_any(skb2); else { skb2->truesize = skb2->len + sizeof(struct sk_buff) + (ALIGN(len + IPA_PKT_STATUS_SIZE, 32) * pkt_status_sz, 32) * unused / used_align); sys->ep->client_notify( sys->ep->priv, IPA_RECEIVE, (unsigned long)(skb2)); } skb_pull(skb, len + IPA_PKT_STATUS_SIZE); skb_pull(skb, len + pkt_status_sz); } } else { IPAERR("fail to alloc skb\n"); if (skb->len < len) { sys->prev_skb = NULL; sys->len_rem = len - skb->len + IPA_PKT_STATUS_SIZE; pkt_status_sz; sys->len_pad = pad_len_byte; skb_pull(skb, skb->len); } else { skb_pull(skb, len + IPA_PKT_STATUS_SIZE); skb_pull(skb, len + pkt_status_sz); } } /* TX comp */ Loading @@ -2452,13 +2458,13 @@ begin: IPADBG_LOW("tx comp imp for %d\n", src_pipe); } else { /* TX comp */ ipa3_wq_write_done_status(status->endp_src_idx, tx_pkt); ipa3_wq_write_done_status(status.endp_src_idx, tx_pkt); IPADBG_LOW("tx comp exp for %d\n", status->endp_src_idx); skb_pull(skb, IPA_PKT_STATUS_SIZE); status.endp_src_idx); skb_pull(skb, pkt_status_sz); IPA_STATS_INC_CNT(ipa3_ctx->stats.stat_compl); IPA_STATS_DEC_CNT( ipa3_ctx->stats.rx_excp_pkts[MAX_NUM_EXCP - 1]); IPA_STATS_DEC_CNT(ipa3_ctx->stats.rx_excp_pkts [IPAHAL_PKT_STATUS_EXCEPTION_NONE]); } }; Loading Loading @@ -2497,7 +2503,7 @@ static void ipa3_wan_rx_handle_splt_pyld(struct sk_buff *skb, if (likely(skb2)) { IPADBG_LOW( "removing Status element from skb and sending to WAN client"); skb_pull(skb2, IPA_PKT_STATUS_SIZE); skb_pull(skb2, ipahal_pkt_status_get_size()); skb2->truesize = skb2->len + sizeof(struct sk_buff); sys->ep->client_notify(sys->ep->priv, Loading @@ -2523,7 +2529,9 @@ static int ipa3_wan_rx_pyld_hdlr(struct sk_buff *skb, struct ipa3_sys_context *sys) { int rc = 0; struct ipa3_hw_pkt_status *status; struct ipahal_pkt_status status; unsigned char *skb_data; u32 pkt_status_sz; struct sk_buff *skb2; u16 pkt_len_with_pad; u32 qmap_hdr; Loading @@ -2546,63 +2554,69 @@ static int ipa3_wan_rx_pyld_hdlr(struct sk_buff *skb, if (sys->len_rem) ipa3_wan_rx_handle_splt_pyld(skb, sys); pkt_status_sz = ipahal_pkt_status_get_size(); while (skb->len) { IPADBG_LOW("LEN_REM %d\n", skb->len); if (skb->len < IPA_PKT_STATUS_SIZE) { if (skb->len < pkt_status_sz) { IPAERR("status straddles buffer\n"); WARN_ON(1); goto bail; } status = (struct ipa3_hw_pkt_status *)skb->data; ipahal_pkt_status_parse(skb->data, &status); skb_data = skb->data; IPADBG_LOW("STATUS opcode=%d src=%d dst=%d len=%d\n", status->status_opcode, status->endp_src_idx, status->endp_dest_idx, status->pkt_len); status.status_opcode, status.endp_src_idx, status.endp_dest_idx, status.pkt_len); if (sys->status_stat) { sys->status_stat->status[sys->status_stat->curr] = *status; status; sys->status_stat->curr++; if (sys->status_stat->curr == IPA_MAX_STATUS_STAT_NUM) sys->status_stat->curr = 0; } if ((status->status_opcode & (IPA_HW_STATUS_OPCODE_DROPPED_PACKET | IPA_HW_STATUS_OPCODE_PACKET | IPA_HW_STATUS_OPCODE_PACKET_2ND_PASS)) == 0) { IPAERR("unsupported opcode\n"); skb_pull(skb, IPA_PKT_STATUS_SIZE); if ((status.status_opcode != IPAHAL_PKT_STATUS_OPCODE_DROPPED_PACKET) && (status.status_opcode != IPAHAL_PKT_STATUS_OPCODE_PACKET) && (status.status_opcode != IPAHAL_PKT_STATUS_OPCODE_PACKET_2ND_PASS)) { IPAERR("unsupported opcode(%d)\n", status.status_opcode); skb_pull(skb, pkt_status_sz); continue; } IPA_STATS_INC_CNT(ipa3_ctx->stats.rx_pkts); if (status->endp_dest_idx >= ipa3_ctx->ipa_num_pipes || status->endp_src_idx >= ipa3_ctx->ipa_num_pipes || status->pkt_len > IPA_GENERIC_AGGR_BYTE_LIMIT * 1024) { if (status.endp_dest_idx >= ipa3_ctx->ipa_num_pipes || status.endp_src_idx >= ipa3_ctx->ipa_num_pipes || status.pkt_len > IPA_GENERIC_AGGR_BYTE_LIMIT * 1024) { IPAERR("status fields invalid\n"); WARN_ON(1); goto bail; } if (status->pkt_len == 0) { if (status.pkt_len == 0) { IPADBG_LOW("Skip aggr close status\n"); skb_pull(skb, IPA_PKT_STATUS_SIZE); skb_pull(skb, pkt_status_sz); IPA_STATS_DEC_CNT(ipa3_ctx->stats.rx_pkts); IPA_STATS_INC_CNT(ipa3_ctx->stats.wan_aggr_close); continue; } ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_CONS); if (status->endp_dest_idx != ep_idx) { if (status.endp_dest_idx != ep_idx) { IPAERR("expected endp_dest_idx %d received %d\n", ep_idx, status->endp_dest_idx); ep_idx, status.endp_dest_idx); WARN_ON(1); goto bail; } /* RX data */ if (skb->len == IPA_PKT_STATUS_SIZE) { if (skb->len == pkt_status_sz) { IPAERR("Ins header in next buffer\n"); WARN_ON(1); goto bail; } qmap_hdr = *(u32 *)(status+1); qmap_hdr = *(u32 *)(skb_data + pkt_status_sz); /* * Take the pkt_len_with_pad from the last 2 bytes of the QMAP * header Loading @@ -2612,13 +2626,12 @@ static int ipa3_wan_rx_pyld_hdlr(struct sk_buff *skb, pkt_len_with_pad = ntohs((qmap_hdr>>16) & 0xffff); IPADBG_LOW("pkt_len with pad %d\n", pkt_len_with_pad); /*get the CHECKSUM_PROCESS bit*/ checksum_trailer_exists = status->status_mask & IPA_HW_PKT_STATUS_MASK_CKSUM_PROCESS; checksum_trailer_exists = IPAHAL_PKT_STATUS_MASK_FLAG_VAL( IPAHAL_PKT_STATUS_MASK_CKSUM_PROCESS_SHFT, &status); IPADBG_LOW("checksum_trailer_exists %d\n", checksum_trailer_exists); frame_len = IPA_PKT_STATUS_SIZE + IPA_QMAP_HEADER_LENGTH + frame_len = pkt_status_sz + IPA_QMAP_HEADER_LENGTH + pkt_len_with_pad; if (checksum_trailer_exists) frame_len += IPA_DL_CHECKSUM_LENGTH; Loading @@ -2639,10 +2652,10 @@ static int ipa3_wan_rx_pyld_hdlr(struct sk_buff *skb, } else { skb_trim(skb2, frame_len); IPADBG_LOW("rx avail for %d\n", status->endp_dest_idx); status.endp_dest_idx); IPADBG_LOW( "removing Status element from skb and sending to WAN client"); skb_pull(skb2, IPA_PKT_STATUS_SIZE); skb_pull(skb2, pkt_status_sz); skb2->truesize = skb2->len + sizeof(struct sk_buff) + (ALIGN(frame_len, 32) * Loading Loading @@ -2680,14 +2693,14 @@ 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 ipa3_hw_pkt_status *status; struct ipahal_pkt_status status; struct ipa3_ep_context *ep; unsigned int src_pipe; u32 metadata; status = (struct ipa3_hw_pkt_status *)rx_skb->data; src_pipe = status->endp_src_idx; metadata = status->metadata; ipahal_pkt_status_parse(rx_skb->data, &status); src_pipe = status.endp_src_idx; metadata = status.metadata; ep = &ipa3_ctx->ep[src_pipe]; if (unlikely(src_pipe >= ipa3_ctx->ipa_num_pipes || !ep->valid || Loading @@ -2697,11 +2710,11 @@ void ipa3_lan_rx_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data) dev_kfree_skb_any(rx_skb); return; } if (!status->exception) skb_pull(rx_skb, IPA_PKT_STATUS_SIZE + if (status.exception == IPAHAL_PKT_STATUS_EXCEPTION_NONE) skb_pull(rx_skb, ipahal_pkt_status_get_size() + IPA_LAN_RX_HEADER_LENGTH); else skb_pull(rx_skb, IPA_PKT_STATUS_SIZE); skb_pull(rx_skb, ipahal_pkt_status_get_size()); /* Metadata Info ------------------------------------------ Loading drivers/platform/msm/ipa/ipa_v3/ipa_hw_defs.h +0 −80 Original line number Diff line number Diff line Loading @@ -152,84 +152,4 @@ struct ipa3_a5_mux_hdr { u32 metadata; }; /*! @brief Struct for the IPAv3.0 UL packet status header */ struct ipa3_hw_pkt_status { u64 status_opcode:8; u64 exception:8; u64 status_mask:16; u64 pkt_len:16; u64 endp_src_idx:5; u64 reserved_1:3; u64 endp_dest_idx:5; u64 reserved_2:3; u64 metadata:32; u64 filt_local:1; u64 filt_hash:1; u64 filt_global:1; u64 ret_hdr:1; u64 filt_rule_id:10; u64 route_local:1; u64 route_hash:1; u64 ucp:1; u64 route_tbl_idx:5; u64 route_rule_id:10; u64 nat_hit:1; u64 nat_tbl_idx:13; u64 nat_type:2; u64 tag:48; u64 seq_num:8; u64 time_day_ctr:24; u64 hdr_local:1; u64 hdr_offset:10; u64 frag_hit:1; u64 frag_rule:4; u64 reserved_4:16; }; #define IPA_PKT_STATUS_SIZE 32 /*! @brief Status header opcodes */ enum ipa3_hw_status_opcode { IPA_HW_STATUS_OPCODE_PACKET = 0x1, IPA_HW_STATUS_OPCODE_NEW_FRAG_RULE = 0x2, IPA_HW_STATUS_OPCODE_DROPPED_PACKET = 0x4, IPA_HW_STATUS_OPCODE_SUSPENDED_PACKET = 0x8, IPA_HW_STATUS_OPCODE_LOG = 0x10, IPA_HW_STATUS_OPCODE_DCMP = 0x20, IPA_HW_STATUS_OPCODE_PACKET_2ND_PASS = 0x40, }; /*! @brief Possible Masks received in status */ enum ipa3_hw_pkt_status_mask { IPA_HW_PKT_STATUS_MASK_FRAG_PROCESS = 0x1, IPA_HW_PKT_STATUS_MASK_FILT_PROCESS = 0x2, IPA_HW_PKT_STATUS_MASK_NAT_PROCESS = 0x4, IPA_HW_PKT_STATUS_MASK_ROUTE_PROCESS = 0x8, IPA_HW_PKT_STATUS_MASK_TAG_VALID = 0x10, IPA_HW_PKT_STATUS_MASK_FRAGMENT = 0x20, IPA_HW_PKT_STATUS_MASK_FIRST_FRAGMENT = 0x40, IPA_HW_PKT_STATUS_MASK_V4 = 0x80, IPA_HW_PKT_STATUS_MASK_CKSUM_PROCESS = 0x100, IPA_HW_PKT_STATUS_MASK_AGGR_PROCESS = 0x200, IPA_HW_PKT_STATUS_MASK_DEST_EOT = 0x400, IPA_HW_PKT_STATUS_MASK_DEAGGR_PROCESS = 0x800, IPA_HW_PKT_STATUS_MASK_DEAGG_FIRST = 0x1000, IPA_HW_PKT_STATUS_MASK_SRC_EOT = 0x2000 }; /*! @brief Possible Exceptions received in status */ enum ipa3_hw_pkt_status_exception { IPA_HW_PKT_STATUS_EXCEPTION_NONE = 0x0, IPA_HW_PKT_STATUS_EXCEPTION_DEAGGR = 0x1, IPA_HW_PKT_STATUS_EXCEPTION_IPTYPE = 0x4, IPA_HW_PKT_STATUS_EXCEPTION_PACKET_LENGTH = 0x8, IPA_HW_PKT_STATUS_EXCEPTION_PACKET_THRESHOLD = 0x9, IPA_HW_PKT_STATUS_EXCEPTION_FRAG_RULE_MISS = 0x10, IPA_HW_PKT_STATUS_EXCEPTION_SW_FILT = 0x20, IPA_HW_PKT_STATUS_EXCEPTION_NAT = 0x40, IPA_HW_PKT_STATUS_EXCEPTION_ACTUAL_MAX, IPA_HW_PKT_STATUS_EXCEPTION_MAX = 0xFF }; #endif /* _IPA_HW_DEFS_H */ drivers/platform/msm/ipa/ipa_v3/ipa_i.h +9 −13 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include "ipa_qmi_service.h" #include "../ipa_api.h" #include "ipahal/ipahal_reg.h" #include "ipahal/ipahal.h" #define DRV_NAME "ipa" #define NAT_DEV_NAME "ipaNatTable" Loading Loading @@ -90,25 +91,20 @@ #define WLAN3_CONS_RX_EP 17 #define WLAN4_CONS_RX_EP 18 #define MAX_NUM_EXCP 8 #define IPA_STATS #ifdef IPA_STATS #define IPA_STATS_INC_CNT(val) (++val) #define IPA_STATS_DEC_CNT(val) (--val) #define IPA_STATS_EXCP_CNT(flags, base) do { \ int i; \ for (i = 0; i < MAX_NUM_EXCP; i++) \ if (flags & BIT(i)) \ ++base[i]; \ if (flags == 0) \ ++base[MAX_NUM_EXCP - 1]; \ #define IPA_STATS_EXCP_CNT(__excp, __base) do { \ if (__excp < 0 || __excp >= IPAHAL_PKT_STATUS_EXCEPTION_MAX) \ break; \ ++__base[__excp]; \ } while (0) #else #define IPA_STATS_INC_CNT(x) do { } while (0) #define IPA_STATS_DEC_CNT(x) #define IPA_STATS_EXCP_CNT(flags, base) do { } while (0) #define IPA_STATS_EXCP_CNT(__excp, __base) do { } while (0) #endif #define IPA_TOS_EQ BIT(0) Loading Loading @@ -665,7 +661,7 @@ struct ipa_gsi_ep_mem_info { }; struct ipa3_status_stats { struct ipa3_hw_pkt_status status[IPA_MAX_STATUS_STAT_NUM]; struct ipahal_pkt_status status[IPA_MAX_STATUS_STAT_NUM]; int curr; }; Loading Loading @@ -1008,7 +1004,7 @@ struct ipa3_stats { u32 tx_sw_pkts; u32 tx_hw_pkts; u32 rx_pkts; u32 rx_excp_pkts[MAX_NUM_EXCP]; u32 rx_excp_pkts[IPAHAL_PKT_STATUS_EXCEPTION_MAX]; u32 rx_repl_repost; u32 tx_pkts_compl; u32 rx_q_len; Loading Loading
drivers/platform/msm/ipa/ipa_v3/ipa.c +0 −6 Original line number Diff line number Diff line Loading @@ -4033,12 +4033,6 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, IPADBG("IPA Driver initialization started\n"); /* * since structure alignment is implementation dependent, add test to * avoid different and incompatible data layouts */ BUILD_BUG_ON(sizeof(struct ipa3_hw_pkt_status) != IPA_PKT_STATUS_SIZE); ipa3_ctx = kzalloc(sizeof(*ipa3_ctx), GFP_KERNEL); if (!ipa3_ctx) { IPAERR(":kzalloc err.\n"); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +55 −66 Original line number Diff line number Diff line Loading @@ -37,17 +37,6 @@ const char *ipa3_excp_name[] = { __stringify_1(IPA_A5_MUX_HDR_EXCP_FLAG_IP), }; const char *ipa3_status_excp_name[] = { __stringify_1(IPA_EXCP_DEAGGR), __stringify_1(IPA_EXCP_REPLICATION), __stringify_1(IPA_EXCP_IP), __stringify_1(IPA_EXCP_IHL), __stringify_1(IPA_EXCP_FRAG_MISS), __stringify_1(IPA_EXCP_SW), __stringify_1(IPA_EXCP_NAT), __stringify_1(IPA_EXCP_NONE), }; const char *ipa3_event_name[] = { __stringify(WLAN_CLIENT_CONNECT), __stringify(WLAN_CLIENT_DISCONNECT), Loading Loading @@ -962,11 +951,11 @@ static ssize_t ipa3_read_stats(struct file *file, char __user *ubuf, ipa3_ctx->stats.flow_disable); cnt += nbytes; for (i = 0; i < MAX_NUM_EXCP; i++) { for (i = 0; i < IPAHAL_PKT_STATUS_EXCEPTION_MAX; i++) { nbytes = scnprintf(dbg_buff + cnt, IPA_MAX_MSG_LEN - cnt, "lan_rx_excp[%u:%20s]=%u\n", i, ipa3_status_excp_name[i], ipahal_pkt_status_exception_str(i), ipa3_ctx->stats.rx_excp_pkts[i]); cnt += nbytes; } Loading Loading @@ -1492,7 +1481,7 @@ static ssize_t ipa3_rm_read_stats(struct file *file, char __user *ubuf, return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); } static void ipa_dump_status(struct ipa3_hw_pkt_status *status) static void ipa_dump_status(struct ipahal_pkt_status *status) { IPA_DUMP_STATUS_FIELD(status_opcode); IPA_DUMP_STATUS_FIELD(exception); Loading @@ -1501,22 +1490,24 @@ static void ipa_dump_status(struct ipa3_hw_pkt_status *status) IPA_DUMP_STATUS_FIELD(endp_src_idx); IPA_DUMP_STATUS_FIELD(endp_dest_idx); IPA_DUMP_STATUS_FIELD(metadata); IPA_DUMP_STATUS_FIELD(filt_local); IPA_DUMP_STATUS_FIELD(filt_hash); IPA_DUMP_STATUS_FIELD(filt_global); IPA_DUMP_STATUS_FIELD(ret_hdr); IPA_DUMP_STATUS_FIELD(filt_rule_id); IPA_DUMP_STATUS_FIELD(route_local); IPA_DUMP_STATUS_FIELD(route_hash); IPA_DUMP_STATUS_FIELD(flt_local); IPA_DUMP_STATUS_FIELD(flt_hash); IPA_DUMP_STATUS_FIELD(flt_global); IPA_DUMP_STATUS_FIELD(flt_ret_hdr); IPA_DUMP_STATUS_FIELD(flt_miss); IPA_DUMP_STATUS_FIELD(flt_rule_id); IPA_DUMP_STATUS_FIELD(rt_local); IPA_DUMP_STATUS_FIELD(rt_hash); IPA_DUMP_STATUS_FIELD(ucp); IPA_DUMP_STATUS_FIELD(route_tbl_idx); IPA_DUMP_STATUS_FIELD(route_rule_id); IPA_DUMP_STATUS_FIELD(rt_tbl_idx); IPA_DUMP_STATUS_FIELD(rt_miss); IPA_DUMP_STATUS_FIELD(rt_rule_id); IPA_DUMP_STATUS_FIELD(nat_hit); IPA_DUMP_STATUS_FIELD(nat_tbl_idx); IPA_DUMP_STATUS_FIELD(nat_entry_idx); IPA_DUMP_STATUS_FIELD(nat_type); pr_err("tag = 0x%llx\n", (u64)status->tag & 0xFFFFFFFFFFFF); pr_err("tag = 0x%llx\n", (u64)status->tag_info & 0xFFFFFFFFFFFF); IPA_DUMP_STATUS_FIELD(seq_num); IPA_DUMP_STATUS_FIELD(time_day_ctr); IPA_DUMP_STATUS_FIELD(time_of_day_ctr); IPA_DUMP_STATUS_FIELD(hdr_local); IPA_DUMP_STATUS_FIELD(hdr_offset); IPA_DUMP_STATUS_FIELD(frag_hit); Loading @@ -1538,8 +1529,6 @@ static ssize_t ipa_status_stats_read(struct file *file, char __user *ubuf, continue; memcpy(stats, ipa3_ctx->ep[i].sys->status_stat, sizeof(*stats)); stats->curr = (stats->curr + IPA_MAX_STATUS_STAT_NUM - 1) % IPA_MAX_STATUS_STAT_NUM; pr_err("Statuses for pipe %d\n", i); for (j = 0; j < IPA_MAX_STATUS_STAT_NUM; j++) { pr_err("curr=%d\n", stats->curr); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +104 −91 Original line number Diff line number Diff line Loading @@ -2212,7 +2212,8 @@ static int ipa3_lan_rx_pyld_hdlr(struct sk_buff *skb, struct ipa3_sys_context *sys) { int rc = 0; struct ipa3_hw_pkt_status *status; struct ipahal_pkt_status status; u32 pkt_status_sz; struct sk_buff *skb2; int pad_len_byte; int len; Loading Loading @@ -2290,11 +2291,12 @@ static int ipa3_lan_rx_pyld_hdlr(struct sk_buff *skb, } begin: pkt_status_sz = ipahal_pkt_status_get_size(); while (skb->len) { drop_packet = false; IPADBG_LOW("LEN_REM %d\n", skb->len); if (skb->len < IPA_PKT_STATUS_SIZE) { if (skb->len < pkt_status_sz) { WARN_ON(sys->prev_skb != NULL); IPADBG_LOW("status straddles buffer\n"); sys->prev_skb = skb; Loading @@ -2302,43 +2304,47 @@ begin: return rc; } status = (struct ipa3_hw_pkt_status *)skb->data; ipahal_pkt_status_parse(skb->data, &status); IPADBG_LOW("STATUS opcode=%d src=%d dst=%d len=%d\n", status->status_opcode, status->endp_src_idx, status->endp_dest_idx, status->pkt_len); status.status_opcode, status.endp_src_idx, status.endp_dest_idx, status.pkt_len); if (sys->status_stat) { sys->status_stat->status[sys->status_stat->curr] = *status; status; sys->status_stat->curr++; if (sys->status_stat->curr == IPA_MAX_STATUS_STAT_NUM) sys->status_stat->curr = 0; } if ((status->status_opcode & (IPA_HW_STATUS_OPCODE_DROPPED_PACKET | IPA_HW_STATUS_OPCODE_PACKET | IPA_HW_STATUS_OPCODE_SUSPENDED_PACKET | IPA_HW_STATUS_OPCODE_PACKET_2ND_PASS)) == 0) { if ((status.status_opcode != IPAHAL_PKT_STATUS_OPCODE_DROPPED_PACKET) && (status.status_opcode != IPAHAL_PKT_STATUS_OPCODE_PACKET) && (status.status_opcode != IPAHAL_PKT_STATUS_OPCODE_SUSPENDED_PACKET) && (status.status_opcode != IPAHAL_PKT_STATUS_OPCODE_PACKET_2ND_PASS)) { IPAERR("unsupported opcode(%d)\n", status->status_opcode); skb_pull(skb, IPA_PKT_STATUS_SIZE); status.status_opcode); skb_pull(skb, pkt_status_sz); continue; } IPA_STATS_EXCP_CNT(status->exception, IPA_STATS_EXCP_CNT(status.exception, ipa3_ctx->stats.rx_excp_pkts); if (status->endp_dest_idx >= ipa3_ctx->ipa_num_pipes || status->endp_src_idx >= ipa3_ctx->ipa_num_pipes || status->pkt_len > IPA_GENERIC_AGGR_BYTE_LIMIT * 1024) { if (status.endp_dest_idx >= ipa3_ctx->ipa_num_pipes || status.endp_src_idx >= ipa3_ctx->ipa_num_pipes || status.pkt_len > IPA_GENERIC_AGGR_BYTE_LIMIT * 1024) { IPAERR("status fields invalid\n"); WARN_ON(1); BUG(); } if (status->status_mask & IPA_HW_PKT_STATUS_MASK_TAG_VALID) { if (IPAHAL_PKT_STATUS_MASK_FLAG_VAL( IPAHAL_PKT_STATUS_MASK_TAG_VALID_SHFT, &status)) { struct ipa3_tag_completion *comp; IPADBG_LOW("TAG packet arrived\n"); if (status->tag == IPA_COOKIE) { skb_pull(skb, IPA_PKT_STATUS_SIZE); if (status.tag_info == IPA_COOKIE) { skb_pull(skb, pkt_status_sz); if (skb->len < sizeof(comp)) { IPAERR("TAG arrived without packet\n"); return rc; Loading @@ -2351,34 +2357,36 @@ begin: kfree(comp); continue; } else { ptr = tag_to_pointer_wa(status->tag); ptr = tag_to_pointer_wa(status.tag_info); tx_pkt = (struct ipa3_tx_pkt_wrapper *)ptr; IPADBG_LOW("tx_pkt recv = %p\n", tx_pkt); } } if (status->pkt_len == 0) { if (status.pkt_len == 0) { IPADBG_LOW("Skip aggr close status\n"); skb_pull(skb, IPA_PKT_STATUS_SIZE); skb_pull(skb, pkt_status_sz); IPA_STATS_INC_CNT(ipa3_ctx->stats.aggr_close); IPA_STATS_DEC_CNT( ipa3_ctx->stats.rx_excp_pkts[MAX_NUM_EXCP - 1]); IPA_STATS_DEC_CNT(ipa3_ctx->stats.rx_excp_pkts [IPAHAL_PKT_STATUS_EXCEPTION_NONE]); continue; } if (status->endp_dest_idx == (sys->ep - ipa3_ctx->ep)) { if (status.endp_dest_idx == (sys->ep - ipa3_ctx->ep)) { /* RX data */ src_pipe = status->endp_src_idx; src_pipe = status.endp_src_idx; /* * A packet which is received back to the AP after * there was no route match. */ if (!status->exception && status->route_rule_id == IPA_RULE_ID_INVALID) if (status.exception == IPAHAL_PKT_STATUS_EXCEPTION_NONE && status.rt_rule_id == IPA_RULE_ID_INVALID) drop_packet = true; if (skb->len == IPA_PKT_STATUS_SIZE && !status->exception) { if (skb->len == pkt_status_sz && status.exception == IPAHAL_PKT_STATUS_EXCEPTION_NONE) { WARN_ON(sys->prev_skb != NULL); IPADBG_LOW("Ins header in next buffer\n"); sys->prev_skb = skb; Loading @@ -2386,65 +2394,63 @@ begin: return rc; } pad_len_byte = ((status->pkt_len + 3) & ~3) - status->pkt_len; pad_len_byte = ((status.pkt_len + 3) & ~3) - status.pkt_len; len = status->pkt_len + pad_len_byte + len = status.pkt_len + pad_len_byte + IPA_SIZE_DL_CSUM_META_TRAILER; IPADBG_LOW("pad %d pkt_len %d len %d\n", pad_len_byte, status->pkt_len, len); status.pkt_len, len); if (status->exception == IPA_HW_PKT_STATUS_EXCEPTION_DEAGGR) { if (status.exception == IPAHAL_PKT_STATUS_EXCEPTION_DEAGGR) { IPADBG_LOW( "Dropping packet on DeAggr Exception\n"); skb_pull(skb, len + IPA_PKT_STATUS_SIZE); skb_pull(skb, len + pkt_status_sz); continue; } skb2 = ipa3_skb_copy_for_client(skb, status->pkt_len + IPA_PKT_STATUS_SIZE); status.pkt_len + pkt_status_sz); if (likely(skb2)) { if (skb->len < len + IPA_PKT_STATUS_SIZE) { if (skb->len < len + pkt_status_sz) { IPADBG_LOW("SPL skb len %d len %d\n", skb->len, len); sys->prev_skb = skb2; sys->len_rem = len - skb->len + IPA_PKT_STATUS_SIZE; pkt_status_sz; sys->len_pad = pad_len_byte; skb_pull(skb, skb->len); } else { skb_trim(skb2, status->pkt_len + IPA_PKT_STATUS_SIZE); skb_trim(skb2, status.pkt_len + pkt_status_sz); IPADBG_LOW("rx avail for %d\n", status->endp_dest_idx); status.endp_dest_idx); if (drop_packet) dev_kfree_skb_any(skb2); else { skb2->truesize = skb2->len + sizeof(struct sk_buff) + (ALIGN(len + IPA_PKT_STATUS_SIZE, 32) * pkt_status_sz, 32) * unused / used_align); sys->ep->client_notify( sys->ep->priv, IPA_RECEIVE, (unsigned long)(skb2)); } skb_pull(skb, len + IPA_PKT_STATUS_SIZE); skb_pull(skb, len + pkt_status_sz); } } else { IPAERR("fail to alloc skb\n"); if (skb->len < len) { sys->prev_skb = NULL; sys->len_rem = len - skb->len + IPA_PKT_STATUS_SIZE; pkt_status_sz; sys->len_pad = pad_len_byte; skb_pull(skb, skb->len); } else { skb_pull(skb, len + IPA_PKT_STATUS_SIZE); skb_pull(skb, len + pkt_status_sz); } } /* TX comp */ Loading @@ -2452,13 +2458,13 @@ begin: IPADBG_LOW("tx comp imp for %d\n", src_pipe); } else { /* TX comp */ ipa3_wq_write_done_status(status->endp_src_idx, tx_pkt); ipa3_wq_write_done_status(status.endp_src_idx, tx_pkt); IPADBG_LOW("tx comp exp for %d\n", status->endp_src_idx); skb_pull(skb, IPA_PKT_STATUS_SIZE); status.endp_src_idx); skb_pull(skb, pkt_status_sz); IPA_STATS_INC_CNT(ipa3_ctx->stats.stat_compl); IPA_STATS_DEC_CNT( ipa3_ctx->stats.rx_excp_pkts[MAX_NUM_EXCP - 1]); IPA_STATS_DEC_CNT(ipa3_ctx->stats.rx_excp_pkts [IPAHAL_PKT_STATUS_EXCEPTION_NONE]); } }; Loading Loading @@ -2497,7 +2503,7 @@ static void ipa3_wan_rx_handle_splt_pyld(struct sk_buff *skb, if (likely(skb2)) { IPADBG_LOW( "removing Status element from skb and sending to WAN client"); skb_pull(skb2, IPA_PKT_STATUS_SIZE); skb_pull(skb2, ipahal_pkt_status_get_size()); skb2->truesize = skb2->len + sizeof(struct sk_buff); sys->ep->client_notify(sys->ep->priv, Loading @@ -2523,7 +2529,9 @@ static int ipa3_wan_rx_pyld_hdlr(struct sk_buff *skb, struct ipa3_sys_context *sys) { int rc = 0; struct ipa3_hw_pkt_status *status; struct ipahal_pkt_status status; unsigned char *skb_data; u32 pkt_status_sz; struct sk_buff *skb2; u16 pkt_len_with_pad; u32 qmap_hdr; Loading @@ -2546,63 +2554,69 @@ static int ipa3_wan_rx_pyld_hdlr(struct sk_buff *skb, if (sys->len_rem) ipa3_wan_rx_handle_splt_pyld(skb, sys); pkt_status_sz = ipahal_pkt_status_get_size(); while (skb->len) { IPADBG_LOW("LEN_REM %d\n", skb->len); if (skb->len < IPA_PKT_STATUS_SIZE) { if (skb->len < pkt_status_sz) { IPAERR("status straddles buffer\n"); WARN_ON(1); goto bail; } status = (struct ipa3_hw_pkt_status *)skb->data; ipahal_pkt_status_parse(skb->data, &status); skb_data = skb->data; IPADBG_LOW("STATUS opcode=%d src=%d dst=%d len=%d\n", status->status_opcode, status->endp_src_idx, status->endp_dest_idx, status->pkt_len); status.status_opcode, status.endp_src_idx, status.endp_dest_idx, status.pkt_len); if (sys->status_stat) { sys->status_stat->status[sys->status_stat->curr] = *status; status; sys->status_stat->curr++; if (sys->status_stat->curr == IPA_MAX_STATUS_STAT_NUM) sys->status_stat->curr = 0; } if ((status->status_opcode & (IPA_HW_STATUS_OPCODE_DROPPED_PACKET | IPA_HW_STATUS_OPCODE_PACKET | IPA_HW_STATUS_OPCODE_PACKET_2ND_PASS)) == 0) { IPAERR("unsupported opcode\n"); skb_pull(skb, IPA_PKT_STATUS_SIZE); if ((status.status_opcode != IPAHAL_PKT_STATUS_OPCODE_DROPPED_PACKET) && (status.status_opcode != IPAHAL_PKT_STATUS_OPCODE_PACKET) && (status.status_opcode != IPAHAL_PKT_STATUS_OPCODE_PACKET_2ND_PASS)) { IPAERR("unsupported opcode(%d)\n", status.status_opcode); skb_pull(skb, pkt_status_sz); continue; } IPA_STATS_INC_CNT(ipa3_ctx->stats.rx_pkts); if (status->endp_dest_idx >= ipa3_ctx->ipa_num_pipes || status->endp_src_idx >= ipa3_ctx->ipa_num_pipes || status->pkt_len > IPA_GENERIC_AGGR_BYTE_LIMIT * 1024) { if (status.endp_dest_idx >= ipa3_ctx->ipa_num_pipes || status.endp_src_idx >= ipa3_ctx->ipa_num_pipes || status.pkt_len > IPA_GENERIC_AGGR_BYTE_LIMIT * 1024) { IPAERR("status fields invalid\n"); WARN_ON(1); goto bail; } if (status->pkt_len == 0) { if (status.pkt_len == 0) { IPADBG_LOW("Skip aggr close status\n"); skb_pull(skb, IPA_PKT_STATUS_SIZE); skb_pull(skb, pkt_status_sz); IPA_STATS_DEC_CNT(ipa3_ctx->stats.rx_pkts); IPA_STATS_INC_CNT(ipa3_ctx->stats.wan_aggr_close); continue; } ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_CONS); if (status->endp_dest_idx != ep_idx) { if (status.endp_dest_idx != ep_idx) { IPAERR("expected endp_dest_idx %d received %d\n", ep_idx, status->endp_dest_idx); ep_idx, status.endp_dest_idx); WARN_ON(1); goto bail; } /* RX data */ if (skb->len == IPA_PKT_STATUS_SIZE) { if (skb->len == pkt_status_sz) { IPAERR("Ins header in next buffer\n"); WARN_ON(1); goto bail; } qmap_hdr = *(u32 *)(status+1); qmap_hdr = *(u32 *)(skb_data + pkt_status_sz); /* * Take the pkt_len_with_pad from the last 2 bytes of the QMAP * header Loading @@ -2612,13 +2626,12 @@ static int ipa3_wan_rx_pyld_hdlr(struct sk_buff *skb, pkt_len_with_pad = ntohs((qmap_hdr>>16) & 0xffff); IPADBG_LOW("pkt_len with pad %d\n", pkt_len_with_pad); /*get the CHECKSUM_PROCESS bit*/ checksum_trailer_exists = status->status_mask & IPA_HW_PKT_STATUS_MASK_CKSUM_PROCESS; checksum_trailer_exists = IPAHAL_PKT_STATUS_MASK_FLAG_VAL( IPAHAL_PKT_STATUS_MASK_CKSUM_PROCESS_SHFT, &status); IPADBG_LOW("checksum_trailer_exists %d\n", checksum_trailer_exists); frame_len = IPA_PKT_STATUS_SIZE + IPA_QMAP_HEADER_LENGTH + frame_len = pkt_status_sz + IPA_QMAP_HEADER_LENGTH + pkt_len_with_pad; if (checksum_trailer_exists) frame_len += IPA_DL_CHECKSUM_LENGTH; Loading @@ -2639,10 +2652,10 @@ static int ipa3_wan_rx_pyld_hdlr(struct sk_buff *skb, } else { skb_trim(skb2, frame_len); IPADBG_LOW("rx avail for %d\n", status->endp_dest_idx); status.endp_dest_idx); IPADBG_LOW( "removing Status element from skb and sending to WAN client"); skb_pull(skb2, IPA_PKT_STATUS_SIZE); skb_pull(skb2, pkt_status_sz); skb2->truesize = skb2->len + sizeof(struct sk_buff) + (ALIGN(frame_len, 32) * Loading Loading @@ -2680,14 +2693,14 @@ 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 ipa3_hw_pkt_status *status; struct ipahal_pkt_status status; struct ipa3_ep_context *ep; unsigned int src_pipe; u32 metadata; status = (struct ipa3_hw_pkt_status *)rx_skb->data; src_pipe = status->endp_src_idx; metadata = status->metadata; ipahal_pkt_status_parse(rx_skb->data, &status); src_pipe = status.endp_src_idx; metadata = status.metadata; ep = &ipa3_ctx->ep[src_pipe]; if (unlikely(src_pipe >= ipa3_ctx->ipa_num_pipes || !ep->valid || Loading @@ -2697,11 +2710,11 @@ void ipa3_lan_rx_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data) dev_kfree_skb_any(rx_skb); return; } if (!status->exception) skb_pull(rx_skb, IPA_PKT_STATUS_SIZE + if (status.exception == IPAHAL_PKT_STATUS_EXCEPTION_NONE) skb_pull(rx_skb, ipahal_pkt_status_get_size() + IPA_LAN_RX_HEADER_LENGTH); else skb_pull(rx_skb, IPA_PKT_STATUS_SIZE); skb_pull(rx_skb, ipahal_pkt_status_get_size()); /* Metadata Info ------------------------------------------ Loading
drivers/platform/msm/ipa/ipa_v3/ipa_hw_defs.h +0 −80 Original line number Diff line number Diff line Loading @@ -152,84 +152,4 @@ struct ipa3_a5_mux_hdr { u32 metadata; }; /*! @brief Struct for the IPAv3.0 UL packet status header */ struct ipa3_hw_pkt_status { u64 status_opcode:8; u64 exception:8; u64 status_mask:16; u64 pkt_len:16; u64 endp_src_idx:5; u64 reserved_1:3; u64 endp_dest_idx:5; u64 reserved_2:3; u64 metadata:32; u64 filt_local:1; u64 filt_hash:1; u64 filt_global:1; u64 ret_hdr:1; u64 filt_rule_id:10; u64 route_local:1; u64 route_hash:1; u64 ucp:1; u64 route_tbl_idx:5; u64 route_rule_id:10; u64 nat_hit:1; u64 nat_tbl_idx:13; u64 nat_type:2; u64 tag:48; u64 seq_num:8; u64 time_day_ctr:24; u64 hdr_local:1; u64 hdr_offset:10; u64 frag_hit:1; u64 frag_rule:4; u64 reserved_4:16; }; #define IPA_PKT_STATUS_SIZE 32 /*! @brief Status header opcodes */ enum ipa3_hw_status_opcode { IPA_HW_STATUS_OPCODE_PACKET = 0x1, IPA_HW_STATUS_OPCODE_NEW_FRAG_RULE = 0x2, IPA_HW_STATUS_OPCODE_DROPPED_PACKET = 0x4, IPA_HW_STATUS_OPCODE_SUSPENDED_PACKET = 0x8, IPA_HW_STATUS_OPCODE_LOG = 0x10, IPA_HW_STATUS_OPCODE_DCMP = 0x20, IPA_HW_STATUS_OPCODE_PACKET_2ND_PASS = 0x40, }; /*! @brief Possible Masks received in status */ enum ipa3_hw_pkt_status_mask { IPA_HW_PKT_STATUS_MASK_FRAG_PROCESS = 0x1, IPA_HW_PKT_STATUS_MASK_FILT_PROCESS = 0x2, IPA_HW_PKT_STATUS_MASK_NAT_PROCESS = 0x4, IPA_HW_PKT_STATUS_MASK_ROUTE_PROCESS = 0x8, IPA_HW_PKT_STATUS_MASK_TAG_VALID = 0x10, IPA_HW_PKT_STATUS_MASK_FRAGMENT = 0x20, IPA_HW_PKT_STATUS_MASK_FIRST_FRAGMENT = 0x40, IPA_HW_PKT_STATUS_MASK_V4 = 0x80, IPA_HW_PKT_STATUS_MASK_CKSUM_PROCESS = 0x100, IPA_HW_PKT_STATUS_MASK_AGGR_PROCESS = 0x200, IPA_HW_PKT_STATUS_MASK_DEST_EOT = 0x400, IPA_HW_PKT_STATUS_MASK_DEAGGR_PROCESS = 0x800, IPA_HW_PKT_STATUS_MASK_DEAGG_FIRST = 0x1000, IPA_HW_PKT_STATUS_MASK_SRC_EOT = 0x2000 }; /*! @brief Possible Exceptions received in status */ enum ipa3_hw_pkt_status_exception { IPA_HW_PKT_STATUS_EXCEPTION_NONE = 0x0, IPA_HW_PKT_STATUS_EXCEPTION_DEAGGR = 0x1, IPA_HW_PKT_STATUS_EXCEPTION_IPTYPE = 0x4, IPA_HW_PKT_STATUS_EXCEPTION_PACKET_LENGTH = 0x8, IPA_HW_PKT_STATUS_EXCEPTION_PACKET_THRESHOLD = 0x9, IPA_HW_PKT_STATUS_EXCEPTION_FRAG_RULE_MISS = 0x10, IPA_HW_PKT_STATUS_EXCEPTION_SW_FILT = 0x20, IPA_HW_PKT_STATUS_EXCEPTION_NAT = 0x40, IPA_HW_PKT_STATUS_EXCEPTION_ACTUAL_MAX, IPA_HW_PKT_STATUS_EXCEPTION_MAX = 0xFF }; #endif /* _IPA_HW_DEFS_H */
drivers/platform/msm/ipa/ipa_v3/ipa_i.h +9 −13 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include "ipa_qmi_service.h" #include "../ipa_api.h" #include "ipahal/ipahal_reg.h" #include "ipahal/ipahal.h" #define DRV_NAME "ipa" #define NAT_DEV_NAME "ipaNatTable" Loading Loading @@ -90,25 +91,20 @@ #define WLAN3_CONS_RX_EP 17 #define WLAN4_CONS_RX_EP 18 #define MAX_NUM_EXCP 8 #define IPA_STATS #ifdef IPA_STATS #define IPA_STATS_INC_CNT(val) (++val) #define IPA_STATS_DEC_CNT(val) (--val) #define IPA_STATS_EXCP_CNT(flags, base) do { \ int i; \ for (i = 0; i < MAX_NUM_EXCP; i++) \ if (flags & BIT(i)) \ ++base[i]; \ if (flags == 0) \ ++base[MAX_NUM_EXCP - 1]; \ #define IPA_STATS_EXCP_CNT(__excp, __base) do { \ if (__excp < 0 || __excp >= IPAHAL_PKT_STATUS_EXCEPTION_MAX) \ break; \ ++__base[__excp]; \ } while (0) #else #define IPA_STATS_INC_CNT(x) do { } while (0) #define IPA_STATS_DEC_CNT(x) #define IPA_STATS_EXCP_CNT(flags, base) do { } while (0) #define IPA_STATS_EXCP_CNT(__excp, __base) do { } while (0) #endif #define IPA_TOS_EQ BIT(0) Loading Loading @@ -665,7 +661,7 @@ struct ipa_gsi_ep_mem_info { }; struct ipa3_status_stats { struct ipa3_hw_pkt_status status[IPA_MAX_STATUS_STAT_NUM]; struct ipahal_pkt_status status[IPA_MAX_STATUS_STAT_NUM]; int curr; }; Loading Loading @@ -1008,7 +1004,7 @@ struct ipa3_stats { u32 tx_sw_pkts; u32 tx_hw_pkts; u32 rx_pkts; u32 rx_excp_pkts[MAX_NUM_EXCP]; u32 rx_excp_pkts[IPAHAL_PKT_STATUS_EXCEPTION_MAX]; u32 rx_repl_repost; u32 tx_pkts_compl; u32 rx_q_len; Loading