// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (C) 2023 Intel Corporation */

#include <net/libeth/rx.h>
#include <net/libeth/tx.h>

#include "idpf.h"

/**
 * idpf_tx_singleq_csum - Enable tx checksum offloads
 * @skb: pointer to skb
 * @off: pointer to struct that holds offload parameters
 *
 * Returns 0 or error (negative) if checksum offload cannot be executed, 1
 * otherwise.
 */
static int idpf_tx_singleq_csum(struct sk_buff *skb,
				struct idpf_tx_offload_params *off)
{
	u32 l4_len, l3_len, l2_len;
	union {
		struct iphdr *v4;
		struct ipv6hdr *v6;
		unsigned char *hdr;
	} ip;
	union {
		struct tcphdr *tcp;
		unsigned char *hdr;
	} l4;
	u32 offset, cmd = 0;
	u8 l4_proto = 0;
	__be16 frag_off;
	bool is_tso;

	if (skb->ip_summed != CHECKSUM_PARTIAL)
		return 0;

	ip.hdr = skb_network_header(skb);
	l4.hdr = skb_transport_header(skb);

	/* compute outer L2 header size */
	l2_len = ip.hdr - skb->data;
	offset = FIELD_PREP(0x3F << IDPF_TX_DESC_LEN_MACLEN_S, l2_len / 2);
	is_tso = !!(off->tx_flags & IDPF_TX_FLAGS_TSO);
	if (skb->encapsulation) {
		u32 tunnel = 0;

		/* define outer network header type */
		if (off->tx_flags & IDPF_TX_FLAGS_IPV4) {
			/* The stack computes the IP header already, the only
			 * time we need the hardware to recompute it is in the
			 * case of TSO.
			 */
			tunnel |= is_tso ?
				  IDPF_TX_CTX_EXT_IP_IPV4 :
				  IDPF_TX_CTX_EXT_IP_IPV4_NO_CSUM;

			l4_proto = ip.v4->protocol;
		} else if (off->tx_flags & IDPF_TX_FLAGS_IPV6) {
			tunnel |= IDPF_TX_CTX_EXT_IP_IPV6;

			l4_proto = ip.v6->nexthdr;
			if (ipv6_ext_hdr(l4_proto))
				ipv6_skip_exthdr(skb, skb_network_offset(skb) +
						 sizeof(*ip.v6),
						 &l4_proto, &frag_off);
		}

		/* define outer transport */
		switch (l4_proto) {
		case IPPROTO_UDP:
			tunnel |= IDPF_TXD_CTX_UDP_TUNNELING;
			break;
		case IPPROTO_GRE:
			tunnel |= IDPF_TXD_CTX_GRE_TUNNELING;
			break;
		case IPPROTO_IPIP:
		case IPPROTO_IPV6:
			l4.hdr = skb_inner_network_header(skb);
			break;
		default:
			if (is_tso)
				return -1;

			skb_checksum_help(skb);

			return 0;
		}
		off->tx_flags |= IDPF_TX_FLAGS_TUNNEL;

		/* compute outer L3 header size */
		tunnel |= FIELD_PREP(IDPF_TXD_CTX_QW0_TUNN_EXT_IPLEN_M,
				     (l4.hdr - ip.hdr) / 4);

		/* switch IP header pointer from outer to inner header */
		ip.hdr = skb_inner_network_header(skb);

		/* compute tunnel header size */
		tunnel |= FIELD_PREP(IDPF_TXD_CTX_QW0_TUNN_NATLEN_M,
				     (ip.hdr - l4.hdr) / 2);

		/* indicate if we need to offload outer UDP header */
		if (is_tso &&
		    !(skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL) &&
		    (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM))
			tunnel |= IDPF_TXD_CTX_QW0_TUNN_L4T_CS_M;

		/* record tunnel offload values */
		off->cd_tunneling |= tunnel;

		/* switch L4 header pointer from outer to inner */
		l4.hdr = skb_inner_transport_header(skb);
		l4_proto = 0;

		/* reset type as we transition from outer to inner headers */
		off->tx_flags &= ~(IDPF_TX_FLAGS_IPV4 | IDPF_TX_FLAGS_IPV6);
		if (ip.v4->version == 4)
			off->tx_flags |= IDPF_TX_FLAGS_IPV4;
		if (ip.v6->version == 6)
			off->tx_flags |= IDPF_TX_FLAGS_IPV6;
	}

	/* Enable IP checksum offloads */
	if (off->tx_flags & IDPF_TX_FLAGS_IPV4) {
		l4_proto = ip.v4->protocol;
		/* See comment above regarding need for HW to recompute IP
		 * header checksum in the case of TSO.
		 */
		if (is_tso)
			cmd |= IDPF_TX_DESC_CMD_IIPT_IPV4_CSUM;
		else
			cmd |= IDPF_TX_DESC_CMD_IIPT_IPV4;

	} else if (off->tx_flags & IDPF_TX_FLAGS_IPV6) {
		cmd |= IDPF_TX_DESC_CMD_IIPT_IPV6;
		l4_proto = ip.v6->nexthdr;
		if (ipv6_ext_hdr(l4_proto))
			ipv6_skip_exthdr(skb, skb_network_offset(skb) +
					 sizeof(*ip.v6), &l4_proto,
					 &frag_off);
	} else {
		return -1;
	}

	/* compute inner L3 header size */
	l3_len = l4.hdr - ip.hdr;
	offset |= (l3_len / 4) << IDPF_TX_DESC_LEN_IPLEN_S;

	/* Enable L4 checksum offloads */
	switch (l4_proto) {
	case IPPROTO_TCP:
		/* enable checksum offloads */
		cmd |= IDPF_TX_DESC_CMD_L4T_EOFT_TCP;
		l4_len = l4.tcp->doff;
		break;
	case IPPROTO_UDP:
		/* enable UDP checksum offload */
		cmd |= IDPF_TX_DESC_CMD_L4T_EOFT_UDP;
		l4_len = sizeof(struct udphdr) >> 2;
		break;
	case IPPROTO_SCTP:
		/* enable SCTP checksum offload */
		cmd |= IDPF_TX_DESC_CMD_L4T_EOFT_SCTP;
		l4_len = sizeof(struct sctphdr) >> 2;
		break;
	default:
		if (is_tso)
			return -1;

		skb_checksum_help(skb);

		return 0;
	}

	offset |= l4_len << IDPF_TX_DESC_LEN_L4_LEN_S;
	off->td_cmd |= cmd;
	off->hdr_offsets |= offset;

	return 1;
}

/**
 * idpf_tx_singleq_map - Build the Tx base descriptor
 * @tx_q: queue to send buffer on
 * @first: first buffer info buffer to use
 * @offloads: pointer to struct that holds offload parameters
 *
 * This function loops over the skb data pointed to by *first
 * and gets a physical address for each memory location and programs
 * it and the length into the transmit base mode descriptor.
 */
static void idpf_tx_singleq_map(struct idpf_tx_queue *tx_q,
				struct idpf_tx_buf *first,
				struct idpf_tx_offload_params *offloads)
{
	u32 offsets = offloads->hdr_offsets;
	struct idpf_tx_buf *tx_buf = first;
	struct idpf_base_tx_desc *tx_desc;
	struct sk_buff *skb = first->skb;
	u64 td_cmd = offloads->td_cmd;
	unsigned int data_len, size;
	u16 i = tx_q->next_to_use;
	struct netdev_queue *nq;
	skb_frag_t *frag;
	dma_addr_t dma;
	u64 td_tag = 0;

	data_len = skb->data_len;
	size = skb_headlen(skb);

	tx_desc = &tx_q->base_tx[i];

	dma = dma_map_single(tx_q->dev, skb->data, size, DMA_TO_DEVICE);

	/* write each descriptor with CRC bit */
	if (idpf_queue_has(CRC_EN, tx_q))
		td_cmd |= IDPF_TX_DESC_CMD_ICRC;

	for (frag = &skb_shinfo(skb)->frags[0];; frag++) {
		unsigned int max_data = IDPF_TX_MAX_DESC_DATA_ALIGNED;

		if (dma_mapping_error(tx_q->dev, dma))
			return idpf_tx_dma_map_error(tx_q, skb, first, i);

		/* record length, and DMA address */
		dma_unmap_len_set(tx_buf, len, size);
		dma_unmap_addr_set(tx_buf, dma, dma);
		tx_buf->type = LIBETH_SQE_FRAG;

		/* align size to end of page */
		max_data += -dma & (IDPF_TX_MAX_READ_REQ_SIZE - 1);
		tx_desc->buf_addr = cpu_to_le64(dma);

		/* account for data chunks larger than the hardware
		 * can handle
		 */
		while (unlikely(size > IDPF_TX_MAX_DESC_DATA)) {
			tx_desc->qw1 = idpf_tx_singleq_build_ctob(td_cmd,
								  offsets,
								  max_data,
								  td_tag);
			if (unlikely(++i == tx_q->desc_count)) {
				tx_buf = &tx_q->tx_buf[0];
				tx_desc = &tx_q->base_tx[0];
				i = 0;
			} else {
				tx_buf++;
				tx_desc++;
			}

			tx_buf->type = LIBETH_SQE_EMPTY;

			dma += max_data;
			size -= max_data;

			max_data = IDPF_TX_MAX_DESC_DATA_ALIGNED;
			tx_desc->buf_addr = cpu_to_le64(dma);
		}

		if (!data_len)
			break;

		tx_desc->qw1 = idpf_tx_singleq_build_ctob(td_cmd, offsets,
							  size, td_tag);

		if (unlikely(++i == tx_q->desc_count)) {
			tx_buf = &tx_q->tx_buf[0];
			tx_desc = &tx_q->base_tx[0];
			i = 0;
		} else {
			tx_buf++;
			tx_desc++;
		}

		size = skb_frag_size(frag);
		data_len -= size;

		dma = skb_frag_dma_map(tx_q->dev, frag, 0, size,
				       DMA_TO_DEVICE);
	}

	skb_tx_timestamp(first->skb);

	/* write last descriptor with RS and EOP bits */
	td_cmd |= (u64)(IDPF_TX_DESC_CMD_EOP | IDPF_TX_DESC_CMD_RS);

	tx_desc->qw1 = idpf_tx_singleq_build_ctob(td_cmd, offsets,
						  size, td_tag);

	first->type = LIBETH_SQE_SKB;
	first->rs_idx = i;

	IDPF_SINGLEQ_BUMP_RING_IDX(tx_q, i);

	nq = netdev_get_tx_queue(tx_q->netdev, tx_q->idx);
	netdev_tx_sent_queue(nq, first->bytes);

	idpf_tx_buf_hw_update(tx_q, i, netdev_xmit_more());
}

/**
 * idpf_tx_singleq_get_ctx_desc - grab next desc and update buffer ring
 * @txq: queue to put context descriptor on
 *
 * Since the TX buffer rings mimics the descriptor ring, update the tx buffer
 * ring entry to reflect that this index is a context descriptor
 */
static struct idpf_base_tx_ctx_desc *
idpf_tx_singleq_get_ctx_desc(struct idpf_tx_queue *txq)
{
	struct idpf_base_tx_ctx_desc *ctx_desc;
	int ntu = txq->next_to_use;

	txq->tx_buf[ntu].type = LIBETH_SQE_CTX;

	ctx_desc = &txq->base_ctx[ntu];

	IDPF_SINGLEQ_BUMP_RING_IDX(txq, ntu);
	txq->next_to_use = ntu;

	return ctx_desc;
}

/**
 * idpf_tx_singleq_build_ctx_desc - populate context descriptor
 * @txq: queue to send buffer on
 * @offload: offload parameter structure
 **/
static void idpf_tx_singleq_build_ctx_desc(struct idpf_tx_queue *txq,
					   struct idpf_tx_offload_params *offload)
{
	struct idpf_base_tx_ctx_desc *desc = idpf_tx_singleq_get_ctx_desc(txq);
	u64 qw1 = (u64)IDPF_TX_DESC_DTYPE_CTX;

	if (offload->tso_segs) {
		qw1 |= IDPF_TX_CTX_DESC_TSO << IDPF_TXD_CTX_QW1_CMD_S;
		qw1 |= FIELD_PREP(IDPF_TXD_CTX_QW1_TSO_LEN_M,
				  offload->tso_len);
		qw1 |= FIELD_PREP(IDPF_TXD_CTX_QW1_MSS_M, offload->mss);

		u64_stats_update_begin(&txq->stats_sync);
		u64_stats_inc(&txq->q_stats.lso_pkts);
		u64_stats_update_end(&txq->stats_sync);
	}

	desc->qw0.tunneling_params = cpu_to_le32(offload->cd_tunneling);

	desc->qw0.l2tag2 = 0;
	desc->qw0.rsvd1 = 0;
	desc->qw1 = cpu_to_le64(qw1);
}

/**
 * idpf_tx_singleq_frame - Sends buffer on Tx ring using base descriptors
 * @skb: send buffer
 * @tx_q: queue to send buffer on
 *
 * Returns NETDEV_TX_OK if sent, else an error code
 */
netdev_tx_t idpf_tx_singleq_frame(struct sk_buff *skb,
				  struct idpf_tx_queue *tx_q)
{
	struct idpf_tx_offload_params offload = { };
	struct idpf_tx_buf *first;
	unsigned int count;
	__be16 protocol;
	int csum, tso;

	count = idpf_tx_desc_count_required(tx_q, skb);
	if (unlikely(!count))
		return idpf_tx_drop_skb(tx_q, skb);

	if (idpf_tx_maybe_stop_common(tx_q,
				      count + IDPF_TX_DESCS_PER_CACHE_LINE +
				      IDPF_TX_DESCS_FOR_CTX)) {
		idpf_tx_buf_hw_update(tx_q, tx_q->next_to_use, false);

		u64_stats_update_begin(&tx_q->stats_sync);
		u64_stats_inc(&tx_q->q_stats.q_busy);
		u64_stats_update_end(&tx_q->stats_sync);

		return NETDEV_TX_BUSY;
	}

	protocol = vlan_get_protocol(skb);
	if (protocol == htons(ETH_P_IP))
		offload.tx_flags |= IDPF_TX_FLAGS_IPV4;
	else if (protocol == htons(ETH_P_IPV6))
		offload.tx_flags |= IDPF_TX_FLAGS_IPV6;

	tso = idpf_tso(skb, &offload);
	if (tso < 0)
		goto out_drop;

	csum = idpf_tx_singleq_csum(skb, &offload);
	if (csum < 0)
		goto out_drop;

	if (tso || offload.cd_tunneling)
		idpf_tx_singleq_build_ctx_desc(tx_q, &offload);

	/* record the location of the first descriptor for this packet */
	first = &tx_q->tx_buf[tx_q->next_to_use];
	first->skb = skb;

	if (tso) {
		first->packets = offload.tso_segs;
		first->bytes = skb->len + ((first->packets - 1) * offload.tso_hdr_len);
	} else {
		first->bytes = max_t(unsigned int, skb->len, ETH_ZLEN);
		first->packets = 1;
	}
	idpf_tx_singleq_map(tx_q, first, &offload);

	return NETDEV_TX_OK;

out_drop:
	return idpf_tx_drop_skb(tx_q, skb);
}

/**
 * idpf_tx_singleq_clean - Reclaim resources from queue
 * @tx_q: Tx queue to clean
 * @napi_budget: Used to determine if we are in netpoll
 * @cleaned: returns number of packets cleaned
 *
 */
static bool idpf_tx_singleq_clean(struct idpf_tx_queue *tx_q, int napi_budget,
				  int *cleaned)
{
	struct libeth_sq_napi_stats ss = { };
	struct idpf_base_tx_desc *tx_desc;
	u32 budget = tx_q->clean_budget;
	s16 ntc = tx_q->next_to_clean;
	struct libeth_cq_pp cp = {
		.dev	= tx_q->dev,
		.ss	= &ss,
		.napi	= napi_budget,
	};
	struct idpf_netdev_priv *np;
	struct idpf_tx_buf *tx_buf;
	struct netdev_queue *nq;
	bool dont_wake;

	tx_desc = &tx_q->base_tx[ntc];
	tx_buf = &tx_q->tx_buf[ntc];
	ntc -= tx_q->desc_count;

	do {
		struct idpf_base_tx_desc *eop_desc;

		/* If this entry in the ring was used as a context descriptor,
		 * it's corresponding entry in the buffer ring will indicate as
		 * such. We can skip this descriptor since there is no buffer
		 * to clean.
		 */
		if (unlikely(tx_buf->type <= LIBETH_SQE_CTX)) {
			tx_buf->type = LIBETH_SQE_EMPTY;
			goto fetch_next_txq_desc;
		}

		if (unlikely(tx_buf->type != LIBETH_SQE_SKB))
			break;

		/* prevent any other reads prior to type */
		smp_rmb();

		eop_desc = &tx_q->base_tx[tx_buf->rs_idx];

		/* if the descriptor isn't done, no work yet to do */
		if (!(eop_desc->qw1 &
		      cpu_to_le64(IDPF_TX_DESC_DTYPE_DESC_DONE)))
			break;

		/* update the statistics for this packet */
		libeth_tx_complete(tx_buf, &cp);

		/* unmap remaining buffers */
		while (tx_desc != eop_desc) {
			tx_buf++;
			tx_desc++;
			ntc++;
			if (unlikely(!ntc)) {
				ntc -= tx_q->desc_count;
				tx_buf = tx_q->tx_buf;
				tx_desc = &tx_q->base_tx[0];
			}

			/* unmap any remaining paged data */
			libeth_tx_complete(tx_buf, &cp);
		}

		/* update budget only if we did something */
		budget--;

fetch_next_txq_desc:
		tx_buf++;
		tx_desc++;
		ntc++;
		if (unlikely(!ntc)) {
			ntc -= tx_q->desc_count;
			tx_buf = tx_q->tx_buf;
			tx_desc = &tx_q->base_tx[0];
		}
	} while (likely(budget));

	ntc += tx_q->desc_count;
	tx_q->next_to_clean = ntc;

	*cleaned += ss.packets;

	u64_stats_update_begin(&tx_q->stats_sync);
	u64_stats_add(&tx_q->q_stats.packets, ss.packets);
	u64_stats_add(&tx_q->q_stats.bytes, ss.bytes);
	u64_stats_update_end(&tx_q->stats_sync);

	np = netdev_priv(tx_q->netdev);
	nq = netdev_get_tx_queue(tx_q->netdev, tx_q->idx);

	dont_wake = np->state != __IDPF_VPORT_UP ||
		    !netif_carrier_ok(tx_q->netdev);
	__netif_txq_completed_wake(nq, ss.packets, ss.bytes,
				   IDPF_DESC_UNUSED(tx_q), IDPF_TX_WAKE_THRESH,
				   dont_wake);

	return !!budget;
}

/**
 * idpf_tx_singleq_clean_all - Clean all Tx queues
 * @q_vec: queue vector
 * @budget: Used to determine if we are in netpoll
 * @cleaned: returns number of packets cleaned
 *
 * Returns false if clean is not complete else returns true
 */
static bool idpf_tx_singleq_clean_all(struct idpf_q_vector *q_vec, int budget,
				      int *cleaned)
{
	u16 num_txq = q_vec->num_txq;
	bool clean_complete = true;
	int i, budget_per_q;

	budget_per_q = num_txq ? max(budget / num_txq, 1) : 0;
	for (i = 0; i < num_txq; i++) {
		struct idpf_tx_queue *q;

		q = q_vec->tx[i];
		clean_complete &= idpf_tx_singleq_clean(q, budget_per_q,
							cleaned);
	}

	return clean_complete;
}

/**
 * idpf_rx_singleq_test_staterr - tests bits in Rx descriptor
 * status and error fields
 * @rx_desc: pointer to receive descriptor (in le64 format)
 * @stat_err_bits: value to mask
 *
 * This function does some fast chicanery in order to return the
 * value of the mask which is really only used for boolean tests.
 * The status_error_ptype_len doesn't need to be shifted because it begins
 * at offset zero.
 */
static bool idpf_rx_singleq_test_staterr(const union virtchnl2_rx_desc *rx_desc,
					 const u64 stat_err_bits)
{
	return !!(rx_desc->base_wb.qword1.status_error_ptype_len &
		  cpu_to_le64(stat_err_bits));
}

/**
 * idpf_rx_singleq_is_non_eop - process handling of non-EOP buffers
 * @rx_desc: Rx descriptor for current buffer
 */
static bool idpf_rx_singleq_is_non_eop(const union virtchnl2_rx_desc *rx_desc)
{
	/* if we are the last buffer then there is nothing else to do */
	if (likely(idpf_rx_singleq_test_staterr(rx_desc, IDPF_RXD_EOF_SINGLEQ)))
		return false;

	return true;
}

/**
 * idpf_rx_singleq_csum - Indicate in skb if checksum is good
 * @rxq: Rx ring being processed
 * @skb: skb currently being received and modified
 * @csum_bits: checksum bits from descriptor
 * @decoded: the packet type decoded by hardware
 *
 * skb->protocol must be set before this function is called
 */
static void idpf_rx_singleq_csum(struct idpf_rx_queue *rxq,
				 struct sk_buff *skb,
				 struct idpf_rx_csum_decoded csum_bits,
				 struct libeth_rx_pt decoded)
{
	bool ipv4, ipv6;

	/* check if Rx checksum is enabled */
	if (!libeth_rx_pt_has_checksum(rxq->netdev, decoded))
		return;

	/* check if HW has decoded the packet and checksum */
	if (unlikely(!csum_bits.l3l4p))
		return;

	ipv4 = libeth_rx_pt_get_ip_ver(decoded) == LIBETH_RX_PT_OUTER_IPV4;
	ipv6 = libeth_rx_pt_get_ip_ver(decoded) == LIBETH_RX_PT_OUTER_IPV6;

	/* Check if there were any checksum errors */
	if (unlikely(ipv4 && (csum_bits.ipe || csum_bits.eipe)))
		goto checksum_fail;

	/* Device could not do any checksum offload for certain extension
	 * headers as indicated by setting IPV6EXADD bit
	 */
	if (unlikely(ipv6 && csum_bits.ipv6exadd))
		return;

	/* check for L4 errors and handle packets that were not able to be
	 * checksummed due to arrival speed
	 */
	if (unlikely(csum_bits.l4e))
		goto checksum_fail;

	if (unlikely(csum_bits.nat && csum_bits.eudpe))
		goto checksum_fail;

	/* Handle packets that were not able to be checksummed due to arrival
	 * speed, in this case the stack can compute the csum.
	 */
	if (unlikely(csum_bits.pprs))
		return;

	/* If there is an outer header present that might contain a checksum
	 * we need to bump the checksum level by 1 to reflect the fact that
	 * we are indicating we validated the inner checksum.
	 */
	if (decoded.tunnel_type >= LIBETH_RX_PT_TUNNEL_IP_GRENAT)
		skb->csum_level = 1;

	skb->ip_summed = CHECKSUM_UNNECESSARY;
	return;

checksum_fail:
	u64_stats_update_begin(&rxq->stats_sync);
	u64_stats_inc(&rxq->q_stats.hw_csum_err);
	u64_stats_update_end(&rxq->stats_sync);
}

/**
 * idpf_rx_singleq_base_csum - Indicate in skb if hw indicated a good cksum
 * @rx_desc: the receive descriptor
 *
 * This function only operates on the VIRTCHNL2_RXDID_1_32B_BASE_M base 32byte
 * descriptor writeback format.
 *
 * Return: parsed checksum status.
 **/
static struct idpf_rx_csum_decoded
idpf_rx_singleq_base_csum(const union virtchnl2_rx_desc *rx_desc)
{
	struct idpf_rx_csum_decoded csum_bits = { };
	u32 rx_error, rx_status;
	u64 qword;

	qword = le64_to_cpu(rx_desc->base_wb.qword1.status_error_ptype_len);

	rx_status = FIELD_GET(VIRTCHNL2_RX_BASE_DESC_QW1_STATUS_M, qword);
	rx_error = FIELD_GET(VIRTCHNL2_RX_BASE_DESC_QW1_ERROR_M, qword);

	csum_bits.ipe = FIELD_GET(VIRTCHNL2_RX_BASE_DESC_ERROR_IPE_M, rx_error);
	csum_bits.eipe = FIELD_GET(VIRTCHNL2_RX_BASE_DESC_ERROR_EIPE_M,
				   rx_error);
	csum_bits.l4e = FIELD_GET(VIRTCHNL2_RX_BASE_DESC_ERROR_L4E_M, rx_error);
	csum_bits.pprs = FIELD_GET(VIRTCHNL2_RX_BASE_DESC_ERROR_PPRS_M,
				   rx_error);
	csum_bits.l3l4p = FIELD_GET(VIRTCHNL2_RX_BASE_DESC_STATUS_L3L4P_M,
				    rx_status);
	csum_bits.ipv6exadd = FIELD_GET(VIRTCHNL2_RX_BASE_DESC_STATUS_IPV6EXADD_M,
					rx_status);

	return csum_bits;
}

/**
 * idpf_rx_singleq_flex_csum - Indicate in skb if hw indicated a good cksum
 * @rx_desc: the receive descriptor
 *
 * This function only operates on the VIRTCHNL2_RXDID_2_FLEX_SQ_NIC flexible
 * descriptor writeback format.
 *
 * Return: parsed checksum status.
 **/
static struct idpf_rx_csum_decoded
idpf_rx_singleq_flex_csum(const union virtchnl2_rx_desc *rx_desc)
{
	struct idpf_rx_csum_decoded csum_bits = { };
	u16 rx_status0, rx_status1;

	rx_status0 = le16_to_cpu(rx_desc->flex_nic_wb.status_error0);
	rx_status1 = le16_to_cpu(rx_desc->flex_nic_wb.status_error1);

	csum_bits.ipe = FIELD_GET(VIRTCHNL2_RX_FLEX_DESC_STATUS0_XSUM_IPE_M,
				  rx_status0);
	csum_bits.eipe = FIELD_GET(VIRTCHNL2_RX_FLEX_DESC_STATUS0_XSUM_EIPE_M,
				   rx_status0);
	csum_bits.l4e = FIELD_GET(VIRTCHNL2_RX_FLEX_DESC_STATUS0_XSUM_L4E_M,
				  rx_status0);
	csum_bits.eudpe = FIELD_GET(VIRTCHNL2_RX_FLEX_DESC_STATUS0_XSUM_EUDPE_M,
				    rx_status0);
	csum_bits.l3l4p = FIELD_GET(VIRTCHNL2_RX_FLEX_DESC_STATUS0_L3L4P_M,
				    rx_status0);
	csum_bits.ipv6exadd = FIELD_GET(VIRTCHNL2_RX_FLEX_DESC_STATUS0_IPV6EXADD_M,
					rx_status0);
	csum_bits.nat = FIELD_GET(VIRTCHNL2_RX_FLEX_DESC_STATUS1_NAT_M,
				  rx_status1);

	return csum_bits;
}

/**
 * idpf_rx_singleq_base_hash - set the hash value in the skb
 * @rx_q: Rx completion queue
 * @skb: skb currently being received and modified
 * @rx_desc: specific descriptor
 * @decoded: Decoded Rx packet type related fields
 *
 * This function only operates on the VIRTCHNL2_RXDID_1_32B_BASE_M base 32byte
 * descriptor writeback format.
 **/
static void idpf_rx_singleq_base_hash(struct idpf_rx_queue *rx_q,
				      struct sk_buff *skb,
				      const union virtchnl2_rx_desc *rx_desc,
				      struct libeth_rx_pt decoded)
{
	u64 mask, qw1;

	if (!libeth_rx_pt_has_hash(rx_q->netdev, decoded))
		return;

	mask = VIRTCHNL2_RX_BASE_DESC_FLTSTAT_RSS_HASH_M;
	qw1 = le64_to_cpu(rx_desc->base_wb.qword1.status_error_ptype_len);

	if (FIELD_GET(mask, qw1) == mask) {
		u32 hash = le32_to_cpu(rx_desc->base_wb.qword0.hi_dword.rss);

		libeth_rx_pt_set_hash(skb, hash, decoded);
	}
}

/**
 * idpf_rx_singleq_flex_hash - set the hash value in the skb
 * @rx_q: Rx completion queue
 * @skb: skb currently being received and modified
 * @rx_desc: specific descriptor
 * @decoded: Decoded Rx packet type related fields
 *
 * This function only operates on the VIRTCHNL2_RXDID_2_FLEX_SQ_NIC flexible
 * descriptor writeback format.
 **/
static void idpf_rx_singleq_flex_hash(struct idpf_rx_queue *rx_q,
				      struct sk_buff *skb,
				      const union virtchnl2_rx_desc *rx_desc,
				      struct libeth_rx_pt decoded)
{
	if (!libeth_rx_pt_has_hash(rx_q->netdev, decoded))
		return;

	if (FIELD_GET(VIRTCHNL2_RX_FLEX_DESC_STATUS0_RSS_VALID_M,
		      le16_to_cpu(rx_desc->flex_nic_wb.status_error0))) {
		u32 hash = le32_to_cpu(rx_desc->flex_nic_wb.rss_hash);

		libeth_rx_pt_set_hash(skb, hash, decoded);
	}
}

/**
 * idpf_rx_singleq_process_skb_fields - Populate skb header fields from Rx
 * descriptor
 * @rx_q: Rx ring being processed
 * @skb: pointer to current skb being populated
 * @rx_desc: descriptor for skb
 * @ptype: packet type
 *
 * This function checks the ring, descriptor, and packet information in
 * order to populate the hash, checksum, VLAN, protocol, and
 * other fields within the skb.
 */
static void
idpf_rx_singleq_process_skb_fields(struct idpf_rx_queue *rx_q,
				   struct sk_buff *skb,
				   const union virtchnl2_rx_desc *rx_desc,
				   u16 ptype)
{
	struct libeth_rx_pt decoded = rx_q->rx_ptype_lkup[ptype];
	struct idpf_rx_csum_decoded csum_bits;

	/* modifies the skb - consumes the enet header */
	skb->protocol = eth_type_trans(skb, rx_q->netdev);

	/* Check if we're using base mode descriptor IDs */
	if (rx_q->rxdids == VIRTCHNL2_RXDID_1_32B_BASE_M) {
		idpf_rx_singleq_base_hash(rx_q, skb, rx_desc, decoded);
		csum_bits = idpf_rx_singleq_base_csum(rx_desc);
	} else {
		idpf_rx_singleq_flex_hash(rx_q, skb, rx_desc, decoded);
		csum_bits = idpf_rx_singleq_flex_csum(rx_desc);
	}

	idpf_rx_singleq_csum(rx_q, skb, csum_bits, decoded);
	skb_record_rx_queue(skb, rx_q->idx);
}

/**
 * idpf_rx_buf_hw_update - Store the new tail and head values
 * @rxq: queue to bump
 * @val: new head index
 */
static void idpf_rx_buf_hw_update(struct idpf_rx_queue *rxq, u32 val)
{
	rxq->next_to_use = val;

	if (unlikely(!rxq->tail))
		return;

	/* writel has an implicit memory barrier */
	writel(val, rxq->tail);
}

/**
 * idpf_rx_singleq_buf_hw_alloc_all - Replace used receive buffers
 * @rx_q: queue for which the hw buffers are allocated
 * @cleaned_count: number of buffers to replace
 *
 * Returns false if all allocations were successful, true if any fail
 */
bool idpf_rx_singleq_buf_hw_alloc_all(struct idpf_rx_queue *rx_q,
				      u16 cleaned_count)
{
	struct virtchnl2_singleq_rx_buf_desc *desc;
	const struct libeth_fq_fp fq = {
		.pp		= rx_q->pp,
		.fqes		= rx_q->rx_buf,
		.truesize	= rx_q->truesize,
		.count		= rx_q->desc_count,
	};
	u16 nta = rx_q->next_to_alloc;

	if (!cleaned_count)
		return false;

	desc = &rx_q->single_buf[nta];

	do {
		dma_addr_t addr;

		addr = libeth_rx_alloc(&fq, nta);
		if (addr == DMA_MAPPING_ERROR)
			break;

		/* Refresh the desc even if buffer_addrs didn't change
		 * because each write-back erases this info.
		 */
		desc->pkt_addr = cpu_to_le64(addr);
		desc->hdr_addr = 0;
		desc++;

		nta++;
		if (unlikely(nta == rx_q->desc_count)) {
			desc = &rx_q->single_buf[0];
			nta = 0;
		}

		cleaned_count--;
	} while (cleaned_count);

	if (rx_q->next_to_alloc != nta) {
		idpf_rx_buf_hw_update(rx_q, nta);
		rx_q->next_to_alloc = nta;
	}

	return !!cleaned_count;
}

/**
 * idpf_rx_singleq_extract_base_fields - Extract fields from the Rx descriptor
 * @rx_desc: the descriptor to process
 * @fields: storage for extracted values
 *
 * Decode the Rx descriptor and extract relevant information including the
 * size and Rx packet type.
 *
 * This function only operates on the VIRTCHNL2_RXDID_1_32B_BASE_M base 32byte
 * descriptor writeback format.
 */
static void
idpf_rx_singleq_extract_base_fields(const union virtchnl2_rx_desc *rx_desc,
				    struct idpf_rx_extracted *fields)
{
	u64 qword;

	qword = le64_to_cpu(rx_desc->base_wb.qword1.status_error_ptype_len);

	fields->size = FIELD_GET(VIRTCHNL2_RX_BASE_DESC_QW1_LEN_PBUF_M, qword);
	fields->rx_ptype = FIELD_GET(VIRTCHNL2_RX_BASE_DESC_QW1_PTYPE_M, qword);
}

/**
 * idpf_rx_singleq_extract_flex_fields - Extract fields from the Rx descriptor
 * @rx_desc: the descriptor to process
 * @fields: storage for extracted values
 *
 * Decode the Rx descriptor and extract relevant information including the
 * size and Rx packet type.
 *
 * This function only operates on the VIRTCHNL2_RXDID_2_FLEX_SQ_NIC flexible
 * descriptor writeback format.
 */
static void
idpf_rx_singleq_extract_flex_fields(const union virtchnl2_rx_desc *rx_desc,
				    struct idpf_rx_extracted *fields)
{
	fields->size = FIELD_GET(VIRTCHNL2_RX_FLEX_DESC_PKT_LEN_M,
				 le16_to_cpu(rx_desc->flex_nic_wb.pkt_len));
	fields->rx_ptype = FIELD_GET(VIRTCHNL2_RX_FLEX_DESC_PTYPE_M,
				     le16_to_cpu(rx_desc->flex_nic_wb.ptype_flex_flags0));
}

/**
 * idpf_rx_singleq_extract_fields - Extract fields from the Rx descriptor
 * @rx_q: Rx descriptor queue
 * @rx_desc: the descriptor to process
 * @fields: storage for extracted values
 *
 */
static void
idpf_rx_singleq_extract_fields(const struct idpf_rx_queue *rx_q,
			       const union virtchnl2_rx_desc *rx_desc,
			       struct idpf_rx_extracted *fields)
{
	if (rx_q->rxdids == VIRTCHNL2_RXDID_1_32B_BASE_M)
		idpf_rx_singleq_extract_base_fields(rx_desc, fields);
	else
		idpf_rx_singleq_extract_flex_fields(rx_desc, fields);
}

/**
 * idpf_rx_singleq_clean - Reclaim resources after receive completes
 * @rx_q: rx queue to clean
 * @budget: Total limit on number of packets to process
 *
 * Returns true if there's any budget left (e.g. the clean is finished)
 */
static int idpf_rx_singleq_clean(struct idpf_rx_queue *rx_q, int budget)
{
	unsigned int total_rx_bytes = 0, total_rx_pkts = 0;
	struct sk_buff *skb = rx_q->skb;
	u16 ntc = rx_q->next_to_clean;
	u16 cleaned_count = 0;
	bool failure = false;

	/* Process Rx packets bounded by budget */
	while (likely(total_rx_pkts < (unsigned int)budget)) {
		struct idpf_rx_extracted fields = { };
		union virtchnl2_rx_desc *rx_desc;
		struct idpf_rx_buf *rx_buf;

		/* get the Rx desc from Rx queue based on 'next_to_clean' */
		rx_desc = &rx_q->rx[ntc];

		/* status_error_ptype_len will always be zero for unused
		 * descriptors because it's cleared in cleanup, and overlaps
		 * with hdr_addr which is always zero because packet split
		 * isn't used, if the hardware wrote DD then the length will be
		 * non-zero
		 */
#define IDPF_RXD_DD VIRTCHNL2_RX_BASE_DESC_STATUS_DD_M
		if (!idpf_rx_singleq_test_staterr(rx_desc,
						  IDPF_RXD_DD))
			break;

		/* This memory barrier is needed to keep us from reading
		 * any other fields out of the rx_desc
		 */
		dma_rmb();

		idpf_rx_singleq_extract_fields(rx_q, rx_desc, &fields);

		rx_buf = &rx_q->rx_buf[ntc];
		if (!libeth_rx_sync_for_cpu(rx_buf, fields.size))
			goto skip_data;

		if (skb)
			idpf_rx_add_frag(rx_buf, skb, fields.size);
		else
			skb = idpf_rx_build_skb(rx_buf, fields.size);

		/* exit if we failed to retrieve a buffer */
		if (!skb)
			break;

skip_data:
		rx_buf->page = NULL;

		IDPF_SINGLEQ_BUMP_RING_IDX(rx_q, ntc);
		cleaned_count++;

		/* skip if it is non EOP desc */
		if (idpf_rx_singleq_is_non_eop(rx_desc) || unlikely(!skb))
			continue;

#define IDPF_RXD_ERR_S FIELD_PREP(VIRTCHNL2_RX_BASE_DESC_QW1_ERROR_M, \
				  VIRTCHNL2_RX_BASE_DESC_ERROR_RXE_M)
		if (unlikely(idpf_rx_singleq_test_staterr(rx_desc,
							  IDPF_RXD_ERR_S))) {
			dev_kfree_skb_any(skb);
			skb = NULL;
			continue;
		}

		/* pad skb if needed (to make valid ethernet frame) */
		if (eth_skb_pad(skb)) {
			skb = NULL;
			continue;
		}

		/* probably a little skewed due to removing CRC */
		total_rx_bytes += skb->len;

		/* protocol */
		idpf_rx_singleq_process_skb_fields(rx_q, skb,
						   rx_desc, fields.rx_ptype);

		/* send completed skb up the stack */
		napi_gro_receive(rx_q->pp->p.napi, skb);
		skb = NULL;

		/* update budget accounting */
		total_rx_pkts++;
	}

	rx_q->skb = skb;

	rx_q->next_to_clean = ntc;

	page_pool_nid_changed(rx_q->pp, numa_mem_id());
	if (cleaned_count)
		failure = idpf_rx_singleq_buf_hw_alloc_all(rx_q, cleaned_count);

	u64_stats_update_begin(&rx_q->stats_sync);
	u64_stats_add(&rx_q->q_stats.packets, total_rx_pkts);
	u64_stats_add(&rx_q->q_stats.bytes, total_rx_bytes);
	u64_stats_update_end(&rx_q->stats_sync);

	/* guarantee a trip back through this routine if there was a failure */
	return failure ? budget : (int)total_rx_pkts;
}

/**
 * idpf_rx_singleq_clean_all - Clean all Rx queues
 * @q_vec: queue vector
 * @budget: Used to determine if we are in netpoll
 * @cleaned: returns number of packets cleaned
 *
 * Returns false if clean is not complete else returns true
 */
static bool idpf_rx_singleq_clean_all(struct idpf_q_vector *q_vec, int budget,
				      int *cleaned)
{
	u16 num_rxq = q_vec->num_rxq;
	bool clean_complete = true;
	int budget_per_q, i;

	/* We attempt to distribute budget to each Rx queue fairly, but don't
	 * allow the budget to go below 1 because that would exit polling early.
	 */
	budget_per_q = num_rxq ? max(budget / num_rxq, 1) : 0;
	for (i = 0; i < num_rxq; i++) {
		struct idpf_rx_queue *rxq = q_vec->rx[i];
		int pkts_cleaned_per_q;

		pkts_cleaned_per_q = idpf_rx_singleq_clean(rxq, budget_per_q);

		/* if we clean as many as budgeted, we must not be done */
		if (pkts_cleaned_per_q >= budget_per_q)
			clean_complete = false;
		*cleaned += pkts_cleaned_per_q;
	}

	return clean_complete;
}

/**
 * idpf_vport_singleq_napi_poll - NAPI handler
 * @napi: struct from which you get q_vector
 * @budget: budget provided by stack
 */
int idpf_vport_singleq_napi_poll(struct napi_struct *napi, int budget)
{
	struct idpf_q_vector *q_vector =
				container_of(napi, struct idpf_q_vector, napi);
	bool clean_complete;
	int work_done = 0;

	/* Handle case where we are called by netpoll with a budget of 0 */
	if (budget <= 0) {
		idpf_tx_singleq_clean_all(q_vector, budget, &work_done);

		return budget;
	}

	clean_complete = idpf_rx_singleq_clean_all(q_vector, budget,
						   &work_done);
	clean_complete &= idpf_tx_singleq_clean_all(q_vector, budget,
						    &work_done);

	/* If work not completed, return budget and polling will return */
	if (!clean_complete) {
		idpf_vport_intr_set_wb_on_itr(q_vector);
		return budget;
	}

	work_done = min_t(int, work_done, budget - 1);

	/* Exit the polling mode, but don't re-enable interrupts if stack might
	 * poll us due to busy-polling
	 */
	if (likely(napi_complete_done(napi, work_done)))
		idpf_vport_intr_update_itr_ena_irq(q_vector);
	else
		idpf_vport_intr_set_wb_on_itr(q_vector);

	return work_done;
}
