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

Commit 2a7c7833 authored by Ghanim Fodi's avatar Ghanim Fodi
Browse files

msm: ipa3: Move IPA Status Packet parsing to IPAHAL



IPA Status Packet parsing is a logic related to H/W.
As such, migrate this logic to IPAHAL (H/W abstraction
layer) of IPA driver and adapt the core driver code to
use it. New internal S/W API is added to access the IPAHAL
for Status Packet parsing.

CRs-Fixed: 980623
Change-Id: I5d6a8b8b18de44b0ae512a4610d9f55f538d0fdb
Signed-off-by: default avatarGhanim Fodi <gfodi@codeaurora.org>
parent 138036dc
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -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");
+55 −66
Original line number Diff line number Diff line
@@ -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),
@@ -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;
	}
@@ -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);
@@ -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);
@@ -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);
+104 −91
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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 */
@@ -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]);
		}
	};

@@ -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,
@@ -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;
@@ -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
@@ -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;
@@ -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) *
@@ -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 ||
@@ -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
	   ------------------------------------------
+0 −80
Original line number Diff line number Diff line
@@ -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 */
+9 −13
Original line number Diff line number Diff line
@@ -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"
@@ -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)
@@ -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;
};

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