162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright 2008 Cisco Systems, Inc.  All rights reserved.
462306a36Sopenharmony_ci * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci#ifndef _VNIC_CQ_COPY_H_
762306a36Sopenharmony_ci#define _VNIC_CQ_COPY_H_
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include "fcpio.h"
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_cistatic inline unsigned int vnic_cq_copy_service(
1262306a36Sopenharmony_ci	struct vnic_cq *cq,
1362306a36Sopenharmony_ci	int (*q_service)(struct vnic_dev *vdev,
1462306a36Sopenharmony_ci			 unsigned int index,
1562306a36Sopenharmony_ci			 struct fcpio_fw_req *desc),
1662306a36Sopenharmony_ci	unsigned int work_to_do)
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci{
1962306a36Sopenharmony_ci	struct fcpio_fw_req *desc;
2062306a36Sopenharmony_ci	unsigned int work_done = 0;
2162306a36Sopenharmony_ci	u8 color;
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci	desc = (struct fcpio_fw_req *)((u8 *)cq->ring.descs +
2462306a36Sopenharmony_ci		cq->ring.desc_size * cq->to_clean);
2562306a36Sopenharmony_ci	fcpio_color_dec(desc, &color);
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	while (color != cq->last_color) {
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci		if ((*q_service)(cq->vdev, cq->index, desc))
3062306a36Sopenharmony_ci			break;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci		cq->to_clean++;
3362306a36Sopenharmony_ci		if (cq->to_clean == cq->ring.desc_count) {
3462306a36Sopenharmony_ci			cq->to_clean = 0;
3562306a36Sopenharmony_ci			cq->last_color = cq->last_color ? 0 : 1;
3662306a36Sopenharmony_ci		}
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci		desc = (struct fcpio_fw_req *)((u8 *)cq->ring.descs +
3962306a36Sopenharmony_ci			cq->ring.desc_size * cq->to_clean);
4062306a36Sopenharmony_ci		fcpio_color_dec(desc, &color);
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci		work_done++;
4362306a36Sopenharmony_ci		if (work_done >= work_to_do)
4462306a36Sopenharmony_ci			break;
4562306a36Sopenharmony_ci	}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	return work_done;
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci#endif /* _VNIC_CQ_COPY_H_ */
51