// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/* Google virtual Ethernet (gve) driver
 *
 * Copyright (C) 2015-2021 Google, Inc.
 */

#include "gve.h"
#include "gve_adminq.h"
#include "gve_utils.h"
#include <linux/etherdevice.h>

static void gve_rx_free_buffer(struct device *dev,
			       struct gve_rx_slot_page_info *page_info,
			       union gve_rx_data_slot *data_slot)
{
	dma_addr_t dma = (dma_addr_t)(be64_to_cpu(data_slot->addr) &
				      GVE_DATA_SLOT_ADDR_PAGE_MASK);

	page_ref_sub(page_info->page, page_info->pagecnt_bias - 1);
	gve_free_page(dev, page_info->page, dma, DMA_FROM_DEVICE);
}

static void gve_rx_unfill_pages(struct gve_priv *priv, struct gve_rx_ring *rx)
{
	u32 slots = rx->mask + 1;
	int i;

	if (rx->data.raw_addressing) {
		for (i = 0; i < slots; i++)
			gve_rx_free_buffer(&priv->pdev->dev, &rx->data.page_info[i],
					   &rx->data.data_ring[i]);
	} else {
		for (i = 0; i < slots; i++)
			page_ref_sub(rx->data.page_info[i].page,
				     rx->data.page_info[i].pagecnt_bias - 1);
		gve_unassign_qpl(priv, rx->data.qpl->id);
		rx->data.qpl = NULL;

		for (i = 0; i < rx->qpl_copy_pool_mask + 1; i++) {
			page_ref_sub(rx->qpl_copy_pool[i].page,
				     rx->qpl_copy_pool[i].pagecnt_bias - 1);
			put_page(rx->qpl_copy_pool[i].page);
		}
	}
	kvfree(rx->data.page_info);
	rx->data.page_info = NULL;
}

static void gve_rx_free_ring(struct gve_priv *priv, int idx)
{
	struct gve_rx_ring *rx = &priv->rx[idx];
	struct device *dev = &priv->pdev->dev;
	u32 slots = rx->mask + 1;
	size_t bytes;

	gve_rx_remove_from_block(priv, idx);

	bytes = sizeof(struct gve_rx_desc) * priv->rx_desc_cnt;
	dma_free_coherent(dev, bytes, rx->desc.desc_ring, rx->desc.bus);
	rx->desc.desc_ring = NULL;

	dma_free_coherent(dev, sizeof(*rx->q_resources),
			  rx->q_resources, rx->q_resources_bus);
	rx->q_resources = NULL;

	gve_rx_unfill_pages(priv, rx);

	bytes = sizeof(*rx->data.data_ring) * slots;
	dma_free_coherent(dev, bytes, rx->data.data_ring,
			  rx->data.data_bus);
	rx->data.data_ring = NULL;

	kvfree(rx->qpl_copy_pool);
	rx->qpl_copy_pool = NULL;

	netif_dbg(priv, drv, priv->dev, "freed rx ring %d\n", idx);
}

static void gve_setup_rx_buffer(struct gve_rx_slot_page_info *page_info,
			     dma_addr_t addr, struct page *page, __be64 *slot_addr)
{
	page_info->page = page;
	page_info->page_offset = 0;
	page_info->page_address = page_address(page);
	*slot_addr = cpu_to_be64(addr);
	/* The page already has 1 ref */
	page_ref_add(page, INT_MAX - 1);
	page_info->pagecnt_bias = INT_MAX;
}

static int gve_rx_alloc_buffer(struct gve_priv *priv, struct device *dev,
			       struct gve_rx_slot_page_info *page_info,
			       union gve_rx_data_slot *data_slot)
{
	struct page *page;
	dma_addr_t dma;
	int err;

	err = gve_alloc_page(priv, dev, &page, &dma, DMA_FROM_DEVICE,
			     GFP_ATOMIC);
	if (err)
		return err;

	gve_setup_rx_buffer(page_info, dma, page, &data_slot->addr);
	return 0;
}

static int gve_prefill_rx_pages(struct gve_rx_ring *rx)
{
	struct gve_priv *priv = rx->gve;
	u32 slots;
	int err;
	int i;
	int j;

	/* Allocate one page per Rx queue slot. Each page is split into two
	 * packet buffers, when possible we "page flip" between the two.
	 */
	slots = rx->mask + 1;

	rx->data.page_info = kvzalloc(slots *
				      sizeof(*rx->data.page_info), GFP_KERNEL);
	if (!rx->data.page_info)
		return -ENOMEM;

	if (!rx->data.raw_addressing) {
		rx->data.qpl = gve_assign_rx_qpl(priv);
		if (!rx->data.qpl) {
			kvfree(rx->data.page_info);
			rx->data.page_info = NULL;
			return -ENOMEM;
		}
	}
	for (i = 0; i < slots; i++) {
		if (!rx->data.raw_addressing) {
			struct page *page = rx->data.qpl->pages[i];
			dma_addr_t addr = i * PAGE_SIZE;

			gve_setup_rx_buffer(&rx->data.page_info[i], addr, page,
					    &rx->data.data_ring[i].qpl_offset);
			continue;
		}
		err = gve_rx_alloc_buffer(priv, &priv->pdev->dev, &rx->data.page_info[i],
					  &rx->data.data_ring[i]);
		if (err)
			goto alloc_err;
	}

	if (!rx->data.raw_addressing) {
		for (j = 0; j < rx->qpl_copy_pool_mask + 1; j++) {
			struct page *page = alloc_page(GFP_KERNEL);

			if (!page) {
				err = -ENOMEM;
				goto alloc_err_qpl;
			}

			rx->qpl_copy_pool[j].page = page;
			rx->qpl_copy_pool[j].page_offset = 0;
			rx->qpl_copy_pool[j].page_address = page_address(page);

			/* The page already has 1 ref. */
			page_ref_add(page, INT_MAX - 1);
			rx->qpl_copy_pool[j].pagecnt_bias = INT_MAX;
		}
	}

	return slots;

alloc_err_qpl:
	while (j--) {
		page_ref_sub(rx->qpl_copy_pool[j].page,
			     rx->qpl_copy_pool[j].pagecnt_bias - 1);
		put_page(rx->qpl_copy_pool[j].page);
	}
alloc_err:
	while (i--)
		gve_rx_free_buffer(&priv->pdev->dev,
				   &rx->data.page_info[i],
				   &rx->data.data_ring[i]);
	return err;
}

static void gve_rx_ctx_clear(struct gve_rx_ctx *ctx)
{
	ctx->skb_head = NULL;
	ctx->skb_tail = NULL;
	ctx->total_size = 0;
	ctx->frag_cnt = 0;
	ctx->drop_pkt = false;
}

static int gve_rx_alloc_ring(struct gve_priv *priv, int idx)
{
	struct gve_rx_ring *rx = &priv->rx[idx];
	struct device *hdev = &priv->pdev->dev;
	u32 slots, npages;
	int filled_pages;
	size_t bytes;
	int err;

	netif_dbg(priv, drv, priv->dev, "allocating rx ring\n");
	/* Make sure everything is zeroed to start with */
	memset(rx, 0, sizeof(*rx));

	rx->gve = priv;
	rx->q_num = idx;

	slots = priv->rx_data_slot_cnt;
	rx->mask = slots - 1;
	rx->data.raw_addressing = priv->queue_format == GVE_GQI_RDA_FORMAT;

	/* alloc rx data ring */
	bytes = sizeof(*rx->data.data_ring) * slots;
	rx->data.data_ring = dma_alloc_coherent(hdev, bytes,
						&rx->data.data_bus,
						GFP_KERNEL);
	if (!rx->data.data_ring)
		return -ENOMEM;

	rx->qpl_copy_pool_mask = min_t(u32, U32_MAX, slots * 2) - 1;
	rx->qpl_copy_pool_head = 0;
	rx->qpl_copy_pool = kvcalloc(rx->qpl_copy_pool_mask + 1,
				     sizeof(rx->qpl_copy_pool[0]),
				     GFP_KERNEL);

	if (!rx->qpl_copy_pool) {
		err = -ENOMEM;
		goto abort_with_slots;
	}

	filled_pages = gve_prefill_rx_pages(rx);
	if (filled_pages < 0) {
		err = -ENOMEM;
		goto abort_with_copy_pool;
	}
	rx->fill_cnt = filled_pages;
	/* Ensure data ring slots (packet buffers) are visible. */
	dma_wmb();

	/* Alloc gve_queue_resources */
	rx->q_resources =
		dma_alloc_coherent(hdev,
				   sizeof(*rx->q_resources),
				   &rx->q_resources_bus,
				   GFP_KERNEL);
	if (!rx->q_resources) {
		err = -ENOMEM;
		goto abort_filled;
	}
	netif_dbg(priv, drv, priv->dev, "rx[%d]->data.data_bus=%lx\n", idx,
		  (unsigned long)rx->data.data_bus);

	/* alloc rx desc ring */
	bytes = sizeof(struct gve_rx_desc) * priv->rx_desc_cnt;
	npages = bytes / PAGE_SIZE;
	if (npages * PAGE_SIZE != bytes) {
		err = -EIO;
		goto abort_with_q_resources;
	}

	rx->desc.desc_ring = dma_alloc_coherent(hdev, bytes, &rx->desc.bus,
						GFP_KERNEL);
	if (!rx->desc.desc_ring) {
		err = -ENOMEM;
		goto abort_with_q_resources;
	}
	rx->cnt = 0;
	rx->db_threshold = priv->rx_desc_cnt / 2;
	rx->desc.seqno = 1;

	/* Allocating half-page buffers allows page-flipping which is faster
	 * than copying or allocating new pages.
	 */
	rx->packet_buffer_size = PAGE_SIZE / 2;
	gve_rx_ctx_clear(&rx->ctx);
	gve_rx_add_to_block(priv, idx);

	return 0;

abort_with_q_resources:
	dma_free_coherent(hdev, sizeof(*rx->q_resources),
			  rx->q_resources, rx->q_resources_bus);
	rx->q_resources = NULL;
abort_filled:
	gve_rx_unfill_pages(priv, rx);
abort_with_copy_pool:
	kvfree(rx->qpl_copy_pool);
	rx->qpl_copy_pool = NULL;
abort_with_slots:
	bytes = sizeof(*rx->data.data_ring) * slots;
	dma_free_coherent(hdev, bytes, rx->data.data_ring, rx->data.data_bus);
	rx->data.data_ring = NULL;

	return err;
}

int gve_rx_alloc_rings(struct gve_priv *priv)
{
	int err = 0;
	int i;

	for (i = 0; i < priv->rx_cfg.num_queues; i++) {
		err = gve_rx_alloc_ring(priv, i);
		if (err) {
			netif_err(priv, drv, priv->dev,
				  "Failed to alloc rx ring=%d: err=%d\n",
				  i, err);
			break;
		}
	}
	/* Unallocate if there was an error */
	if (err) {
		int j;

		for (j = 0; j < i; j++)
			gve_rx_free_ring(priv, j);
	}
	return err;
}

void gve_rx_free_rings_gqi(struct gve_priv *priv)
{
	int i;

	for (i = 0; i < priv->rx_cfg.num_queues; i++)
		gve_rx_free_ring(priv, i);
}

void gve_rx_write_doorbell(struct gve_priv *priv, struct gve_rx_ring *rx)
{
	u32 db_idx = be32_to_cpu(rx->q_resources->db_index);

	iowrite32be(rx->fill_cnt, &priv->db_bar2[db_idx]);
}

static enum pkt_hash_types gve_rss_type(__be16 pkt_flags)
{
	if (likely(pkt_flags & (GVE_RXF_TCP | GVE_RXF_UDP)))
		return PKT_HASH_TYPE_L4;
	if (pkt_flags & (GVE_RXF_IPV4 | GVE_RXF_IPV6))
		return PKT_HASH_TYPE_L3;
	return PKT_HASH_TYPE_L2;
}

static struct sk_buff *gve_rx_add_frags(struct napi_struct *napi,
					struct gve_rx_slot_page_info *page_info,
					u16 packet_buffer_size, u16 len,
					struct gve_rx_ctx *ctx)
{
	u32 offset = page_info->page_offset + page_info->pad;
	struct sk_buff *skb = ctx->skb_tail;
	int num_frags = 0;

	if (!skb) {
		skb = napi_get_frags(napi);
		if (unlikely(!skb))
			return NULL;

		ctx->skb_head = skb;
		ctx->skb_tail = skb;
	} else {
		num_frags = skb_shinfo(ctx->skb_tail)->nr_frags;
		if (num_frags == MAX_SKB_FRAGS) {
			skb = napi_alloc_skb(napi, 0);
			if (!skb)
				return NULL;

			// We will never chain more than two SKBs: 2 * 16 * 2k > 64k
			// which is why we do not need to chain by using skb->next
			skb_shinfo(ctx->skb_tail)->frag_list = skb;

			ctx->skb_tail = skb;
			num_frags = 0;
		}
	}

	if (skb != ctx->skb_head) {
		ctx->skb_head->len += len;
		ctx->skb_head->data_len += len;
		ctx->skb_head->truesize += packet_buffer_size;
	}
	skb_add_rx_frag(skb, num_frags, page_info->page,
			offset, len, packet_buffer_size);

	return ctx->skb_head;
}

static void gve_rx_flip_buff(struct gve_rx_slot_page_info *page_info, __be64 *slot_addr)
{
	const __be64 offset = cpu_to_be64(PAGE_SIZE / 2);

	/* "flip" to other packet buffer on this page */
	page_info->page_offset ^= PAGE_SIZE / 2;
	*(slot_addr) ^= offset;
}

static int gve_rx_can_recycle_buffer(struct gve_rx_slot_page_info *page_info)
{
	int pagecount = page_count(page_info->page);

	/* This page is not being used by any SKBs - reuse */
	if (pagecount == page_info->pagecnt_bias)
		return 1;
	/* This page is still being used by an SKB - we can't reuse */
	else if (pagecount > page_info->pagecnt_bias)
		return 0;
	WARN(pagecount < page_info->pagecnt_bias,
	     "Pagecount should never be less than the bias.");
	return -1;
}

static struct sk_buff *
gve_rx_raw_addressing(struct device *dev, struct net_device *netdev,
		      struct gve_rx_slot_page_info *page_info, u16 len,
		      struct napi_struct *napi,
		      union gve_rx_data_slot *data_slot,
		      u16 packet_buffer_size, struct gve_rx_ctx *ctx)
{
	struct sk_buff *skb = gve_rx_add_frags(napi, page_info, packet_buffer_size, len, ctx);

	if (!skb)
		return NULL;

	/* Optimistically stop the kernel from freeing the page.
	 * We will check again in refill to determine if we need to alloc a
	 * new page.
	 */
	gve_dec_pagecnt_bias(page_info);

	return skb;
}

static struct sk_buff *gve_rx_copy_to_pool(struct gve_rx_ring *rx,
					   struct gve_rx_slot_page_info *page_info,
					   u16 len, struct napi_struct *napi)
{
	u32 pool_idx = rx->qpl_copy_pool_head & rx->qpl_copy_pool_mask;
	void *src = page_info->page_address + page_info->page_offset;
	struct gve_rx_slot_page_info *copy_page_info;
	struct gve_rx_ctx *ctx = &rx->ctx;
	bool alloc_page = false;
	struct sk_buff *skb;
	void *dst;

	copy_page_info = &rx->qpl_copy_pool[pool_idx];
	if (!copy_page_info->can_flip) {
		int recycle = gve_rx_can_recycle_buffer(copy_page_info);

		if (unlikely(recycle < 0)) {
			gve_schedule_reset(rx->gve);
			return NULL;
		}
		alloc_page = !recycle;
	}

	if (alloc_page) {
		struct gve_rx_slot_page_info alloc_page_info;
		struct page *page;

		/* The least recently used page turned out to be
		 * still in use by the kernel. Ignoring it and moving
		 * on alleviates head-of-line blocking.
		 */
		rx->qpl_copy_pool_head++;

		page = alloc_page(GFP_ATOMIC);
		if (!page)
			return NULL;

		alloc_page_info.page = page;
		alloc_page_info.page_offset = 0;
		alloc_page_info.page_address = page_address(page);
		alloc_page_info.pad = page_info->pad;

		memcpy(alloc_page_info.page_address, src, page_info->pad + len);
		skb = gve_rx_add_frags(napi, &alloc_page_info,
				       rx->packet_buffer_size,
				       len, ctx);

		u64_stats_update_begin(&rx->statss);
		rx->rx_frag_copy_cnt++;
		rx->rx_frag_alloc_cnt++;
		u64_stats_update_end(&rx->statss);

		return skb;
	}

	dst = copy_page_info->page_address + copy_page_info->page_offset;
	memcpy(dst, src, page_info->pad + len);
	copy_page_info->pad = page_info->pad;

	skb = gve_rx_add_frags(napi, copy_page_info,
			       rx->packet_buffer_size, len, ctx);
	if (unlikely(!skb))
		return NULL;

	gve_dec_pagecnt_bias(copy_page_info);
	copy_page_info->page_offset += rx->packet_buffer_size;
	copy_page_info->page_offset &= (PAGE_SIZE - 1);

	if (copy_page_info->can_flip) {
		/* We have used both halves of this copy page, it
		 * is time for it to go to the back of the queue.
		 */
		copy_page_info->can_flip = false;
		rx->qpl_copy_pool_head++;
		prefetch(rx->qpl_copy_pool[rx->qpl_copy_pool_head & rx->qpl_copy_pool_mask].page);
	} else {
		copy_page_info->can_flip = true;
	}

	u64_stats_update_begin(&rx->statss);
	rx->rx_frag_copy_cnt++;
	u64_stats_update_end(&rx->statss);

	return skb;
}

static struct sk_buff *
gve_rx_qpl(struct device *dev, struct net_device *netdev,
	   struct gve_rx_ring *rx, struct gve_rx_slot_page_info *page_info,
	   u16 len, struct napi_struct *napi,
	   union gve_rx_data_slot *data_slot)
{
	struct gve_rx_ctx *ctx = &rx->ctx;
	struct sk_buff *skb;

	/* if raw_addressing mode is not enabled gvnic can only receive into
	 * registered segments. If the buffer can't be recycled, our only
	 * choice is to copy the data out of it so that we can return it to the
	 * device.
	 */
	if (page_info->can_flip) {
		skb = gve_rx_add_frags(napi, page_info, rx->packet_buffer_size, len, ctx);
		/* No point in recycling if we didn't get the skb */
		if (skb) {
			/* Make sure that the page isn't freed. */
			gve_dec_pagecnt_bias(page_info);
			gve_rx_flip_buff(page_info, &data_slot->qpl_offset);
		}
	} else {
		skb = gve_rx_copy_to_pool(rx, page_info, len, napi);
	}
	return skb;
}

static struct sk_buff *gve_rx_skb(struct gve_priv *priv, struct gve_rx_ring *rx,
				  struct gve_rx_slot_page_info *page_info, struct napi_struct *napi,
				  u16 len, union gve_rx_data_slot *data_slot,
				  bool is_only_frag)
{
	struct net_device *netdev = priv->dev;
	struct gve_rx_ctx *ctx = &rx->ctx;
	struct sk_buff *skb = NULL;

	if (len <= priv->rx_copybreak && is_only_frag)  {
		/* Just copy small packets */
		skb = gve_rx_copy(netdev, napi, page_info, len, GVE_RX_PAD);
		if (skb) {
			u64_stats_update_begin(&rx->statss);
			rx->rx_copied_pkt++;
			rx->rx_frag_copy_cnt++;
			rx->rx_copybreak_pkt++;
			u64_stats_update_end(&rx->statss);
		}
	} else {
		int recycle = gve_rx_can_recycle_buffer(page_info);

		if (unlikely(recycle < 0)) {
			gve_schedule_reset(priv);
			return NULL;
		}
		page_info->can_flip = recycle;
		if (page_info->can_flip) {
			u64_stats_update_begin(&rx->statss);
			rx->rx_frag_flip_cnt++;
			u64_stats_update_end(&rx->statss);
		}

		if (rx->data.raw_addressing) {
			skb = gve_rx_raw_addressing(&priv->pdev->dev, netdev,
						    page_info, len, napi,
						    data_slot,
						    rx->packet_buffer_size, ctx);
		} else {
			skb = gve_rx_qpl(&priv->pdev->dev, netdev, rx,
					 page_info, len, napi, data_slot);
		}
	}
	return skb;
}

#define GVE_PKTCONT_BIT_IS_SET(x) (GVE_RXF_PKT_CONT & (x))
static void gve_rx(struct gve_rx_ring *rx, netdev_features_t feat,
		   struct gve_rx_desc *desc, u32 idx,
		   struct gve_rx_cnts *cnts)
{
	bool is_last_frag = !GVE_PKTCONT_BIT_IS_SET(desc->flags_seq);
	struct gve_rx_slot_page_info *page_info;
	u16 frag_size = be16_to_cpu(desc->len);
	struct gve_rx_ctx *ctx = &rx->ctx;
	union gve_rx_data_slot *data_slot;
	struct gve_priv *priv = rx->gve;
	struct sk_buff *skb = NULL;
	dma_addr_t page_bus;
	void *va;

	struct napi_struct *napi = &priv->ntfy_blocks[rx->ntfy_id].napi;
	bool is_first_frag = ctx->frag_cnt == 0;

	bool is_only_frag = is_first_frag && is_last_frag;

	if (unlikely(ctx->drop_pkt))
		goto finish_frag;

	if (desc->flags_seq & GVE_RXF_ERR) {
		ctx->drop_pkt = true;
		cnts->desc_err_pkt_cnt++;
		napi_free_frags(napi);
		goto finish_frag;
	}

	if (unlikely(frag_size > rx->packet_buffer_size)) {
		netdev_warn(priv->dev, "Unexpected frag size %d, can't exceed %d, scheduling reset",
			    frag_size, rx->packet_buffer_size);
		ctx->drop_pkt = true;
		napi_free_frags(napi);
		gve_schedule_reset(rx->gve);
		goto finish_frag;
	}

	/* Prefetch two packet buffers ahead, we will need it soon. */
	page_info = &rx->data.page_info[(idx + 2) & rx->mask];
	va = page_info->page_address + page_info->page_offset;
	prefetch(page_info->page); /* Kernel page struct. */
	prefetch(va);              /* Packet header. */
	prefetch(va + 64);         /* Next cacheline too. */

	page_info = &rx->data.page_info[idx];
	data_slot = &rx->data.data_ring[idx];
	page_bus = (rx->data.raw_addressing) ?
		be64_to_cpu(data_slot->addr) - page_info->page_offset :
		rx->data.qpl->page_buses[idx];
	dma_sync_single_for_cpu(&priv->pdev->dev, page_bus,
				PAGE_SIZE, DMA_FROM_DEVICE);
	page_info->pad = is_first_frag ? GVE_RX_PAD : 0;
	frag_size -= page_info->pad;

	skb = gve_rx_skb(priv, rx, page_info, napi, frag_size,
			 data_slot, is_only_frag);
	if (!skb) {
		u64_stats_update_begin(&rx->statss);
		rx->rx_skb_alloc_fail++;
		u64_stats_update_end(&rx->statss);

		napi_free_frags(napi);
		ctx->drop_pkt = true;
		goto finish_frag;
	}
	ctx->total_size += frag_size;

	if (is_first_frag) {
		if (likely(feat & NETIF_F_RXCSUM)) {
			/* NIC passes up the partial sum */
			if (desc->csum)
				skb->ip_summed = CHECKSUM_COMPLETE;
			else
				skb->ip_summed = CHECKSUM_NONE;
			skb->csum = csum_unfold(desc->csum);
		}

		/* parse flags & pass relevant info up */
		if (likely(feat & NETIF_F_RXHASH) &&
		    gve_needs_rss(desc->flags_seq))
			skb_set_hash(skb, be32_to_cpu(desc->rss_hash),
				     gve_rss_type(desc->flags_seq));
	}

	if (is_last_frag) {
		skb_record_rx_queue(skb, rx->q_num);
		if (skb_is_nonlinear(skb))
			napi_gro_frags(napi);
		else
			napi_gro_receive(napi, skb);
		goto finish_ok_pkt;
	}

	goto finish_frag;

finish_ok_pkt:
	cnts->ok_pkt_bytes += ctx->total_size;
	cnts->ok_pkt_cnt++;
finish_frag:
	ctx->frag_cnt++;
	if (is_last_frag) {
		cnts->total_pkt_cnt++;
		cnts->cont_pkt_cnt += (ctx->frag_cnt > 1);
		gve_rx_ctx_clear(ctx);
	}
}

bool gve_rx_work_pending(struct gve_rx_ring *rx)
{
	struct gve_rx_desc *desc;
	__be16 flags_seq;
	u32 next_idx;

	next_idx = rx->cnt & rx->mask;
	desc = rx->desc.desc_ring + next_idx;

	flags_seq = desc->flags_seq;

	return (GVE_SEQNO(flags_seq) == rx->desc.seqno);
}

static bool gve_rx_refill_buffers(struct gve_priv *priv, struct gve_rx_ring *rx)
{
	int refill_target = rx->mask + 1;
	u32 fill_cnt = rx->fill_cnt;

	while (fill_cnt - rx->cnt < refill_target) {
		struct gve_rx_slot_page_info *page_info;
		u32 idx = fill_cnt & rx->mask;

		page_info = &rx->data.page_info[idx];
		if (page_info->can_flip) {
			/* The other half of the page is free because it was
			 * free when we processed the descriptor. Flip to it.
			 */
			union gve_rx_data_slot *data_slot =
						&rx->data.data_ring[idx];

			gve_rx_flip_buff(page_info, &data_slot->addr);
			page_info->can_flip = 0;
		} else {
			/* It is possible that the networking stack has already
			 * finished processing all outstanding packets in the buffer
			 * and it can be reused.
			 * Flipping is unnecessary here - if the networking stack still
			 * owns half the page it is impossible to tell which half. Either
			 * the whole page is free or it needs to be replaced.
			 */
			int recycle = gve_rx_can_recycle_buffer(page_info);

			if (recycle < 0) {
				if (!rx->data.raw_addressing)
					gve_schedule_reset(priv);
				return false;
			}
			if (!recycle) {
				/* We can't reuse the buffer - alloc a new one*/
				union gve_rx_data_slot *data_slot =
						&rx->data.data_ring[idx];
				struct device *dev = &priv->pdev->dev;
				gve_rx_free_buffer(dev, page_info, data_slot);
				page_info->page = NULL;
				if (gve_rx_alloc_buffer(priv, dev, page_info,
							data_slot)) {
					u64_stats_update_begin(&rx->statss);
					rx->rx_buf_alloc_fail++;
					u64_stats_update_end(&rx->statss);
					break;
				}
			}
		}
		fill_cnt++;
	}
	rx->fill_cnt = fill_cnt;
	return true;
}

static int gve_clean_rx_done(struct gve_rx_ring *rx, int budget,
			     netdev_features_t feat)
{
	struct gve_rx_ctx *ctx = &rx->ctx;
	struct gve_priv *priv = rx->gve;
	struct gve_rx_cnts cnts = {0};
	struct gve_rx_desc *next_desc;
	u32 idx = rx->cnt & rx->mask;
	u32 work_done = 0;

	struct gve_rx_desc *desc = &rx->desc.desc_ring[idx];

	// Exceed budget only if (and till) the inflight packet is consumed.
	while ((GVE_SEQNO(desc->flags_seq) == rx->desc.seqno) &&
	       (work_done < budget || ctx->frag_cnt)) {
		next_desc = &rx->desc.desc_ring[(idx + 1) & rx->mask];
		prefetch(next_desc);

		gve_rx(rx, feat, desc, idx, &cnts);

		rx->cnt++;
		idx = rx->cnt & rx->mask;
		desc = &rx->desc.desc_ring[idx];
		rx->desc.seqno = gve_next_seqno(rx->desc.seqno);
		work_done++;
	}

	// The device will only send whole packets.
	if (unlikely(ctx->frag_cnt)) {
		struct napi_struct *napi = &priv->ntfy_blocks[rx->ntfy_id].napi;

		napi_free_frags(napi);
		gve_rx_ctx_clear(&rx->ctx);
		netdev_warn(priv->dev, "Unexpected seq number %d with incomplete packet, expected %d, scheduling reset",
			    GVE_SEQNO(desc->flags_seq), rx->desc.seqno);
		gve_schedule_reset(rx->gve);
	}

	if (!work_done && rx->fill_cnt - rx->cnt > rx->db_threshold)
		return 0;

	if (work_done) {
		u64_stats_update_begin(&rx->statss);
		rx->rpackets += cnts.ok_pkt_cnt;
		rx->rbytes += cnts.ok_pkt_bytes;
		rx->rx_cont_packet_cnt += cnts.cont_pkt_cnt;
		rx->rx_desc_err_dropped_pkt += cnts.desc_err_pkt_cnt;
		u64_stats_update_end(&rx->statss);
	}

	/* restock ring slots */
	if (!rx->data.raw_addressing) {
		/* In QPL mode buffs are refilled as the desc are processed */
		rx->fill_cnt += work_done;
	} else if (rx->fill_cnt - rx->cnt <= rx->db_threshold) {
		/* In raw addressing mode buffs are only refilled if the avail
		 * falls below a threshold.
		 */
		if (!gve_rx_refill_buffers(priv, rx))
			return 0;

		/* If we were not able to completely refill buffers, we'll want
		 * to schedule this queue for work again to refill buffers.
		 */
		if (rx->fill_cnt - rx->cnt <= rx->db_threshold) {
			gve_rx_write_doorbell(priv, rx);
			return budget;
		}
	}

	gve_rx_write_doorbell(priv, rx);
	return cnts.total_pkt_cnt;
}

int gve_rx_poll(struct gve_notify_block *block, int budget)
{
	struct gve_rx_ring *rx = block->rx;
	netdev_features_t feat;
	int work_done = 0;

	feat = block->napi.dev->features;

	/* If budget is 0, do all the work */
	if (budget == 0)
		budget = INT_MAX;

	if (budget > 0)
		work_done = gve_clean_rx_done(rx, budget, feat);

	return work_done;
}
