162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright 2008-2010 Cisco Systems, Inc.  All rights reserved.
462306a36Sopenharmony_ci * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef _CQ_DESC_H_
862306a36Sopenharmony_ci#define _CQ_DESC_H_
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci/*
1162306a36Sopenharmony_ci * Completion queue descriptor types
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_cienum cq_desc_types {
1462306a36Sopenharmony_ci	CQ_DESC_TYPE_WQ_ENET = 0,
1562306a36Sopenharmony_ci	CQ_DESC_TYPE_DESC_COPY = 1,
1662306a36Sopenharmony_ci	CQ_DESC_TYPE_WQ_EXCH = 2,
1762306a36Sopenharmony_ci	CQ_DESC_TYPE_RQ_ENET = 3,
1862306a36Sopenharmony_ci	CQ_DESC_TYPE_RQ_FCP = 4,
1962306a36Sopenharmony_ci};
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/* Completion queue descriptor: 16B
2262306a36Sopenharmony_ci *
2362306a36Sopenharmony_ci * All completion queues have this basic layout.  The
2462306a36Sopenharmony_ci * type_specfic area is unique for each completion
2562306a36Sopenharmony_ci * queue type.
2662306a36Sopenharmony_ci */
2762306a36Sopenharmony_cistruct cq_desc {
2862306a36Sopenharmony_ci	__le16 completed_index;
2962306a36Sopenharmony_ci	__le16 q_number;
3062306a36Sopenharmony_ci	u8 type_specfic[11];
3162306a36Sopenharmony_ci	u8 type_color;
3262306a36Sopenharmony_ci};
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#define CQ_DESC_TYPE_BITS        4
3562306a36Sopenharmony_ci#define CQ_DESC_TYPE_MASK        ((1 << CQ_DESC_TYPE_BITS) - 1)
3662306a36Sopenharmony_ci#define CQ_DESC_COLOR_MASK       1
3762306a36Sopenharmony_ci#define CQ_DESC_COLOR_SHIFT      7
3862306a36Sopenharmony_ci#define CQ_DESC_Q_NUM_BITS       10
3962306a36Sopenharmony_ci#define CQ_DESC_Q_NUM_MASK       ((1 << CQ_DESC_Q_NUM_BITS) - 1)
4062306a36Sopenharmony_ci#define CQ_DESC_COMP_NDX_BITS    12
4162306a36Sopenharmony_ci#define CQ_DESC_COMP_NDX_MASK    ((1 << CQ_DESC_COMP_NDX_BITS) - 1)
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistatic inline void cq_desc_dec(const struct cq_desc *desc_arg,
4462306a36Sopenharmony_ci	u8 *type, u8 *color, u16 *q_number, u16 *completed_index)
4562306a36Sopenharmony_ci{
4662306a36Sopenharmony_ci	const struct cq_desc *desc = desc_arg;
4762306a36Sopenharmony_ci	const u8 type_color = desc->type_color;
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	*color = (type_color >> CQ_DESC_COLOR_SHIFT) & CQ_DESC_COLOR_MASK;
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	/*
5262306a36Sopenharmony_ci	 * Make sure color bit is read from desc *before* other fields
5362306a36Sopenharmony_ci	 * are read from desc.  Hardware guarantees color bit is last
5462306a36Sopenharmony_ci	 * bit (byte) written.  Adding the rmb() prevents the compiler
5562306a36Sopenharmony_ci	 * and/or CPU from reordering the reads which would potentially
5662306a36Sopenharmony_ci	 * result in reading stale values.
5762306a36Sopenharmony_ci	 */
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	rmb();
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	*type = type_color & CQ_DESC_TYPE_MASK;
6262306a36Sopenharmony_ci	*q_number = le16_to_cpu(desc->q_number) & CQ_DESC_Q_NUM_MASK;
6362306a36Sopenharmony_ci	*completed_index = le16_to_cpu(desc->completed_index) &
6462306a36Sopenharmony_ci		CQ_DESC_COMP_NDX_MASK;
6562306a36Sopenharmony_ci}
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci#endif /* _CQ_DESC_H_ */
68