// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
/* QLogic qede NIC Driver
 * Copyright (c) 2015-2017  QLogic Corporation
 * Copyright (c) 2019-2020 Marvell International Ltd.
 */

#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/bpf_trace.h>
#include <net/udp_tunnel.h>
#include <linux/ip.h>
#include <net/ipv6.h>
#include <net/tcp.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <net/ip6_checksum.h>
#include "qede_ptp.h"

#include <linux/qed/qed_if.h>
#include "qede.h"
/*********************************
 * Content also used by slowpath *
 *********************************/

int qede_alloc_rx_buffer(struct qede_rx_queue *rxq, bool allow_lazy)
{
	struct sw_rx_data *sw_rx_data;
	struct eth_rx_bd *rx_bd;
	dma_addr_t mapping;
	struct page *data;

	/* In case lazy-allocation is allowed, postpone allocation until the
	 * end of the NAPI run. We'd still need to make sure the Rx ring has
	 * sufficient buffers to guarantee an additional Rx interrupt.
	 */
	if (allow_lazy && likely(rxq->filled_buffers > 12)) {
		rxq->filled_buffers--;
		return 0;
	}

	data = alloc_pages(GFP_ATOMIC, 0);
	if (unlikely(!data))
		return -ENOMEM;

	/* Map the entire page as it would be used
	 * for multiple RX buffer segment size mapping.
	 */
	mapping = dma_map_page(rxq->dev, data, 0,
			       PAGE_SIZE, rxq->data_direction);
	if (unlikely(dma_mapping_error(rxq->dev, mapping))) {
		__free_page(data);
		return -ENOMEM;
	}

	sw_rx_data = &rxq->sw_rx_ring[rxq->sw_rx_prod & NUM_RX_BDS_MAX];
	sw_rx_data->page_offset = 0;
	sw_rx_data->data = data;
	sw_rx_data->mapping = mapping;

	/* Advance PROD and get BD pointer */
	rx_bd = (struct eth_rx_bd *)qed_chain_produce(&rxq->rx_bd_ring);
	WARN_ON(!rx_bd);
	rx_bd->addr.hi = cpu_to_le32(upper_32_bits(mapping));
	rx_bd->addr.lo = cpu_to_le32(lower_32_bits(mapping) +
				     rxq->rx_headroom);

	rxq->sw_rx_prod++;
	rxq->filled_buffers++;

	return 0;
}

/* Unmap the data and free skb */
int qede_free_tx_pkt(struct qede_dev *edev, struct qede_tx_queue *txq, int *len)
{
	u16 idx = txq->sw_tx_cons;
	struct sk_buff *skb = txq->sw_tx_ring.skbs[idx].skb;
	struct eth_tx_1st_bd *first_bd;
	struct eth_tx_bd *tx_data_bd;
	int bds_consumed = 0;
	int nbds;
	bool data_split = txq->sw_tx_ring.skbs[idx].flags & QEDE_TSO_SPLIT_BD;
	int i, split_bd_len = 0;

	if (unlikely(!skb)) {
		DP_ERR(edev,
		       "skb is null for txq idx=%d txq->sw_tx_cons=%d txq->sw_tx_prod=%d\n",
		       idx, txq->sw_tx_cons, txq->sw_tx_prod);
		return -1;
	}

	*len = skb->len;

	first_bd = (struct eth_tx_1st_bd *)qed_chain_consume(&txq->tx_pbl);

	bds_consumed++;

	nbds = first_bd->data.nbds;

	if (data_split) {
		struct eth_tx_bd *split = (struct eth_tx_bd *)
			qed_chain_consume(&txq->tx_pbl);
		split_bd_len = BD_UNMAP_LEN(split);
		bds_consumed++;
	}
	dma_unmap_single(&edev->pdev->dev, BD_UNMAP_ADDR(first_bd),
			 BD_UNMAP_LEN(first_bd) + split_bd_len, DMA_TO_DEVICE);

	/* Unmap the data of the skb frags */
	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++, bds_consumed++) {
		tx_data_bd = (struct eth_tx_bd *)
			qed_chain_consume(&txq->tx_pbl);
		dma_unmap_page(&edev->pdev->dev, BD_UNMAP_ADDR(tx_data_bd),
			       BD_UNMAP_LEN(tx_data_bd), DMA_TO_DEVICE);
	}

	while (bds_consumed++ < nbds)
		qed_chain_consume(&txq->tx_pbl);

	/* Free skb */
	dev_kfree_skb_any(skb);
	txq->sw_tx_ring.skbs[idx].skb = NULL;
	txq->sw_tx_ring.skbs[idx].flags = 0;

	return 0;
}

/* Unmap the data and free skb when mapping failed during start_xmit */
static void qede_free_failed_tx_pkt(struct qede_tx_queue *txq,
				    struct eth_tx_1st_bd *first_bd,
				    int nbd, bool data_split)
{
	u16 idx = txq->sw_tx_prod;
	struct sk_buff *skb = txq->sw_tx_ring.skbs[idx].skb;
	struct eth_tx_bd *tx_data_bd;
	int i, split_bd_len = 0;

	/* Return prod to its position before this skb was handled */
	qed_chain_set_prod(&txq->tx_pbl,
			   le16_to_cpu(txq->tx_db.data.bd_prod), first_bd);

	first_bd = (struct eth_tx_1st_bd *)qed_chain_produce(&txq->tx_pbl);

	if (data_split) {
		struct eth_tx_bd *split = (struct eth_tx_bd *)
					  qed_chain_produce(&txq->tx_pbl);
		split_bd_len = BD_UNMAP_LEN(split);
		nbd--;
	}

	dma_unmap_single(txq->dev, BD_UNMAP_ADDR(first_bd),
			 BD_UNMAP_LEN(first_bd) + split_bd_len, DMA_TO_DEVICE);

	/* Unmap the data of the skb frags */
	for (i = 0; i < nbd; i++) {
		tx_data_bd = (struct eth_tx_bd *)
			qed_chain_produce(&txq->tx_pbl);
		if (tx_data_bd->nbytes)
			dma_unmap_page(txq->dev,
				       BD_UNMAP_ADDR(tx_data_bd),
				       BD_UNMAP_LEN(tx_data_bd), DMA_TO_DEVICE);
	}

	/* Return again prod to its position before this skb was handled */
	qed_chain_set_prod(&txq->tx_pbl,
			   le16_to_cpu(txq->tx_db.data.bd_prod), first_bd);

	/* Free skb */
	dev_kfree_skb_any(skb);
	txq->sw_tx_ring.skbs[idx].skb = NULL;
	txq->sw_tx_ring.skbs[idx].flags = 0;
}

static u32 qede_xmit_type(struct sk_buff *skb, int *ipv6_ext)
{
	u32 rc = XMIT_L4_CSUM;
	__be16 l3_proto;

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

	l3_proto = vlan_get_protocol(skb);
	if (l3_proto == htons(ETH_P_IPV6) &&
	    (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6))
		*ipv6_ext = 1;

	if (skb->encapsulation) {
		rc |= XMIT_ENC;
		if (skb_is_gso(skb)) {
			unsigned short gso_type = skb_shinfo(skb)->gso_type;

			if ((gso_type & SKB_GSO_UDP_TUNNEL_CSUM) ||
			    (gso_type & SKB_GSO_GRE_CSUM))
				rc |= XMIT_ENC_GSO_L4_CSUM;

			rc |= XMIT_LSO;
			return rc;
		}
	}

	if (skb_is_gso(skb))
		rc |= XMIT_LSO;

	return rc;
}

static void qede_set_params_for_ipv6_ext(struct sk_buff *skb,
					 struct eth_tx_2nd_bd *second_bd,
					 struct eth_tx_3rd_bd *third_bd)
{
	u8 l4_proto;
	u16 bd2_bits1 = 0, bd2_bits2 = 0;

	bd2_bits1 |= (1 << ETH_TX_DATA_2ND_BD_IPV6_EXT_SHIFT);

	bd2_bits2 |= ((((u8 *)skb_transport_header(skb) - skb->data) >> 1) &
		     ETH_TX_DATA_2ND_BD_L4_HDR_START_OFFSET_W_MASK)
		    << ETH_TX_DATA_2ND_BD_L4_HDR_START_OFFSET_W_SHIFT;

	bd2_bits1 |= (ETH_L4_PSEUDO_CSUM_CORRECT_LENGTH <<
		      ETH_TX_DATA_2ND_BD_L4_PSEUDO_CSUM_MODE_SHIFT);

	if (vlan_get_protocol(skb) == htons(ETH_P_IPV6))
		l4_proto = ipv6_hdr(skb)->nexthdr;
	else
		l4_proto = ip_hdr(skb)->protocol;

	if (l4_proto == IPPROTO_UDP)
		bd2_bits1 |= 1 << ETH_TX_DATA_2ND_BD_L4_UDP_SHIFT;

	if (third_bd)
		third_bd->data.bitfields |=
			cpu_to_le16(((tcp_hdrlen(skb) / 4) &
				ETH_TX_DATA_3RD_BD_TCP_HDR_LEN_DW_MASK) <<
				ETH_TX_DATA_3RD_BD_TCP_HDR_LEN_DW_SHIFT);

	second_bd->data.bitfields1 = cpu_to_le16(bd2_bits1);
	second_bd->data.bitfields2 = cpu_to_le16(bd2_bits2);
}

static int map_frag_to_bd(struct qede_tx_queue *txq,
			  skb_frag_t *frag, struct eth_tx_bd *bd)
{
	dma_addr_t mapping;

	/* Map skb non-linear frag data for DMA */
	mapping = skb_frag_dma_map(txq->dev, frag, 0,
				   skb_frag_size(frag), DMA_TO_DEVICE);
	if (unlikely(dma_mapping_error(txq->dev, mapping)))
		return -ENOMEM;

	/* Setup the data pointer of the frag data */
	BD_SET_UNMAP_ADDR_LEN(bd, mapping, skb_frag_size(frag));

	return 0;
}

static u16 qede_get_skb_hlen(struct sk_buff *skb, bool is_encap_pkt)
{
	if (is_encap_pkt)
		return (skb_inner_transport_header(skb) +
			inner_tcp_hdrlen(skb) - skb->data);
	else
		return (skb_transport_header(skb) +
			tcp_hdrlen(skb) - skb->data);
}

/* +2 for 1st BD for headers and 2nd BD for headlen (if required) */
#if ((MAX_SKB_FRAGS + 2) > ETH_TX_MAX_BDS_PER_NON_LSO_PACKET)
static bool qede_pkt_req_lin(struct sk_buff *skb, u8 xmit_type)
{
	int allowed_frags = ETH_TX_MAX_BDS_PER_NON_LSO_PACKET - 1;

	if (xmit_type & XMIT_LSO) {
		int hlen;

		hlen = qede_get_skb_hlen(skb, xmit_type & XMIT_ENC);

		/* linear payload would require its own BD */
		if (skb_headlen(skb) > hlen)
			allowed_frags--;
	}

	return (skb_shinfo(skb)->nr_frags > allowed_frags);
}
#endif

static inline void qede_update_tx_producer(struct qede_tx_queue *txq)
{
	/* wmb makes sure that the BDs data is updated before updating the
	 * producer, otherwise FW may read old data from the BDs.
	 */
	wmb();
	barrier();
	writel(txq->tx_db.raw, txq->doorbell_addr);

	/* Fence required to flush the write combined buffer, since another
	 * CPU may write to the same doorbell address and data may be lost
	 * due to relaxed order nature of write combined bar.
	 */
	wmb();
}

static int qede_xdp_xmit(struct qede_tx_queue *txq, dma_addr_t dma, u16 pad,
			 u16 len, struct page *page, struct xdp_frame *xdpf)
{
	struct eth_tx_1st_bd *bd;
	struct sw_tx_xdp *xdp;
	u16 val;

	if (unlikely(qed_chain_get_elem_used(&txq->tx_pbl) >=
		     txq->num_tx_buffers)) {
		txq->stopped_cnt++;
		return -ENOMEM;
	}

	bd = qed_chain_produce(&txq->tx_pbl);
	bd->data.nbds = 1;
	bd->data.bd_flags.bitfields = BIT(ETH_TX_1ST_BD_FLAGS_START_BD_SHIFT);

	val = (len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK) <<
	       ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT;

	bd->data.bitfields = cpu_to_le16(val);

	/* We can safely ignore the offset, as it's 0 for XDP */
	BD_SET_UNMAP_ADDR_LEN(bd, dma + pad, len);

	xdp = txq->sw_tx_ring.xdp + txq->sw_tx_prod;
	xdp->mapping = dma;
	xdp->page = page;
	xdp->xdpf = xdpf;

	txq->sw_tx_prod = (txq->sw_tx_prod + 1) % txq->num_tx_buffers;

	return 0;
}

int qede_xdp_transmit(struct net_device *dev, int n_frames,
		      struct xdp_frame **frames, u32 flags)
{
	struct qede_dev *edev = netdev_priv(dev);
	struct device *dmadev = &edev->pdev->dev;
	struct qede_tx_queue *xdp_tx;
	struct xdp_frame *xdpf;
	dma_addr_t mapping;
	int i, nxmit = 0;
	u16 xdp_prod;

	if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
		return -EINVAL;

	if (unlikely(!netif_running(dev)))
		return -ENETDOWN;

	i = smp_processor_id() % edev->total_xdp_queues;
	xdp_tx = edev->fp_array[i].xdp_tx;

	spin_lock(&xdp_tx->xdp_tx_lock);

	for (i = 0; i < n_frames; i++) {
		xdpf = frames[i];

		mapping = dma_map_single(dmadev, xdpf->data, xdpf->len,
					 DMA_TO_DEVICE);
		if (unlikely(dma_mapping_error(dmadev, mapping)))
			break;

		if (unlikely(qede_xdp_xmit(xdp_tx, mapping, 0, xdpf->len,
					   NULL, xdpf)))
			break;
		nxmit++;
	}

	if (flags & XDP_XMIT_FLUSH) {
		xdp_prod = qed_chain_get_prod_idx(&xdp_tx->tx_pbl);

		xdp_tx->tx_db.data.bd_prod = cpu_to_le16(xdp_prod);
		qede_update_tx_producer(xdp_tx);
	}

	spin_unlock(&xdp_tx->xdp_tx_lock);

	return nxmit;
}

int qede_txq_has_work(struct qede_tx_queue *txq)
{
	u16 hw_bd_cons;

	/* Tell compiler that consumer and producer can change */
	barrier();
	hw_bd_cons = le16_to_cpu(*txq->hw_cons_ptr);
	if (qed_chain_get_cons_idx(&txq->tx_pbl) == hw_bd_cons + 1)
		return 0;

	return hw_bd_cons != qed_chain_get_cons_idx(&txq->tx_pbl);
}

static void qede_xdp_tx_int(struct qede_dev *edev, struct qede_tx_queue *txq)
{
	struct sw_tx_xdp *xdp_info, *xdp_arr = txq->sw_tx_ring.xdp;
	struct device *dev = &edev->pdev->dev;
	struct xdp_frame *xdpf;
	u16 hw_bd_cons;

	hw_bd_cons = le16_to_cpu(*txq->hw_cons_ptr);
	barrier();

	while (hw_bd_cons != qed_chain_get_cons_idx(&txq->tx_pbl)) {
		xdp_info = xdp_arr + txq->sw_tx_cons;
		xdpf = xdp_info->xdpf;

		if (xdpf) {
			dma_unmap_single(dev, xdp_info->mapping, xdpf->len,
					 DMA_TO_DEVICE);
			xdp_return_frame(xdpf);

			xdp_info->xdpf = NULL;
		} else {
			dma_unmap_page(dev, xdp_info->mapping, PAGE_SIZE,
				       DMA_BIDIRECTIONAL);
			__free_page(xdp_info->page);
		}

		qed_chain_consume(&txq->tx_pbl);
		txq->sw_tx_cons = (txq->sw_tx_cons + 1) % txq->num_tx_buffers;
		txq->xmit_pkts++;
	}
}

static int qede_tx_int(struct qede_dev *edev, struct qede_tx_queue *txq)
{
	unsigned int pkts_compl = 0, bytes_compl = 0;
	struct netdev_queue *netdev_txq;
	u16 hw_bd_cons;
	int rc;

	netdev_txq = netdev_get_tx_queue(edev->ndev, txq->ndev_txq_id);

	hw_bd_cons = le16_to_cpu(*txq->hw_cons_ptr);
	barrier();

	while (hw_bd_cons != qed_chain_get_cons_idx(&txq->tx_pbl)) {
		int len = 0;

		rc = qede_free_tx_pkt(edev, txq, &len);
		if (rc) {
			DP_NOTICE(edev, "hw_bd_cons = %d, chain_cons=%d\n",
				  hw_bd_cons,
				  qed_chain_get_cons_idx(&txq->tx_pbl));
			break;
		}

		bytes_compl += len;
		pkts_compl++;
		txq->sw_tx_cons = (txq->sw_tx_cons + 1) % txq->num_tx_buffers;
		txq->xmit_pkts++;
	}

	netdev_tx_completed_queue(netdev_txq, pkts_compl, bytes_compl);

	/* Need to make the tx_bd_cons update visible to start_xmit()
	 * before checking for netif_tx_queue_stopped().  Without the
	 * memory barrier, there is a small possibility that
	 * start_xmit() will miss it and cause the queue to be stopped
	 * forever.
	 * On the other hand we need an rmb() here to ensure the proper
	 * ordering of bit testing in the following
	 * netif_tx_queue_stopped(txq) call.
	 */
	smp_mb();

	if (unlikely(netif_tx_queue_stopped(netdev_txq))) {
		/* Taking tx_lock is needed to prevent reenabling the queue
		 * while it's empty. This could have happen if rx_action() gets
		 * suspended in qede_tx_int() after the condition before
		 * netif_tx_wake_queue(), while tx_action (qede_start_xmit()):
		 *
		 * stops the queue->sees fresh tx_bd_cons->releases the queue->
		 * sends some packets consuming the whole queue again->
		 * stops the queue
		 */

		__netif_tx_lock(netdev_txq, smp_processor_id());

		if ((netif_tx_queue_stopped(netdev_txq)) &&
		    (edev->state == QEDE_STATE_OPEN) &&
		    (qed_chain_get_elem_left(&txq->tx_pbl)
		      >= (MAX_SKB_FRAGS + 1))) {
			netif_tx_wake_queue(netdev_txq);
			DP_VERBOSE(edev, NETIF_MSG_TX_DONE,
				   "Wake queue was called\n");
		}

		__netif_tx_unlock(netdev_txq);
	}

	return 0;
}

bool qede_has_rx_work(struct qede_rx_queue *rxq)
{
	u16 hw_comp_cons, sw_comp_cons;

	/* Tell compiler that status block fields can change */
	barrier();

	hw_comp_cons = le16_to_cpu(*rxq->hw_cons_ptr);
	sw_comp_cons = qed_chain_get_cons_idx(&rxq->rx_comp_ring);

	return hw_comp_cons != sw_comp_cons;
}

static inline void qede_rx_bd_ring_consume(struct qede_rx_queue *rxq)
{
	qed_chain_consume(&rxq->rx_bd_ring);
	rxq->sw_rx_cons++;
}

/* This function reuses the buffer(from an offset) from
 * consumer index to producer index in the bd ring
 */
static inline void qede_reuse_page(struct qede_rx_queue *rxq,
				   struct sw_rx_data *curr_cons)
{
	struct eth_rx_bd *rx_bd_prod = qed_chain_produce(&rxq->rx_bd_ring);
	struct sw_rx_data *curr_prod;
	dma_addr_t new_mapping;

	curr_prod = &rxq->sw_rx_ring[rxq->sw_rx_prod & NUM_RX_BDS_MAX];
	*curr_prod = *curr_cons;

	new_mapping = curr_prod->mapping + curr_prod->page_offset;

	rx_bd_prod->addr.hi = cpu_to_le32(upper_32_bits(new_mapping));
	rx_bd_prod->addr.lo = cpu_to_le32(lower_32_bits(new_mapping) +
					  rxq->rx_headroom);

	rxq->sw_rx_prod++;
	curr_cons->data = NULL;
}

/* In case of allocation failures reuse buffers
 * from consumer index to produce buffers for firmware
 */
void qede_recycle_rx_bd_ring(struct qede_rx_queue *rxq, u8 count)
{
	struct sw_rx_data *curr_cons;

	for (; count > 0; count--) {
		curr_cons = &rxq->sw_rx_ring[rxq->sw_rx_cons & NUM_RX_BDS_MAX];
		qede_reuse_page(rxq, curr_cons);
		qede_rx_bd_ring_consume(rxq);
	}
}

static inline int qede_realloc_rx_buffer(struct qede_rx_queue *rxq,
					 struct sw_rx_data *curr_cons)
{
	/* Move to the next segment in the page */
	curr_cons->page_offset += rxq->rx_buf_seg_size;

	if (curr_cons->page_offset == PAGE_SIZE) {
		if (unlikely(qede_alloc_rx_buffer(rxq, true))) {
			/* Since we failed to allocate new buffer
			 * current buffer can be used again.
			 */
			curr_cons->page_offset -= rxq->rx_buf_seg_size;

			return -ENOMEM;
		}

		dma_unmap_page(rxq->dev, curr_cons->mapping,
			       PAGE_SIZE, rxq->data_direction);
	} else {
		/* Increment refcount of the page as we don't want
		 * network stack to take the ownership of the page
		 * which can be recycled multiple times by the driver.
		 */
		page_ref_inc(curr_cons->data);
		qede_reuse_page(rxq, curr_cons);
	}

	return 0;
}

void qede_update_rx_prod(struct qede_dev *edev, struct qede_rx_queue *rxq)
{
	u16 bd_prod = qed_chain_get_prod_idx(&rxq->rx_bd_ring);
	u16 cqe_prod = qed_chain_get_prod_idx(&rxq->rx_comp_ring);
	struct eth_rx_prod_data rx_prods = {0};

	/* Update producers */
	rx_prods.bd_prod = cpu_to_le16(bd_prod);
	rx_prods.cqe_prod = cpu_to_le16(cqe_prod);

	/* Make sure that the BD and SGE data is updated before updating the
	 * producers since FW might read the BD/SGE right after the producer
	 * is updated.
	 */
	wmb();

	internal_ram_wr(rxq->hw_rxq_prod_addr, sizeof(rx_prods),
			(u32 *)&rx_prods);
}

static void qede_get_rxhash(struct sk_buff *skb, u8 bitfields, __le32 rss_hash)
{
	enum pkt_hash_types hash_type = PKT_HASH_TYPE_NONE;
	enum rss_hash_type htype;
	u32 hash = 0;

	htype = GET_FIELD(bitfields, ETH_FAST_PATH_RX_REG_CQE_RSS_HASH_TYPE);
	if (htype) {
		hash_type = ((htype == RSS_HASH_TYPE_IPV4) ||
			     (htype == RSS_HASH_TYPE_IPV6)) ?
			    PKT_HASH_TYPE_L3 : PKT_HASH_TYPE_L4;
		hash = le32_to_cpu(rss_hash);
	}
	skb_set_hash(skb, hash, hash_type);
}

static void qede_set_skb_csum(struct sk_buff *skb, u8 csum_flag)
{
	skb_checksum_none_assert(skb);

	if (csum_flag & QEDE_CSUM_UNNECESSARY)
		skb->ip_summed = CHECKSUM_UNNECESSARY;

	if (csum_flag & QEDE_TUNN_CSUM_UNNECESSARY) {
		skb->csum_level = 1;
		skb->encapsulation = 1;
	}
}

static inline void qede_skb_receive(struct qede_dev *edev,
				    struct qede_fastpath *fp,
				    struct qede_rx_queue *rxq,
				    struct sk_buff *skb, u16 vlan_tag)
{
	if (vlan_tag)
		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);

	napi_gro_receive(&fp->napi, skb);
}

static void qede_set_gro_params(struct qede_dev *edev,
				struct sk_buff *skb,
				struct eth_fast_path_rx_tpa_start_cqe *cqe)
{
	u16 parsing_flags = le16_to_cpu(cqe->pars_flags.flags);

	if (((parsing_flags >> PARSING_AND_ERR_FLAGS_L3TYPE_SHIFT) &
	    PARSING_AND_ERR_FLAGS_L3TYPE_MASK) == 2)
		skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
	else
		skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;

	skb_shinfo(skb)->gso_size = __le16_to_cpu(cqe->len_on_first_bd) -
				    cqe->header_len;
}

static int qede_fill_frag_skb(struct qede_dev *edev,
			      struct qede_rx_queue *rxq,
			      u8 tpa_agg_index, u16 len_on_bd)
{
	struct sw_rx_data *current_bd = &rxq->sw_rx_ring[rxq->sw_rx_cons &
							 NUM_RX_BDS_MAX];
	struct qede_agg_info *tpa_info = &rxq->tpa_info[tpa_agg_index];
	struct sk_buff *skb = tpa_info->skb;

	if (unlikely(tpa_info->state != QEDE_AGG_STATE_START))
		goto out;

	/* Add one frag and update the appropriate fields in the skb */
	skb_fill_page_desc(skb, tpa_info->frag_id++,
			   current_bd->data,
			   current_bd->page_offset + rxq->rx_headroom,
			   len_on_bd);

	if (unlikely(qede_realloc_rx_buffer(rxq, current_bd))) {
		/* Incr page ref count to reuse on allocation failure
		 * so that it doesn't get freed while freeing SKB.
		 */
		page_ref_inc(current_bd->data);
		goto out;
	}

	qede_rx_bd_ring_consume(rxq);

	skb->data_len += len_on_bd;
	skb->truesize += rxq->rx_buf_seg_size;
	skb->len += len_on_bd;

	return 0;

out:
	tpa_info->state = QEDE_AGG_STATE_ERROR;
	qede_recycle_rx_bd_ring(rxq, 1);

	return -ENOMEM;
}

static bool qede_tunn_exist(u16 flag)
{
	return !!(flag & (PARSING_AND_ERR_FLAGS_TUNNELEXIST_MASK <<
			  PARSING_AND_ERR_FLAGS_TUNNELEXIST_SHIFT));
}

static u8 qede_check_tunn_csum(u16 flag)
{
	u16 csum_flag = 0;
	u8 tcsum = 0;

	if (flag & (PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMWASCALCULATED_MASK <<
		    PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMWASCALCULATED_SHIFT))
		csum_flag |= PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMERROR_MASK <<
			     PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMERROR_SHIFT;

	if (flag & (PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_MASK <<
		    PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_SHIFT)) {
		csum_flag |= PARSING_AND_ERR_FLAGS_L4CHKSMERROR_MASK <<
			     PARSING_AND_ERR_FLAGS_L4CHKSMERROR_SHIFT;
		tcsum = QEDE_TUNN_CSUM_UNNECESSARY;
	}

	csum_flag |= PARSING_AND_ERR_FLAGS_TUNNELIPHDRERROR_MASK <<
		     PARSING_AND_ERR_FLAGS_TUNNELIPHDRERROR_SHIFT |
		     PARSING_AND_ERR_FLAGS_IPHDRERROR_MASK <<
		     PARSING_AND_ERR_FLAGS_IPHDRERROR_SHIFT;

	if (csum_flag & flag)
		return QEDE_CSUM_ERROR;

	return QEDE_CSUM_UNNECESSARY | tcsum;
}

static inline struct sk_buff *
qede_build_skb(struct qede_rx_queue *rxq,
	       struct sw_rx_data *bd, u16 len, u16 pad)
{
	struct sk_buff *skb;
	void *buf;

	buf = page_address(bd->data) + bd->page_offset;
	skb = build_skb(buf, rxq->rx_buf_seg_size);

	if (unlikely(!skb))
		return NULL;

	skb_reserve(skb, pad);
	skb_put(skb, len);

	return skb;
}

static struct sk_buff *
qede_tpa_rx_build_skb(struct qede_dev *edev,
		      struct qede_rx_queue *rxq,
		      struct sw_rx_data *bd, u16 len, u16 pad,
		      bool alloc_skb)
{
	struct sk_buff *skb;

	skb = qede_build_skb(rxq, bd, len, pad);
	bd->page_offset += rxq->rx_buf_seg_size;

	if (bd->page_offset == PAGE_SIZE) {
		if (unlikely(qede_alloc_rx_buffer(rxq, true))) {
			DP_NOTICE(edev,
				  "Failed to allocate RX buffer for tpa start\n");
			bd->page_offset -= rxq->rx_buf_seg_size;
			page_ref_inc(bd->data);
			dev_kfree_skb_any(skb);
			return NULL;
		}
	} else {
		page_ref_inc(bd->data);
		qede_reuse_page(rxq, bd);
	}

	/* We've consumed the first BD and prepared an SKB */
	qede_rx_bd_ring_consume(rxq);

	return skb;
}

static struct sk_buff *
qede_rx_build_skb(struct qede_dev *edev,
		  struct qede_rx_queue *rxq,
		  struct sw_rx_data *bd, u16 len, u16 pad)
{
	struct sk_buff *skb = NULL;

	/* For smaller frames still need to allocate skb, memcpy
	 * data and benefit in reusing the page segment instead of
	 * un-mapping it.
	 */
	if ((len + pad <= edev->rx_copybreak)) {
		unsigned int offset = bd->page_offset + pad;

		skb = netdev_alloc_skb(edev->ndev, QEDE_RX_HDR_SIZE);
		if (unlikely(!skb))
			return NULL;

		skb_reserve(skb, pad);
		skb_put_data(skb, page_address(bd->data) + offset, len);
		qede_reuse_page(rxq, bd);
		goto out;
	}

	skb = qede_build_skb(rxq, bd, len, pad);

	if (unlikely(qede_realloc_rx_buffer(rxq, bd))) {
		/* Incr page ref count to reuse on allocation failure so
		 * that it doesn't get freed while freeing SKB [as its
		 * already mapped there].
		 */
		page_ref_inc(bd->data);
		dev_kfree_skb_any(skb);
		return NULL;
	}
out:
	/* We've consumed the first BD and prepared an SKB */
	qede_rx_bd_ring_consume(rxq);

	return skb;
}

static void qede_tpa_start(struct qede_dev *edev,
			   struct qede_rx_queue *rxq,
			   struct eth_fast_path_rx_tpa_start_cqe *cqe)
{
	struct qede_agg_info *tpa_info = &rxq->tpa_info[cqe->tpa_agg_index];
	struct sw_rx_data *sw_rx_data_cons;
	u16 pad;

	sw_rx_data_cons = &rxq->sw_rx_ring[rxq->sw_rx_cons & NUM_RX_BDS_MAX];
	pad = cqe->placement_offset + rxq->rx_headroom;

	tpa_info->skb = qede_tpa_rx_build_skb(edev, rxq, sw_rx_data_cons,
					      le16_to_cpu(cqe->len_on_first_bd),
					      pad, false);
	tpa_info->buffer.page_offset = sw_rx_data_cons->page_offset;
	tpa_info->buffer.mapping = sw_rx_data_cons->mapping;

	if (unlikely(!tpa_info->skb)) {
		DP_NOTICE(edev, "Failed to allocate SKB for gro\n");

		/* Consume from ring but do not produce since
		 * this might be used by FW still, it will be re-used
		 * at TPA end.
		 */
		tpa_info->tpa_start_fail = true;
		qede_rx_bd_ring_consume(rxq);
		tpa_info->state = QEDE_AGG_STATE_ERROR;
		goto cons_buf;
	}

	tpa_info->frag_id = 0;
	tpa_info->state = QEDE_AGG_STATE_START;

	if ((le16_to_cpu(cqe->pars_flags.flags) >>
	     PARSING_AND_ERR_FLAGS_TAG8021QEXIST_SHIFT) &
	    PARSING_AND_ERR_FLAGS_TAG8021QEXIST_MASK)
		tpa_info->vlan_tag = le16_to_cpu(cqe->vlan_tag);
	else
		tpa_info->vlan_tag = 0;

	qede_get_rxhash(tpa_info->skb, cqe->bitfields, cqe->rss_hash);

	/* This is needed in order to enable forwarding support */
	qede_set_gro_params(edev, tpa_info->skb, cqe);

cons_buf: /* We still need to handle bd_len_list to consume buffers */
	if (likely(cqe->bw_ext_bd_len_list[0]))
		qede_fill_frag_skb(edev, rxq, cqe->tpa_agg_index,
				   le16_to_cpu(cqe->bw_ext_bd_len_list[0]));

	if (unlikely(cqe->bw_ext_bd_len_list[1])) {
		DP_ERR(edev,
		       "Unlikely - got a TPA aggregation with more than one bw_ext_bd_len_list entry in the TPA start\n");
		tpa_info->state = QEDE_AGG_STATE_ERROR;
	}
}

#ifdef CONFIG_INET
static void qede_gro_ip_csum(struct sk_buff *skb)
{
	const struct iphdr *iph = ip_hdr(skb);
	struct tcphdr *th;

	skb_set_transport_header(skb, sizeof(struct iphdr));
	th = tcp_hdr(skb);

	th->check = ~tcp_v4_check(skb->len - skb_transport_offset(skb),
				  iph->saddr, iph->daddr, 0);

	tcp_gro_complete(skb);
}

static void qede_gro_ipv6_csum(struct sk_buff *skb)
{
	struct ipv6hdr *iph = ipv6_hdr(skb);
	struct tcphdr *th;

	skb_set_transport_header(skb, sizeof(struct ipv6hdr));
	th = tcp_hdr(skb);

	th->check = ~tcp_v6_check(skb->len - skb_transport_offset(skb),
				  &iph->saddr, &iph->daddr, 0);
	tcp_gro_complete(skb);
}
#endif

static void qede_gro_receive(struct qede_dev *edev,
			     struct qede_fastpath *fp,
			     struct sk_buff *skb,
			     u16 vlan_tag)
{
	/* FW can send a single MTU sized packet from gro flow
	 * due to aggregation timeout/last segment etc. which
	 * is not expected to be a gro packet. If a skb has zero
	 * frags then simply push it in the stack as non gso skb.
	 */
	if (unlikely(!skb->data_len)) {
		skb_shinfo(skb)->gso_type = 0;
		skb_shinfo(skb)->gso_size = 0;
		goto send_skb;
	}

#ifdef CONFIG_INET
	if (skb_shinfo(skb)->gso_size) {
		skb_reset_network_header(skb);

		switch (skb->protocol) {
		case htons(ETH_P_IP):
			qede_gro_ip_csum(skb);
			break;
		case htons(ETH_P_IPV6):
			qede_gro_ipv6_csum(skb);
			break;
		default:
			DP_ERR(edev,
			       "Error: FW GRO supports only IPv4/IPv6, not 0x%04x\n",
			       ntohs(skb->protocol));
		}
	}
#endif

send_skb:
	skb_record_rx_queue(skb, fp->rxq->rxq_id);
	qede_skb_receive(edev, fp, fp->rxq, skb, vlan_tag);
}

static inline void qede_tpa_cont(struct qede_dev *edev,
				 struct qede_rx_queue *rxq,
				 struct eth_fast_path_rx_tpa_cont_cqe *cqe)
{
	int i;

	for (i = 0; cqe->len_list[i]; i++)
		qede_fill_frag_skb(edev, rxq, cqe->tpa_agg_index,
				   le16_to_cpu(cqe->len_list[i]));

	if (unlikely(i > 1))
		DP_ERR(edev,
		       "Strange - TPA cont with more than a single len_list entry\n");
}

static int qede_tpa_end(struct qede_dev *edev,
			struct qede_fastpath *fp,
			struct eth_fast_path_rx_tpa_end_cqe *cqe)
{
	struct qede_rx_queue *rxq = fp->rxq;
	struct qede_agg_info *tpa_info;
	struct sk_buff *skb;
	int i;

	tpa_info = &rxq->tpa_info[cqe->tpa_agg_index];
	skb = tpa_info->skb;

	if (tpa_info->buffer.page_offset == PAGE_SIZE)
		dma_unmap_page(rxq->dev, tpa_info->buffer.mapping,
			       PAGE_SIZE, rxq->data_direction);

	for (i = 0; cqe->len_list[i]; i++)
		qede_fill_frag_skb(edev, rxq, cqe->tpa_agg_index,
				   le16_to_cpu(cqe->len_list[i]));
	if (unlikely(i > 1))
		DP_ERR(edev,
		       "Strange - TPA emd with more than a single len_list entry\n");

	if (unlikely(tpa_info->state != QEDE_AGG_STATE_START))
		goto err;

	/* Sanity */
	if (unlikely(cqe->num_of_bds != tpa_info->frag_id + 1))
		DP_ERR(edev,
		       "Strange - TPA had %02x BDs, but SKB has only %d frags\n",
		       cqe->num_of_bds, tpa_info->frag_id);
	if (unlikely(skb->len != le16_to_cpu(cqe->total_packet_len)))
		DP_ERR(edev,
		       "Strange - total packet len [cqe] is %4x but SKB has len %04x\n",
		       le16_to_cpu(cqe->total_packet_len), skb->len);

	/* Finalize the SKB */
	skb->protocol = eth_type_trans(skb, edev->ndev);
	skb->ip_summed = CHECKSUM_UNNECESSARY;

	/* tcp_gro_complete() will copy NAPI_GRO_CB(skb)->count
	 * to skb_shinfo(skb)->gso_segs
	 */
	NAPI_GRO_CB(skb)->count = le16_to_cpu(cqe->num_of_coalesced_segs);

	qede_gro_receive(edev, fp, skb, tpa_info->vlan_tag);

	tpa_info->state = QEDE_AGG_STATE_NONE;

	return 1;
err:
	tpa_info->state = QEDE_AGG_STATE_NONE;

	if (tpa_info->tpa_start_fail) {
		qede_reuse_page(rxq, &tpa_info->buffer);
		tpa_info->tpa_start_fail = false;
	}

	dev_kfree_skb_any(tpa_info->skb);
	tpa_info->skb = NULL;
	return 0;
}

static u8 qede_check_notunn_csum(u16 flag)
{
	u16 csum_flag = 0;
	u8 csum = 0;

	if (flag & (PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_MASK <<
		    PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_SHIFT)) {
		csum_flag |= PARSING_AND_ERR_FLAGS_L4CHKSMERROR_MASK <<
			     PARSING_AND_ERR_FLAGS_L4CHKSMERROR_SHIFT;
		csum = QEDE_CSUM_UNNECESSARY;
	}

	csum_flag |= PARSING_AND_ERR_FLAGS_IPHDRERROR_MASK <<
		     PARSING_AND_ERR_FLAGS_IPHDRERROR_SHIFT;

	if (csum_flag & flag)
		return QEDE_CSUM_ERROR;

	return csum;
}

static u8 qede_check_csum(u16 flag)
{
	if (!qede_tunn_exist(flag))
		return qede_check_notunn_csum(flag);
	else
		return qede_check_tunn_csum(flag);
}

static bool qede_pkt_is_ip_fragmented(struct eth_fast_path_rx_reg_cqe *cqe,
				      u16 flag)
{
	u8 tun_pars_flg = cqe->tunnel_pars_flags.flags;

	if ((tun_pars_flg & (ETH_TUNNEL_PARSING_FLAGS_IPV4_FRAGMENT_MASK <<
			     ETH_TUNNEL_PARSING_FLAGS_IPV4_FRAGMENT_SHIFT)) ||
	    (flag & (PARSING_AND_ERR_FLAGS_IPV4FRAG_MASK <<
		     PARSING_AND_ERR_FLAGS_IPV4FRAG_SHIFT)))
		return true;

	return false;
}

/* Return true iff packet is to be passed to stack */
static bool qede_rx_xdp(struct qede_dev *edev,
			struct qede_fastpath *fp,
			struct qede_rx_queue *rxq,
			struct bpf_prog *prog,
			struct sw_rx_data *bd,
			struct eth_fast_path_rx_reg_cqe *cqe,
			u16 *data_offset, u16 *len)
{
	struct xdp_buff xdp;
	enum xdp_action act;

	xdp_init_buff(&xdp, rxq->rx_buf_seg_size, &rxq->xdp_rxq);
	xdp_prepare_buff(&xdp, page_address(bd->data), *data_offset,
			 *len, false);

	act = bpf_prog_run_xdp(prog, &xdp);

	/* Recalculate, as XDP might have changed the headers */
	*data_offset = xdp.data - xdp.data_hard_start;
	*len = xdp.data_end - xdp.data;

	if (act == XDP_PASS)
		return true;

	/* Count number of packets not to be passed to stack */
	rxq->xdp_no_pass++;

	switch (act) {
	case XDP_TX:
		/* We need the replacement buffer before transmit. */
		if (unlikely(qede_alloc_rx_buffer(rxq, true))) {
			qede_recycle_rx_bd_ring(rxq, 1);

			trace_xdp_exception(edev->ndev, prog, act);
			break;
		}

		/* Now if there's a transmission problem, we'd still have to
		 * throw current buffer, as replacement was already allocated.
		 */
		if (unlikely(qede_xdp_xmit(fp->xdp_tx, bd->mapping,
					   *data_offset, *len, bd->data,
					   NULL))) {
			dma_unmap_page(rxq->dev, bd->mapping, PAGE_SIZE,
				       rxq->data_direction);
			__free_page(bd->data);

			trace_xdp_exception(edev->ndev, prog, act);
		} else {
			dma_sync_single_for_device(rxq->dev,
						   bd->mapping + *data_offset,
						   *len, rxq->data_direction);
			fp->xdp_xmit |= QEDE_XDP_TX;
		}

		/* Regardless, we've consumed an Rx BD */
		qede_rx_bd_ring_consume(rxq);
		break;
	case XDP_REDIRECT:
		/* We need the replacement buffer before transmit. */
		if (unlikely(qede_alloc_rx_buffer(rxq, true))) {
			qede_recycle_rx_bd_ring(rxq, 1);

			trace_xdp_exception(edev->ndev, prog, act);
			break;
		}

		dma_unmap_page(rxq->dev, bd->mapping, PAGE_SIZE,
			       rxq->data_direction);

		if (unlikely(xdp_do_redirect(edev->ndev, &xdp, prog)))
			DP_NOTICE(edev, "Failed to redirect the packet\n");
		else
			fp->xdp_xmit |= QEDE_XDP_REDIRECT;

		qede_rx_bd_ring_consume(rxq);
		break;
	default:
		bpf_warn_invalid_xdp_action(act);
		fallthrough;
	case XDP_ABORTED:
		trace_xdp_exception(edev->ndev, prog, act);
		fallthrough;
	case XDP_DROP:
		qede_recycle_rx_bd_ring(rxq, cqe->bd_num);
	}

	return false;
}

static int qede_rx_build_jumbo(struct qede_dev *edev,
			       struct qede_rx_queue *rxq,
			       struct sk_buff *skb,
			       struct eth_fast_path_rx_reg_cqe *cqe,
			       u16 first_bd_len)
{
	u16 pkt_len = le16_to_cpu(cqe->pkt_len);
	struct sw_rx_data *bd;
	u16 bd_cons_idx;
	u8 num_frags;

	pkt_len -= first_bd_len;

	/* We've already used one BD for the SKB. Now take care of the rest */
	for (num_frags = cqe->bd_num - 1; num_frags > 0; num_frags--) {
		u16 cur_size = pkt_len > rxq->rx_buf_size ? rxq->rx_buf_size :
		    pkt_len;

		if (unlikely(!cur_size)) {
			DP_ERR(edev,
			       "Still got %d BDs for mapping jumbo, but length became 0\n",
			       num_frags);
			goto out;
		}

		/* We need a replacement buffer for each BD */
		if (unlikely(qede_alloc_rx_buffer(rxq, true)))
			goto out;

		/* Now that we've allocated the replacement buffer,
		 * we can safely consume the next BD and map it to the SKB.
		 */
		bd_cons_idx = rxq->sw_rx_cons & NUM_RX_BDS_MAX;
		bd = &rxq->sw_rx_ring[bd_cons_idx];
		qede_rx_bd_ring_consume(rxq);

		dma_unmap_page(rxq->dev, bd->mapping,
			       PAGE_SIZE, DMA_FROM_DEVICE);

		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, bd->data,
				rxq->rx_headroom, cur_size, PAGE_SIZE);

		pkt_len -= cur_size;
	}

	if (unlikely(pkt_len))
		DP_ERR(edev,
		       "Mapped all BDs of jumbo, but still have %d bytes\n",
		       pkt_len);

out:
	return num_frags;
}

static int qede_rx_process_tpa_cqe(struct qede_dev *edev,
				   struct qede_fastpath *fp,
				   struct qede_rx_queue *rxq,
				   union eth_rx_cqe *cqe,
				   enum eth_rx_cqe_type type)
{
	switch (type) {
	case ETH_RX_CQE_TYPE_TPA_START:
		qede_tpa_start(edev, rxq, &cqe->fast_path_tpa_start);
		return 0;
	case ETH_RX_CQE_TYPE_TPA_CONT:
		qede_tpa_cont(edev, rxq, &cqe->fast_path_tpa_cont);
		return 0;
	case ETH_RX_CQE_TYPE_TPA_END:
		return qede_tpa_end(edev, fp, &cqe->fast_path_tpa_end);
	default:
		return 0;
	}
}

static int qede_rx_process_cqe(struct qede_dev *edev,
			       struct qede_fastpath *fp,
			       struct qede_rx_queue *rxq)
{
	struct bpf_prog *xdp_prog = READ_ONCE(rxq->xdp_prog);
	struct eth_fast_path_rx_reg_cqe *fp_cqe;
	u16 len, pad, bd_cons_idx, parse_flag;
	enum eth_rx_cqe_type cqe_type;
	union eth_rx_cqe *cqe;
	struct sw_rx_data *bd;
	struct sk_buff *skb;
	__le16 flags;
	u8 csum_flag;

	/* Get the CQE from the completion ring */
	cqe = (union eth_rx_cqe *)qed_chain_consume(&rxq->rx_comp_ring);
	cqe_type = cqe->fast_path_regular.type;

	/* Process an unlikely slowpath event */
	if (unlikely(cqe_type == ETH_RX_CQE_TYPE_SLOW_PATH)) {
		struct eth_slow_path_rx_cqe *sp_cqe;

		sp_cqe = (struct eth_slow_path_rx_cqe *)cqe;
		edev->ops->eth_cqe_completion(edev->cdev, fp->id, sp_cqe);
		return 0;
	}

	/* Handle TPA cqes */
	if (cqe_type != ETH_RX_CQE_TYPE_REGULAR)
		return qede_rx_process_tpa_cqe(edev, fp, rxq, cqe, cqe_type);

	/* Get the data from the SW ring; Consume it only after it's evident
	 * we wouldn't recycle it.
	 */
	bd_cons_idx = rxq->sw_rx_cons & NUM_RX_BDS_MAX;
	bd = &rxq->sw_rx_ring[bd_cons_idx];

	fp_cqe = &cqe->fast_path_regular;
	len = le16_to_cpu(fp_cqe->len_on_first_bd);
	pad = fp_cqe->placement_offset + rxq->rx_headroom;

	/* Run eBPF program if one is attached */
	if (xdp_prog)
		if (!qede_rx_xdp(edev, fp, rxq, xdp_prog, bd, fp_cqe,
				 &pad, &len))
			return 0;

	/* If this is an error packet then drop it */
	flags = cqe->fast_path_regular.pars_flags.flags;
	parse_flag = le16_to_cpu(flags);

	csum_flag = qede_check_csum(parse_flag);
	if (unlikely(csum_flag == QEDE_CSUM_ERROR)) {
		if (qede_pkt_is_ip_fragmented(fp_cqe, parse_flag))
			rxq->rx_ip_frags++;
		else
			rxq->rx_hw_errors++;
	}

	/* Basic validation passed; Need to prepare an SKB. This would also
	 * guarantee to finally consume the first BD upon success.
	 */
	skb = qede_rx_build_skb(edev, rxq, bd, len, pad);
	if (!skb) {
		rxq->rx_alloc_errors++;
		qede_recycle_rx_bd_ring(rxq, fp_cqe->bd_num);
		return 0;
	}

	/* In case of Jumbo packet, several PAGE_SIZEd buffers will be pointed
	 * by a single cqe.
	 */
	if (fp_cqe->bd_num > 1) {
		u16 unmapped_frags = qede_rx_build_jumbo(edev, rxq, skb,
							 fp_cqe, len);

		if (unlikely(unmapped_frags > 0)) {
			qede_recycle_rx_bd_ring(rxq, unmapped_frags);
			dev_kfree_skb_any(skb);
			return 0;
		}
	}

	/* The SKB contains all the data. Now prepare meta-magic */
	skb->protocol = eth_type_trans(skb, edev->ndev);
	qede_get_rxhash(skb, fp_cqe->bitfields, fp_cqe->rss_hash);
	qede_set_skb_csum(skb, csum_flag);
	skb_record_rx_queue(skb, rxq->rxq_id);
	qede_ptp_record_rx_ts(edev, cqe, skb);

	/* SKB is prepared - pass it to stack */
	qede_skb_receive(edev, fp, rxq, skb, le16_to_cpu(fp_cqe->vlan_tag));

	return 1;
}

static int qede_rx_int(struct qede_fastpath *fp, int budget)
{
	struct qede_rx_queue *rxq = fp->rxq;
	struct qede_dev *edev = fp->edev;
	int work_done = 0, rcv_pkts = 0;
	u16 hw_comp_cons, sw_comp_cons;

	hw_comp_cons = le16_to_cpu(*rxq->hw_cons_ptr);
	sw_comp_cons = qed_chain_get_cons_idx(&rxq->rx_comp_ring);

	/* Memory barrier to prevent the CPU from doing speculative reads of CQE
	 * / BD in the while-loop before reading hw_comp_cons. If the CQE is
	 * read before it is written by FW, then FW writes CQE and SB, and then
	 * the CPU reads the hw_comp_cons, it will use an old CQE.
	 */
	rmb();

	/* Loop to complete all indicated BDs */
	while ((sw_comp_cons != hw_comp_cons) && (work_done < budget)) {
		rcv_pkts += qede_rx_process_cqe(edev, fp, rxq);
		qed_chain_recycle_consumed(&rxq->rx_comp_ring);
		sw_comp_cons = qed_chain_get_cons_idx(&rxq->rx_comp_ring);
		work_done++;
	}

	rxq->rcv_pkts += rcv_pkts;

	/* Allocate replacement buffers */
	while (rxq->num_rx_buffers - rxq->filled_buffers)
		if (qede_alloc_rx_buffer(rxq, false))
			break;

	/* Update producers */
	qede_update_rx_prod(edev, rxq);

	return work_done;
}

static bool qede_poll_is_more_work(struct qede_fastpath *fp)
{
	qed_sb_update_sb_idx(fp->sb_info);

	/* *_has_*_work() reads the status block, thus we need to ensure that
	 * status block indices have been actually read (qed_sb_update_sb_idx)
	 * prior to this check (*_has_*_work) so that we won't write the
	 * "newer" value of the status block to HW (if there was a DMA right
	 * after qede_has_rx_work and if there is no rmb, the memory reading
	 * (qed_sb_update_sb_idx) may be postponed to right before *_ack_sb).
	 * In this case there will never be another interrupt until there is
	 * another update of the status block, while there is still unhandled
	 * work.
	 */
	rmb();

	if (likely(fp->type & QEDE_FASTPATH_RX))
		if (qede_has_rx_work(fp->rxq))
			return true;

	if (fp->type & QEDE_FASTPATH_XDP)
		if (qede_txq_has_work(fp->xdp_tx))
			return true;

	if (likely(fp->type & QEDE_FASTPATH_TX)) {
		int cos;

		for_each_cos_in_txq(fp->edev, cos) {
			if (qede_txq_has_work(&fp->txq[cos]))
				return true;
		}
	}

	return false;
}

/*********************
 * NDO & API related *
 *********************/
int qede_poll(struct napi_struct *napi, int budget)
{
	struct qede_fastpath *fp = container_of(napi, struct qede_fastpath,
						napi);
	struct qede_dev *edev = fp->edev;
	int rx_work_done = 0;
	u16 xdp_prod;

	fp->xdp_xmit = 0;

	if (likely(fp->type & QEDE_FASTPATH_TX)) {
		int cos;

		for_each_cos_in_txq(fp->edev, cos) {
			if (qede_txq_has_work(&fp->txq[cos]))
				qede_tx_int(edev, &fp->txq[cos]);
		}
	}

	if ((fp->type & QEDE_FASTPATH_XDP) && qede_txq_has_work(fp->xdp_tx))
		qede_xdp_tx_int(edev, fp->xdp_tx);

	rx_work_done = (likely(fp->type & QEDE_FASTPATH_RX) &&
			qede_has_rx_work(fp->rxq)) ?
			qede_rx_int(fp, budget) : 0;
	/* Handle case where we are called by netpoll with a budget of 0 */
	if (rx_work_done < budget || !budget) {
		if (!qede_poll_is_more_work(fp)) {
			napi_complete_done(napi, rx_work_done);

			/* Update and reenable interrupts */
			qed_sb_ack(fp->sb_info, IGU_INT_ENABLE, 1);
		} else {
			rx_work_done = budget;
		}
	}

	if (fp->xdp_xmit & QEDE_XDP_TX) {
		xdp_prod = qed_chain_get_prod_idx(&fp->xdp_tx->tx_pbl);

		fp->xdp_tx->tx_db.data.bd_prod = cpu_to_le16(xdp_prod);
		qede_update_tx_producer(fp->xdp_tx);
	}

	if (fp->xdp_xmit & QEDE_XDP_REDIRECT)
		xdp_do_flush_map();

	return rx_work_done;
}

irqreturn_t qede_msix_fp_int(int irq, void *fp_cookie)
{
	struct qede_fastpath *fp = fp_cookie;

	qed_sb_ack(fp->sb_info, IGU_INT_DISABLE, 0 /*do not update*/);

	napi_schedule_irqoff(&fp->napi);
	return IRQ_HANDLED;
}

/* Main transmit function */
netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
	struct qede_dev *edev = netdev_priv(ndev);
	struct netdev_queue *netdev_txq;
	struct qede_tx_queue *txq;
	struct eth_tx_1st_bd *first_bd;
	struct eth_tx_2nd_bd *second_bd = NULL;
	struct eth_tx_3rd_bd *third_bd = NULL;
	struct eth_tx_bd *tx_data_bd = NULL;
	u16 txq_index, val = 0;
	u8 nbd = 0;
	dma_addr_t mapping;
	int rc, frag_idx = 0, ipv6_ext = 0;
	u8 xmit_type;
	u16 idx;
	u16 hlen;
	bool data_split = false;

	/* Get tx-queue context and netdev index */
	txq_index = skb_get_queue_mapping(skb);
	WARN_ON(txq_index >= QEDE_TSS_COUNT(edev) * edev->dev_info.num_tc);
	txq = QEDE_NDEV_TXQ_ID_TO_TXQ(edev, txq_index);
	netdev_txq = netdev_get_tx_queue(ndev, txq_index);

	WARN_ON(qed_chain_get_elem_left(&txq->tx_pbl) < (MAX_SKB_FRAGS + 1));

	xmit_type = qede_xmit_type(skb, &ipv6_ext);

#if ((MAX_SKB_FRAGS + 2) > ETH_TX_MAX_BDS_PER_NON_LSO_PACKET)
	if (qede_pkt_req_lin(skb, xmit_type)) {
		if (skb_linearize(skb)) {
			txq->tx_mem_alloc_err++;

			dev_kfree_skb_any(skb);
			return NETDEV_TX_OK;
		}
	}
#endif

	/* Fill the entry in the SW ring and the BDs in the FW ring */
	idx = txq->sw_tx_prod;
	txq->sw_tx_ring.skbs[idx].skb = skb;
	first_bd = (struct eth_tx_1st_bd *)
		   qed_chain_produce(&txq->tx_pbl);
	memset(first_bd, 0, sizeof(*first_bd));
	first_bd->data.bd_flags.bitfields =
		1 << ETH_TX_1ST_BD_FLAGS_START_BD_SHIFT;

	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
		qede_ptp_tx_ts(edev, skb);

	/* Map skb linear data for DMA and set in the first BD */
	mapping = dma_map_single(txq->dev, skb->data,
				 skb_headlen(skb), DMA_TO_DEVICE);
	if (unlikely(dma_mapping_error(txq->dev, mapping))) {
		DP_NOTICE(edev, "SKB mapping failed\n");
		qede_free_failed_tx_pkt(txq, first_bd, 0, false);
		qede_update_tx_producer(txq);
		return NETDEV_TX_OK;
	}
	nbd++;
	BD_SET_UNMAP_ADDR_LEN(first_bd, mapping, skb_headlen(skb));

	/* In case there is IPv6 with extension headers or LSO we need 2nd and
	 * 3rd BDs.
	 */
	if (unlikely((xmit_type & XMIT_LSO) | ipv6_ext)) {
		second_bd = (struct eth_tx_2nd_bd *)
			qed_chain_produce(&txq->tx_pbl);
		memset(second_bd, 0, sizeof(*second_bd));

		nbd++;
		third_bd = (struct eth_tx_3rd_bd *)
			qed_chain_produce(&txq->tx_pbl);
		memset(third_bd, 0, sizeof(*third_bd));

		nbd++;
		/* We need to fill in additional data in second_bd... */
		tx_data_bd = (struct eth_tx_bd *)second_bd;
	}

	if (skb_vlan_tag_present(skb)) {
		first_bd->data.vlan = cpu_to_le16(skb_vlan_tag_get(skb));
		first_bd->data.bd_flags.bitfields |=
			1 << ETH_TX_1ST_BD_FLAGS_VLAN_INSERTION_SHIFT;
	}

	/* Fill the parsing flags & params according to the requested offload */
	if (xmit_type & XMIT_L4_CSUM) {
		/* We don't re-calculate IP checksum as it is already done by
		 * the upper stack
		 */
		first_bd->data.bd_flags.bitfields |=
			1 << ETH_TX_1ST_BD_FLAGS_L4_CSUM_SHIFT;

		if (xmit_type & XMIT_ENC) {
			first_bd->data.bd_flags.bitfields |=
				1 << ETH_TX_1ST_BD_FLAGS_IP_CSUM_SHIFT;

			val |= (1 << ETH_TX_DATA_1ST_BD_TUNN_FLAG_SHIFT);
		}

		/* Legacy FW had flipped behavior in regard to this bit -
		 * I.e., needed to set to prevent FW from touching encapsulated
		 * packets when it didn't need to.
		 */
		if (unlikely(txq->is_legacy))
			val ^= (1 << ETH_TX_DATA_1ST_BD_TUNN_FLAG_SHIFT);

		/* If the packet is IPv6 with extension header, indicate that
		 * to FW and pass few params, since the device cracker doesn't
		 * support parsing IPv6 with extension header/s.
		 */
		if (unlikely(ipv6_ext))
			qede_set_params_for_ipv6_ext(skb, second_bd, third_bd);
	}

	if (xmit_type & XMIT_LSO) {
		first_bd->data.bd_flags.bitfields |=
			(1 << ETH_TX_1ST_BD_FLAGS_LSO_SHIFT);
		third_bd->data.lso_mss =
			cpu_to_le16(skb_shinfo(skb)->gso_size);

		if (unlikely(xmit_type & XMIT_ENC)) {
			first_bd->data.bd_flags.bitfields |=
				1 << ETH_TX_1ST_BD_FLAGS_TUNN_IP_CSUM_SHIFT;

			if (xmit_type & XMIT_ENC_GSO_L4_CSUM) {
				u8 tmp = ETH_TX_1ST_BD_FLAGS_TUNN_L4_CSUM_SHIFT;

				first_bd->data.bd_flags.bitfields |= 1 << tmp;
			}
			hlen = qede_get_skb_hlen(skb, true);
		} else {
			first_bd->data.bd_flags.bitfields |=
				1 << ETH_TX_1ST_BD_FLAGS_IP_CSUM_SHIFT;
			hlen = qede_get_skb_hlen(skb, false);
		}

		/* @@@TBD - if will not be removed need to check */
		third_bd->data.bitfields |=
			cpu_to_le16(1 << ETH_TX_DATA_3RD_BD_HDR_NBD_SHIFT);

		/* Make life easier for FW guys who can't deal with header and
		 * data on same BD. If we need to split, use the second bd...
		 */
		if (unlikely(skb_headlen(skb) > hlen)) {
			DP_VERBOSE(edev, NETIF_MSG_TX_QUEUED,
				   "TSO split header size is %d (%x:%x)\n",
				   first_bd->nbytes, first_bd->addr.hi,
				   first_bd->addr.lo);

			mapping = HILO_U64(le32_to_cpu(first_bd->addr.hi),
					   le32_to_cpu(first_bd->addr.lo)) +
					   hlen;

			BD_SET_UNMAP_ADDR_LEN(tx_data_bd, mapping,
					      le16_to_cpu(first_bd->nbytes) -
					      hlen);

			/* this marks the BD as one that has no
			 * individual mapping
			 */
			txq->sw_tx_ring.skbs[idx].flags |= QEDE_TSO_SPLIT_BD;

			first_bd->nbytes = cpu_to_le16(hlen);

			tx_data_bd = (struct eth_tx_bd *)third_bd;
			data_split = true;
		}
	} else {
		if (unlikely(skb->len > ETH_TX_MAX_NON_LSO_PKT_LEN)) {
			DP_ERR(edev, "Unexpected non LSO skb length = 0x%x\n", skb->len);
			qede_free_failed_tx_pkt(txq, first_bd, 0, false);
			qede_update_tx_producer(txq);
			return NETDEV_TX_OK;
		}

		val |= ((skb->len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK) <<
			 ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT);
	}

	first_bd->data.bitfields = cpu_to_le16(val);

	/* Handle fragmented skb */
	/* special handle for frags inside 2nd and 3rd bds.. */
	while (tx_data_bd && frag_idx < skb_shinfo(skb)->nr_frags) {
		rc = map_frag_to_bd(txq,
				    &skb_shinfo(skb)->frags[frag_idx],
				    tx_data_bd);
		if (rc) {
			qede_free_failed_tx_pkt(txq, first_bd, nbd, data_split);
			qede_update_tx_producer(txq);
			return NETDEV_TX_OK;
		}

		if (tx_data_bd == (struct eth_tx_bd *)second_bd)
			tx_data_bd = (struct eth_tx_bd *)third_bd;
		else
			tx_data_bd = NULL;

		frag_idx++;
	}

	/* map last frags into 4th, 5th .... */
	for (; frag_idx < skb_shinfo(skb)->nr_frags; frag_idx++, nbd++) {
		tx_data_bd = (struct eth_tx_bd *)
			     qed_chain_produce(&txq->tx_pbl);

		memset(tx_data_bd, 0, sizeof(*tx_data_bd));

		rc = map_frag_to_bd(txq,
				    &skb_shinfo(skb)->frags[frag_idx],
				    tx_data_bd);
		if (rc) {
			qede_free_failed_tx_pkt(txq, first_bd, nbd, data_split);
			qede_update_tx_producer(txq);
			return NETDEV_TX_OK;
		}
	}

	/* update the first BD with the actual num BDs */
	first_bd->data.nbds = nbd;

	netdev_tx_sent_queue(netdev_txq, skb->len);

	skb_tx_timestamp(skb);

	/* Advance packet producer only before sending the packet since mapping
	 * of pages may fail.
	 */
	txq->sw_tx_prod = (txq->sw_tx_prod + 1) % txq->num_tx_buffers;

	/* 'next page' entries are counted in the producer value */
	txq->tx_db.data.bd_prod =
		cpu_to_le16(qed_chain_get_prod_idx(&txq->tx_pbl));

	if (!netdev_xmit_more() || netif_xmit_stopped(netdev_txq))
		qede_update_tx_producer(txq);

	if (unlikely(qed_chain_get_elem_left(&txq->tx_pbl)
		      < (MAX_SKB_FRAGS + 1))) {
		if (netdev_xmit_more())
			qede_update_tx_producer(txq);

		netif_tx_stop_queue(netdev_txq);
		txq->stopped_cnt++;
		DP_VERBOSE(edev, NETIF_MSG_TX_QUEUED,
			   "Stop queue was called\n");
		/* paired memory barrier is in qede_tx_int(), we have to keep
		 * ordering of set_bit() in netif_tx_stop_queue() and read of
		 * fp->bd_tx_cons
		 */
		smp_mb();

		if ((qed_chain_get_elem_left(&txq->tx_pbl) >=
		     (MAX_SKB_FRAGS + 1)) &&
		    (edev->state == QEDE_STATE_OPEN)) {
			netif_tx_wake_queue(netdev_txq);
			DP_VERBOSE(edev, NETIF_MSG_TX_QUEUED,
				   "Wake queue was called\n");
		}
	}

	return NETDEV_TX_OK;
}

u16 qede_select_queue(struct net_device *dev, struct sk_buff *skb,
		      struct net_device *sb_dev)
{
	struct qede_dev *edev = netdev_priv(dev);
	int total_txq;

	total_txq = QEDE_TSS_COUNT(edev) * edev->dev_info.num_tc;

	return QEDE_TSS_COUNT(edev) ?
		netdev_pick_tx(dev, skb, NULL) % total_txq :  0;
}

/* 8B udp header + 8B base tunnel header + 32B option length */
#define QEDE_MAX_TUN_HDR_LEN 48

netdev_features_t qede_features_check(struct sk_buff *skb,
				      struct net_device *dev,
				      netdev_features_t features)
{
	if (skb->encapsulation) {
		u8 l4_proto = 0;

		switch (vlan_get_protocol(skb)) {
		case htons(ETH_P_IP):
			l4_proto = ip_hdr(skb)->protocol;
			break;
		case htons(ETH_P_IPV6):
			l4_proto = ipv6_hdr(skb)->nexthdr;
			break;
		default:
			return features;
		}

		/* Disable offloads for geneve tunnels, as HW can't parse
		 * the geneve header which has option length greater than 32b
		 * and disable offloads for the ports which are not offloaded.
		 */
		if (l4_proto == IPPROTO_UDP) {
			struct qede_dev *edev = netdev_priv(dev);
			u16 hdrlen, vxln_port, gnv_port;

			hdrlen = QEDE_MAX_TUN_HDR_LEN;
			vxln_port = edev->vxlan_dst_port;
			gnv_port = edev->geneve_dst_port;

			if ((skb_inner_mac_header(skb) -
			     skb_transport_header(skb)) > hdrlen ||
			     (ntohs(udp_hdr(skb)->dest) != vxln_port &&
			      ntohs(udp_hdr(skb)->dest) != gnv_port))
				return features & ~(NETIF_F_CSUM_MASK |
						    NETIF_F_GSO_MASK);
		} else if (l4_proto == IPPROTO_IPIP) {
			/* IPIP tunnels are unknown to the device or at least unsupported natively,
			 * offloads for them can't be done trivially, so disable them for such skb.
			 */
			return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
		}
	}

	return features;
}
